From e8711d7cd582b5ccef952dde1037c84582827fcb Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 7 Jan 2026 13:04:24 +0200 Subject: [PATCH] fix(client/lightweight): not handling returning backend entities --- apps/client/src/lightweight/browser_router.ts | 5 +-- apps/server/src/routes/route_api.ts | 32 ++----------------- packages/trilium-core/src/routes/index.ts | 29 +++++++++++++++++ 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/apps/client/src/lightweight/browser_router.ts b/apps/client/src/lightweight/browser_router.ts index d1e53586cb..b80aa09890 100644 --- a/apps/client/src/lightweight/browser_router.ts +++ b/apps/client/src/lightweight/browser_router.ts @@ -3,7 +3,7 @@ * Supports path parameters (e.g., /api/notes/:noteId) and query strings. */ -import { getContext } from "@triliumnext/core"; +import { getContext, routes } from "@triliumnext/core"; export interface BrowserRequest { method: string; @@ -74,7 +74,8 @@ function parseQuery(search: string): Record { * Convert a result to a JSON response. */ function jsonResponse(obj: unknown, status = 200, extraHeaders: Record = {}): BrowserResponse { - const body = encoder.encode(JSON.stringify(obj)).buffer as ArrayBuffer; + const parsedObj = routes.convertEntitiesToPojo(obj); + const body = encoder.encode(JSON.stringify(parsedObj)).buffer as ArrayBuffer; return { status, headers: { "content-type": "application/json; charset=utf-8", ...extraHeaders }, diff --git a/apps/server/src/routes/route_api.ts b/apps/server/src/routes/route_api.ts index dc11dfb417..9adf33c628 100644 --- a/apps/server/src/routes/route_api.ts +++ b/apps/server/src/routes/route_api.ts @@ -1,4 +1,4 @@ -import { AbstractBeccaEntity,NotFoundError, ValidationError } from "@triliumnext/core"; +import { routes, NotFoundError, ValidationError } from "@triliumnext/core"; import express, { type RequestHandler } from "express"; import multer from "multer"; @@ -23,38 +23,10 @@ type NotAPromise = T & { then?: void }; export type ApiRequestHandler = (req: express.Request, res: express.Response, next: express.NextFunction) => unknown; export type SyncRouteRequestHandler = (req: express.Request, res: express.Response, next: express.NextFunction) => NotAPromise | number | string | void | null; -/** Handling common patterns. If entity is not caught, serialization to JSON will fail */ -function convertEntitiesToPojo(result: unknown) { - if (result instanceof AbstractBeccaEntity) { - result = result.getPojo(); - } else if (Array.isArray(result)) { - for (const idx in result) { - if (result[idx] instanceof AbstractBeccaEntity) { - result[idx] = result[idx].getPojo(); - } - } - } else if (result && typeof result === "object") { - if ("note" in result && result.note instanceof AbstractBeccaEntity) { - result.note = result.note.getPojo(); - } - - if ("branch" in result && result.branch instanceof AbstractBeccaEntity) { - result.branch = result.branch.getPojo(); - } - } - - if (result && typeof result === "object" && "executionResult" in result) { - // from runOnBackend() - result.executionResult = convertEntitiesToPojo(result.executionResult); - } - - return result; -} - export function apiResultHandler(req: express.Request, res: express.Response, result: unknown) { res.setHeader("trilium-max-entity-change-id", entityChangesService.getMaxEntityChangeId()); - result = convertEntitiesToPojo(result); + result = routes.convertEntitiesToPojo(result); // if it's an array and the first element is integer, then we consider this to be [statusCode, response] format if (Array.isArray(result) && result.length > 0 && Number.isInteger(result[0])) { diff --git a/packages/trilium-core/src/routes/index.ts b/packages/trilium-core/src/routes/index.ts index 74872424bf..28c80f34a3 100644 --- a/packages/trilium-core/src/routes/index.ts +++ b/packages/trilium-core/src/routes/index.ts @@ -2,6 +2,7 @@ import optionsApiRoute from "./api/options"; import treeApiRoute from "./api/tree"; import keysApiRoute from "./api/keys"; import notesApiRoute from "./api/notes"; +import AbstractBeccaEntity from "../becca/entities/abstract_becca_entity"; // TODO: Deduplicate with routes.ts const GET = "get", @@ -42,3 +43,31 @@ export function buildSharedApiRoutes(apiRoute: any) { apiRoute(GET, "/api/keyboard-actions", keysApiRoute.getKeyboardActions); apiRoute(GET, "/api/keyboard-shortcuts-for-notes", keysApiRoute.getShortcutsForNotes); } + +/** Handling common patterns. If entity is not caught, serialization to JSON will fail */ +export function convertEntitiesToPojo(result: unknown) { + if (result instanceof AbstractBeccaEntity) { + result = result.getPojo(); + } else if (Array.isArray(result)) { + for (const idx in result) { + if (result[idx] instanceof AbstractBeccaEntity) { + result[idx] = result[idx].getPojo(); + } + } + } else if (result && typeof result === "object") { + if ("note" in result && result.note instanceof AbstractBeccaEntity) { + result.note = result.note.getPojo(); + } + + if ("branch" in result && result.branch instanceof AbstractBeccaEntity) { + result.branch = result.branch.getPojo(); + } + } + + if (result && typeof result === "object" && "executionResult" in result) { + // from runOnBackend() + result.executionResult = convertEntitiesToPojo(result.executionResult); + } + + return result; +}