fix(client/lightweight): not handling returning backend entities

This commit is contained in:
Elian Doran 2026-01-07 13:04:24 +02:00
parent 35f4d2aaad
commit e8711d7cd5
No known key found for this signature in database
3 changed files with 34 additions and 32 deletions

View File

@ -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<string, string | undefined> {
* Convert a result to a JSON response.
*/
function jsonResponse(obj: unknown, status = 200, extraHeaders: Record<string, string> = {}): 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 },

View File

@ -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> = 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<object> | 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])) {

View File

@ -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;
}