diff --git a/apps/server/src/etapi/attachments.ts b/apps/server/src/etapi/attachments.ts index 48cccec29a..453da10edf 100644 --- a/apps/server/src/etapi/attachments.ts +++ b/apps/server/src/etapi/attachments.ts @@ -1,14 +1,15 @@ +import type { AttachmentRow } from "@triliumnext/commons"; +import type { Router } from "express"; + import becca from "../becca/becca.js"; +import utils from "../services/utils.js"; import eu from "./etapi_utils.js"; +import type { ValidatorMap } from "./etapi-interface.js"; import mappers from "./mappers.js"; import v from "./validators.js"; -import utils from "../services/utils.js"; -import type { Router } from "express"; -import type { AttachmentRow } from "@triliumnext/commons"; -import type { ValidatorMap } from "./etapi-interface.js"; function register(router: Router) { - eu.route(router, "get", "/etapi/notes/:noteId/attachments", (req, res, next) => { + eu.route<{ noteId: string }>(router, "get", "/etapi/notes/:noteId/attachments", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); const attachments = note.getAttachments(); res.json(attachments.map((attachment) => mappers.mapAttachmentToPojo(attachment))); @@ -23,7 +24,7 @@ function register(router: Router) { content: [v.isString] }; - eu.route(router, "post", "/etapi/attachments", (req, res, next) => { + eu.route<{ attachmentId: string }>(router, "post", "/etapi/attachments", (req, res, next) => { const _params: Partial = {}; eu.validateAndPatch(_params, req.body, ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT); const params = _params as AttachmentRow; @@ -41,7 +42,7 @@ function register(router: Router) { } }); - eu.route(router, "get", "/etapi/attachments/:attachmentId", (req, res, next) => { + eu.route<{ attachmentId: string }>(router, "get", "/etapi/attachments/:attachmentId", (req, res, next) => { const attachment = eu.getAndCheckAttachment(req.params.attachmentId); res.json(mappers.mapAttachmentToPojo(attachment)); @@ -54,7 +55,7 @@ function register(router: Router) { position: [v.notNull, v.isInteger] }; - eu.route(router, "patch", "/etapi/attachments/:attachmentId", (req, res, next) => { + eu.route<{ attachmentId: string }>(router, "patch", "/etapi/attachments/:attachmentId", (req, res, next) => { const attachment = eu.getAndCheckAttachment(req.params.attachmentId); if (attachment.isProtected) { @@ -67,7 +68,7 @@ function register(router: Router) { res.json(mappers.mapAttachmentToPojo(attachment)); }); - eu.route(router, "get", "/etapi/attachments/:attachmentId/content", (req, res, next) => { + eu.route<{ attachmentId: string }>(router, "get", "/etapi/attachments/:attachmentId/content", (req, res, next) => { const attachment = eu.getAndCheckAttachment(req.params.attachmentId); if (attachment.isProtected) { @@ -84,7 +85,7 @@ function register(router: Router) { res.send(attachment.getContent()); }); - eu.route(router, "put", "/etapi/attachments/:attachmentId/content", (req, res, next) => { + eu.route<{ attachmentId: string }>(router, "put", "/etapi/attachments/:attachmentId/content", (req, res, next) => { const attachment = eu.getAndCheckAttachment(req.params.attachmentId); if (attachment.isProtected) { @@ -96,7 +97,7 @@ function register(router: Router) { return res.sendStatus(204); }); - eu.route(router, "delete", "/etapi/attachments/:attachmentId", (req, res, next) => { + eu.route<{ attachmentId: string }>(router, "delete", "/etapi/attachments/:attachmentId", (req, res, next) => { const attachment = becca.getAttachment(req.params.attachmentId); if (!attachment) { diff --git a/apps/server/src/etapi/attributes.ts b/apps/server/src/etapi/attributes.ts index f3bca61662..bb66e9459c 100644 --- a/apps/server/src/etapi/attributes.ts +++ b/apps/server/src/etapi/attributes.ts @@ -1,14 +1,15 @@ -import becca from "../becca/becca.js"; -import eu from "./etapi_utils.js"; -import mappers from "./mappers.js"; -import attributeService from "../services/attributes.js"; -import v from "./validators.js"; -import type { Router } from "express"; import type { AttributeRow } from "@triliumnext/commons"; +import type { Router } from "express"; + +import becca from "../becca/becca.js"; +import attributeService from "../services/attributes.js"; +import eu from "./etapi_utils.js"; import type { ValidatorMap } from "./etapi-interface.js"; +import mappers from "./mappers.js"; +import v from "./validators.js"; function register(router: Router) { - eu.route(router, "get", "/etapi/attributes/:attributeId", (req, res, next) => { + eu.route<{ attributeId: string }>(router, "get", "/etapi/attributes/:attributeId", (req, res, next) => { const attribute = eu.getAndCheckAttribute(req.params.attributeId); res.json(mappers.mapAttributeToPojo(attribute)); @@ -51,7 +52,7 @@ function register(router: Router) { position: [v.notNull, v.isInteger] }; - eu.route(router, "patch", "/etapi/attributes/:attributeId", (req, res, next) => { + eu.route<{ attributeId: string }>(router, "patch", "/etapi/attributes/:attributeId", (req, res, next) => { const attribute = eu.getAndCheckAttribute(req.params.attributeId); if (attribute.type === "label") { @@ -67,7 +68,7 @@ function register(router: Router) { res.json(mappers.mapAttributeToPojo(attribute)); }); - eu.route(router, "delete", "/etapi/attributes/:attributeId", (req, res, next) => { + eu.route<{ attributeId: string }>(router, "delete", "/etapi/attributes/:attributeId", (req, res, next) => { const attribute = becca.getAttribute(req.params.attributeId); if (!attribute) { diff --git a/apps/server/src/etapi/backup.ts b/apps/server/src/etapi/backup.ts index 9c986f45a4..73ab3e5c48 100644 --- a/apps/server/src/etapi/backup.ts +++ b/apps/server/src/etapi/backup.ts @@ -1,10 +1,10 @@ import type { Router } from "express"; -import eu from "./etapi_utils.js"; import backupService from "../services/backup.js"; +import eu from "./etapi_utils.js"; function register(router: Router) { - eu.route(router, "put", "/etapi/backup/:backupName", (req, res, next) => { + eu.route<{ backupName: string }>(router, "put", "/etapi/backup/:backupName", (req, res, next) => { backupService.backupNow(req.params.backupName) .then(() => res.sendStatus(204)) .catch(() => res.sendStatus(500)); diff --git a/apps/server/src/etapi/branches.ts b/apps/server/src/etapi/branches.ts index dfdadbb984..138a09c75a 100644 --- a/apps/server/src/etapi/branches.ts +++ b/apps/server/src/etapi/branches.ts @@ -1,15 +1,15 @@ +import type { BranchRow } from "@triliumnext/commons"; import type { Router } from "express"; import becca from "../becca/becca.js"; -import eu from "./etapi_utils.js"; -import mappers from "./mappers.js"; import BBranch from "../becca/entities/bbranch.js"; import entityChangesService from "../services/entity_changes.js"; +import eu from "./etapi_utils.js"; +import mappers from "./mappers.js"; import v from "./validators.js"; -import type { BranchRow } from "@triliumnext/commons"; function register(router: Router) { - eu.route(router, "get", "/etapi/branches/:branchId", (req, res, next) => { + eu.route<{ branchId: string }>(router, "get", "/etapi/branches/:branchId", (req, res, next) => { const branch = eu.getAndCheckBranch(req.params.branchId); res.json(mappers.mapBranchToPojo(branch)); @@ -37,15 +37,15 @@ function register(router: Router) { existing.save(); return res.status(200).json(mappers.mapBranchToPojo(existing)); - } else { - try { - const branch = new BBranch(params).save(); + } + try { + const branch = new BBranch(params).save(); - res.status(201).json(mappers.mapBranchToPojo(branch)); - } catch (e: any) { - throw new eu.EtapiError(400, eu.GENERIC_CODE, e.message); - } + res.status(201).json(mappers.mapBranchToPojo(branch)); + } catch (e: any) { + throw new eu.EtapiError(400, eu.GENERIC_CODE, e.message); } + }); const ALLOWED_PROPERTIES_FOR_PATCH = { @@ -54,7 +54,7 @@ function register(router: Router) { isExpanded: [v.notNull, v.isBoolean] }; - eu.route(router, "patch", "/etapi/branches/:branchId", (req, res, next) => { + eu.route<{ branchId: string }>(router, "patch", "/etapi/branches/:branchId", (req, res, next) => { const branch = eu.getAndCheckBranch(req.params.branchId); eu.validateAndPatch(branch, req.body, ALLOWED_PROPERTIES_FOR_PATCH); @@ -63,7 +63,7 @@ function register(router: Router) { res.json(mappers.mapBranchToPojo(branch)); }); - eu.route(router, "delete", "/etapi/branches/:branchId", (req, res, next) => { + eu.route<{ branchId: string }>(router, "delete", "/etapi/branches/:branchId", (req, res, next) => { const branch = becca.getBranch(req.params.branchId); if (!branch) { @@ -75,7 +75,7 @@ function register(router: Router) { res.sendStatus(204); }); - eu.route(router, "post", "/etapi/refresh-note-ordering/:parentNoteId", (req, res, next) => { + eu.route<{ parentNoteId: string }>(router, "post", "/etapi/refresh-note-ordering/:parentNoteId", (req, res, next) => { eu.getAndCheckNote(req.params.parentNoteId); entityChangesService.putNoteReorderingEntityChange(req.params.parentNoteId, "etapi"); diff --git a/apps/server/src/etapi/etapi_utils.ts b/apps/server/src/etapi/etapi_utils.ts index 9bafdf731a..7ad4a3c5af 100644 --- a/apps/server/src/etapi/etapi_utils.ts +++ b/apps/server/src/etapi/etapi_utils.ts @@ -1,12 +1,14 @@ -import cls from "../services/cls.js"; -import sql from "../services/sql.js"; -import log from "../services/log.js"; -import becca from "../becca/becca.js"; -import etapiTokenService from "../services/etapi_tokens.js"; -import config from "../services/config.js"; import type { NextFunction, Request, RequestHandler, Response, Router } from "express"; -import type { ValidatorMap } from "./etapi-interface.js"; +import type { ParamsDictionary } from "express-serve-static-core"; + +import becca from "../becca/becca.js"; import type { ApiRequestHandler, SyncRouteRequestHandler } from "../routes/route_api.js"; +import cls from "../services/cls.js"; +import config from "../services/config.js"; +import etapiTokenService from "../services/etapi_tokens.js"; +import log from "../services/log.js"; +import sql from "../services/sql.js"; +import type { ValidatorMap } from "./etapi-interface.js"; const GENERIC_CODE = "GENERIC"; type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head"; @@ -35,8 +37,8 @@ function sendError(res: Response, statusCode: number, code: string, message: str .send( JSON.stringify({ status: statusCode, - code: code, - message: message + code, + message }) ); } @@ -49,7 +51,7 @@ function checkEtapiAuth(req: Request, res: Response, next: NextFunction) { } } -function processRequest(req: Request, res: Response, routeHandler: ApiRequestHandler, next: NextFunction, method: string, path: string) { +function processRequest

(req: Request

, res: Response, routeHandler: ApiRequestHandler

, next: NextFunction, method: string, path: string) { try { cls.namespace.bindEmitter(req); cls.namespace.bindEmitter(res); @@ -73,12 +75,12 @@ function processRequest(req: Request, res: Response, routeHandler: ApiRequestHan } } -function route(router: Router, method: HttpMethod, path: string, routeHandler: SyncRouteRequestHandler) { - router[method](path, checkEtapiAuth, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path)); +function route

(router: Router, method: HttpMethod, path: string, routeHandler: SyncRouteRequestHandler

) { + router[method](path, checkEtapiAuth, (req: Request

, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path)); } -function NOT_AUTHENTICATED_ROUTE(router: Router, method: HttpMethod, path: string, middleware: RequestHandler[], routeHandler: SyncRouteRequestHandler) { - router[method](path, ...middleware, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path)); +function NOT_AUTHENTICATED_ROUTE

(router: Router, method: HttpMethod, path: string, middleware: RequestHandler[], routeHandler: SyncRouteRequestHandler

) { + router[method](path, ...middleware, (req: Request

, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path)); } function getAndCheckNote(noteId: string) { @@ -86,9 +88,8 @@ function getAndCheckNote(noteId: string) { if (note) { return note; - } else { - throw new EtapiError(404, "NOTE_NOT_FOUND", `Note '${noteId}' not found.`); } + throw new EtapiError(404, "NOTE_NOT_FOUND", `Note '${noteId}' not found.`); } function getAndCheckAttachment(attachmentId: string) { @@ -96,9 +97,9 @@ function getAndCheckAttachment(attachmentId: string) { if (attachment) { return attachment; - } else { - throw new EtapiError(404, "ATTACHMENT_NOT_FOUND", `Attachment '${attachmentId}' not found.`); } + throw new EtapiError(404, "ATTACHMENT_NOT_FOUND", `Attachment '${attachmentId}' not found.`); + } function getAndCheckBranch(branchId: string) { @@ -106,9 +107,8 @@ function getAndCheckBranch(branchId: string) { if (branch) { return branch; - } else { - throw new EtapiError(404, "BRANCH_NOT_FOUND", `Branch '${branchId}' not found.`); } + throw new EtapiError(404, "BRANCH_NOT_FOUND", `Branch '${branchId}' not found.`); } function getAndCheckAttribute(attributeId: string) { @@ -116,9 +116,8 @@ function getAndCheckAttribute(attributeId: string) { if (attribute) { return attribute; - } else { - throw new EtapiError(404, "ATTRIBUTE_NOT_FOUND", `Attribute '${attributeId}' not found.`); } + throw new EtapiError(404, "ATTRIBUTE_NOT_FOUND", `Attribute '${attributeId}' not found.`); } function getAndCheckRevision(revisionId: string) { @@ -126,9 +125,8 @@ function getAndCheckRevision(revisionId: string) { if (revision) { return revision; - } else { - throw new EtapiError(404, "REVISION_NOT_FOUND", `Revision '${revisionId}' not found.`); } + throw new EtapiError(404, "REVISION_NOT_FOUND", `Revision '${revisionId}' not found.`); } function validateAndPatch(target: any, source: any, allowedProperties: ValidatorMap) { diff --git a/apps/server/src/etapi/notes.ts b/apps/server/src/etapi/notes.ts index 9fae830704..867d325925 100644 --- a/apps/server/src/etapi/notes.ts +++ b/apps/server/src/etapi/notes.ts @@ -1,20 +1,21 @@ -import becca from "../becca/becca.js"; -import utils from "../services/utils.js"; -import eu from "./etapi_utils.js"; -import mappers from "./mappers.js"; -import noteService from "../services/notes.js"; -import TaskContext from "../services/task_context.js"; -import v from "./validators.js"; -import searchService from "../services/search/services/search.js"; -import SearchContext from "../services/search/search_context.js"; -import zipExportService from "../services/export/zip.js"; -import zipImportService from "../services/import/zip.js"; import type { Request, Router } from "express"; import type { ParsedQs } from "qs"; -import type { NoteParams } from "../services/note-interface.js"; -import type { SearchParams } from "../services/search/services/types.js"; -import type { ValidatorMap } from "./etapi-interface.js"; + +import becca from "../becca/becca.js"; +import zipExportService from "../services/export/zip.js"; import type { ExportFormat } from "../services/export/zip/abstract_provider.js"; +import zipImportService from "../services/import/zip.js"; +import type { NoteParams } from "../services/note-interface.js"; +import noteService from "../services/notes.js"; +import SearchContext from "../services/search/search_context.js"; +import searchService from "../services/search/services/search.js"; +import type { SearchParams } from "../services/search/services/types.js"; +import TaskContext from "../services/task_context.js"; +import utils from "../services/utils.js"; +import eu from "./etapi_utils.js"; +import type { ValidatorMap } from "./etapi-interface.js"; +import mappers from "./mappers.js"; +import v from "./validators.js"; function register(router: Router) { eu.route(router, "get", "/etapi/notes", (req, res, next) => { @@ -41,7 +42,7 @@ function register(router: Router) { res.json(resp); }); - eu.route(router, "get", "/etapi/notes/:noteId", (req, res, next) => { + eu.route<{ noteId: string }>(router, "get", "/etapi/notes/:noteId", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); res.json(mappers.mapNoteToPojo(note)); @@ -86,7 +87,7 @@ function register(router: Router) { utcDateCreated: [v.notNull, v.isString, v.isUtcDateTime] }; - eu.route(router, "patch", "/etapi/notes/:noteId", (req, res, next) => { + eu.route<{ noteId: string }>(router, "patch", "/etapi/notes/:noteId", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); if (note.isProtected) { @@ -100,7 +101,7 @@ function register(router: Router) { res.json(mappers.mapNoteToPojo(note)); }); - eu.route(router, "delete", "/etapi/notes/:noteId", (req, res, next) => { + eu.route<{ noteId: string }>(router, "delete", "/etapi/notes/:noteId", (req, res, next) => { const { noteId } = req.params; const note = becca.getNote(noteId); @@ -114,7 +115,7 @@ function register(router: Router) { res.sendStatus(204); }); - eu.route(router, "get", "/etapi/notes/:noteId/content", (req, res, next) => { + eu.route<{ noteId: string }>(router, "get", "/etapi/notes/:noteId/content", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); if (note.isProtected) { @@ -131,7 +132,7 @@ function register(router: Router) { res.send(note.getContent()); }); - eu.route(router, "put", "/etapi/notes/:noteId/content", (req, res, next) => { + eu.route<{ noteId: string }>(router, "put", "/etapi/notes/:noteId/content", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); if (note.isProtected) { @@ -146,7 +147,7 @@ function register(router: Router) { return res.sendStatus(204); }); - eu.route(router, "get", "/etapi/notes/:noteId/export", (req, res, next) => { + eu.route<{ noteId: string }>(router, "get", "/etapi/notes/:noteId/export", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); const format = req.query.format || "html"; @@ -163,7 +164,7 @@ function register(router: Router) { zipExportService.exportToZip(taskContext, branch, format as ExportFormat, res); }); - eu.route(router, "post", "/etapi/notes/:noteId/import", (req, res, next) => { + eu.route<{ noteId: string }>(router, "post", "/etapi/notes/:noteId/import", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); const taskContext = new TaskContext("no-progress-reporting", "importNotes", null); @@ -175,7 +176,7 @@ function register(router: Router) { }); // we need better error handling here, async errors won't be properly processed. }); - eu.route(router, "post", "/etapi/notes/:noteId/revision", (req, res, next) => { + eu.route<{ noteId: string }>(router, "post", "/etapi/notes/:noteId/revision", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); note.saveRevision(); @@ -183,7 +184,7 @@ function register(router: Router) { return res.sendStatus(204); }); - eu.route(router, "get", "/etapi/notes/:noteId/attachments", (req, res, next) => { + eu.route<{ noteId: string }>(router, "get", "/etapi/notes/:noteId/attachments", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); const attachments = note.getAttachments(); diff --git a/apps/server/src/etapi/revisions.ts b/apps/server/src/etapi/revisions.ts index 6451b18a15..a8e963417c 100644 --- a/apps/server/src/etapi/revisions.ts +++ b/apps/server/src/etapi/revisions.ts @@ -1,13 +1,14 @@ +import type { NoteRow, RecentChangeRow } from "@triliumnext/commons"; +import type { Router } from "express"; + import becca from "../becca/becca.js"; +import noteService from "../services/notes.js"; +import protectedSessionService from "../services/protected_session.js"; import sql from "../services/sql.js"; +import TaskContext from "../services/task_context.js"; +import utils from "../services/utils.js"; import eu from "./etapi_utils.js"; import mappers from "./mappers.js"; -import noteService from "../services/notes.js"; -import TaskContext from "../services/task_context.js"; -import protectedSessionService from "../services/protected_session.js"; -import utils from "../services/utils.js"; -import type { Router } from "express"; -import type { NoteRow, RecentChangeRow } from "@triliumnext/commons"; function register(router: Router) { // GET /etapi/notes/history - must be registered before /etapi/notes/:noteId routes @@ -130,7 +131,7 @@ function register(router: Router) { }); // GET /etapi/notes/:noteId/revisions - List all revisions for a note - eu.route(router, "get", "/etapi/notes/:noteId/revisions", (req, res, next) => { + eu.route<{ noteId: string }>(router, "get", "/etapi/notes/:noteId/revisions", (req, res, next) => { const note = eu.getAndCheckNote(req.params.noteId); const revisions = becca.getRevisionsFromQuery( @@ -146,7 +147,7 @@ function register(router: Router) { }); // POST /etapi/notes/:noteId/undelete - Restore a deleted note - eu.route(router, "post", "/etapi/notes/:noteId/undelete", (req, res, next) => { + eu.route<{ noteId: string }>(router, "post", "/etapi/notes/:noteId/undelete", (req, res, next) => { const { noteId } = req.params; const noteRow = sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]); @@ -172,7 +173,7 @@ function register(router: Router) { }); // GET /etapi/revisions/:revisionId - Get revision metadata - eu.route(router, "get", "/etapi/revisions/:revisionId", (req, res, next) => { + eu.route<{ revisionId: string }>(router, "get", "/etapi/revisions/:revisionId", (req, res, next) => { const revision = eu.getAndCheckRevision(req.params.revisionId); if (revision.isProtected) { @@ -183,7 +184,7 @@ function register(router: Router) { }); // GET /etapi/revisions/:revisionId/content - Get revision content - eu.route(router, "get", "/etapi/revisions/:revisionId/content", (req, res, next) => { + eu.route<{ revisionId: string }>(router, "get", "/etapi/revisions/:revisionId/content", (req, res, next) => { const revision = eu.getAndCheckRevision(req.params.revisionId); if (revision.isProtected) { diff --git a/apps/server/src/etapi/special_notes.ts b/apps/server/src/etapi/special_notes.ts index 043ce1d3a7..c88b1da429 100644 --- a/apps/server/src/etapi/special_notes.ts +++ b/apps/server/src/etapi/special_notes.ts @@ -1,8 +1,9 @@ -import specialNotesService from "../services/special_notes.js"; +import type { Router } from "express"; + import dateNotesService from "../services/date_notes.js"; +import specialNotesService from "../services/special_notes.js"; import eu from "./etapi_utils.js"; import mappers from "./mappers.js"; -import type { Router } from "express"; const getDateInvalidError = (date: string) => new eu.EtapiError(400, "DATE_INVALID", `Date "${date}" is not valid.`); const getWeekInvalidError = (week: string) => new eu.EtapiError(400, "WEEK_INVALID", `Week "${week}" is not valid.`); @@ -15,7 +16,7 @@ function isValidDate(date: string) { } function register(router: Router) { - eu.route(router, "get", "/etapi/inbox/:date", (req, res, next) => { + eu.route<{ date: string }>(router, "get", "/etapi/inbox/:date", (req, res, next) => { const { date } = req.params; if (!isValidDate(date)) { @@ -25,7 +26,7 @@ function register(router: Router) { res.json(mappers.mapNoteToPojo(note)); }); - eu.route(router, "get", "/etapi/calendar/days/:date", (req, res, next) => { + eu.route<{ date: string }>(router, "get", "/etapi/calendar/days/:date", (req, res, next) => { const { date } = req.params; if (!isValidDate(date)) { @@ -36,7 +37,7 @@ function register(router: Router) { res.json(mappers.mapNoteToPojo(note)); }); - eu.route(router, "get", "/etapi/calendar/week-first-day/:date", (req, res, next) => { + eu.route<{ date: string }>(router, "get", "/etapi/calendar/week-first-day/:date", (req, res, next) => { const { date } = req.params; if (!isValidDate(date)) { @@ -47,7 +48,7 @@ function register(router: Router) { res.json(mappers.mapNoteToPojo(note)); }); - eu.route(router, "get", "/etapi/calendar/weeks/:week", (req, res, next) => { + eu.route<{ week: string }>(router, "get", "/etapi/calendar/weeks/:week", (req, res, next) => { const { week } = req.params; if (!/[0-9]{4}-W[0-9]{2}/.test(week)) { @@ -63,7 +64,7 @@ function register(router: Router) { res.json(mappers.mapNoteToPojo(note)); }); - eu.route(router, "get", "/etapi/calendar/months/:month", (req, res, next) => { + eu.route<{ month: string }>(router, "get", "/etapi/calendar/months/:month", (req, res, next) => { const { month } = req.params; if (!/[0-9]{4}-[0-9]{2}/.test(month)) { @@ -74,7 +75,7 @@ function register(router: Router) { res.json(mappers.mapNoteToPojo(note)); }); - eu.route(router, "get", "/etapi/calendar/years/:year", (req, res, next) => { + eu.route<{ year: string }>(router, "get", "/etapi/calendar/years/:year", (req, res, next) => { const { year } = req.params; if (!/[0-9]{4}/.test(year)) { diff --git a/apps/server/src/routes/api/attachments.ts b/apps/server/src/routes/api/attachments.ts index b2c877fcb3..03608cf16b 100644 --- a/apps/server/src/routes/api/attachments.ts +++ b/apps/server/src/routes/api/attachments.ts @@ -1,29 +1,30 @@ -import becca from "../../becca/becca.js"; -import blobService from "../../services/blob.js"; -import ValidationError from "../../errors/validation_error.js"; -import imageService from "../../services/image.js"; -import type { Request } from "express"; import { ConvertAttachmentToNoteResponse } from "@triliumnext/commons"; +import type { Request } from "express"; -function getAttachmentBlob(req: Request) { +import becca from "../../becca/becca.js"; +import ValidationError from "../../errors/validation_error.js"; +import blobService from "../../services/blob.js"; +import imageService from "../../services/image.js"; + +function getAttachmentBlob(req: Request<{ attachmentId: string }>) { const preview = req.query.preview === "true"; return blobService.getBlobPojo("attachments", req.params.attachmentId, { preview }); } -function getAttachments(req: Request) { +function getAttachments(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); return note.getAttachments(); } -function getAttachment(req: Request) { +function getAttachment(req: Request<{ attachmentId: string }>) { const { attachmentId } = req.params; return becca.getAttachmentOrThrow(attachmentId); } -function getAllAttachments(req: Request) { +function getAllAttachments(req: Request<{ attachmentId: string }>) { const { attachmentId } = req.params; // one particular attachment is requested, but return all note's attachments @@ -31,10 +32,10 @@ function getAllAttachments(req: Request) { return attachment.getNote()?.getAttachments() || []; } -function saveAttachment(req: Request) { +function saveAttachment(req: Request<{ noteId: string }>) { const { noteId } = req.params; const { attachmentId, role, mime, title, content } = req.body; - const matchByQuery = req.query.matchBy + const matchByQuery = req.query.matchBy; const isValidMatchBy = (typeof matchByQuery === "string") && (matchByQuery === "attachmentId" || matchByQuery === "title"); const matchBy = isValidMatchBy ? matchByQuery : undefined; @@ -42,7 +43,7 @@ function saveAttachment(req: Request) { note.saveAttachment({ attachmentId, role, mime, title, content }, matchBy); } -function uploadAttachment(req: Request) { +function uploadAttachment(req: Request<{ noteId: string }>) { const { noteId } = req.params; const { file } = req; @@ -76,7 +77,7 @@ function uploadAttachment(req: Request) { }; } -function renameAttachment(req: Request) { +function renameAttachment(req: Request<{ attachmentId: string }>) { const { title } = req.body; const { attachmentId } = req.params; @@ -90,7 +91,7 @@ function renameAttachment(req: Request) { attachment.save(); } -function deleteAttachment(req: Request) { +function deleteAttachment(req: Request<{ attachmentId: string }>) { const { attachmentId } = req.params; const attachment = becca.getAttachment(attachmentId); @@ -100,7 +101,7 @@ function deleteAttachment(req: Request) { } } -function convertAttachmentToNote(req: Request) { +function convertAttachmentToNote(req: Request<{ attachmentId: string }>) { const { attachmentId } = req.params; const attachment = becca.getAttachmentOrThrow(attachmentId); diff --git a/apps/server/src/routes/api/attributes.ts b/apps/server/src/routes/api/attributes.ts index 55c3e3e298..b89747e299 100644 --- a/apps/server/src/routes/api/attributes.ts +++ b/apps/server/src/routes/api/attributes.ts @@ -1,21 +1,22 @@ -"use strict"; -import sql from "../../services/sql.js"; -import log from "../../services/log.js"; -import attributeService from "../../services/attributes.js"; -import BAttribute from "../../becca/entities/battribute.js"; -import becca from "../../becca/becca.js"; -import ValidationError from "../../errors/validation_error.js"; -import type { Request } from "express"; + import { UpdateAttributeResponse } from "@triliumnext/commons"; +import type { Request } from "express"; -function getEffectiveNoteAttributes(req: Request) { +import becca from "../../becca/becca.js"; +import BAttribute from "../../becca/entities/battribute.js"; +import ValidationError from "../../errors/validation_error.js"; +import attributeService from "../../services/attributes.js"; +import log from "../../services/log.js"; +import sql from "../../services/sql.js"; + +function getEffectiveNoteAttributes(req: Request<{ noteId: string }>) { const note = becca.getNote(req.params.noteId); return note?.getAttributes(); } -function updateNoteAttribute(req: Request) { +function updateNoteAttribute(req: Request<{ noteId: string }>) { const noteId = req.params.noteId; const body = req.body; @@ -47,7 +48,7 @@ function updateNoteAttribute(req: Request) { } attribute = new BAttribute({ - noteId: noteId, + noteId, name: body.name, type: body.type, isInheritable: body.isInheritable @@ -96,7 +97,7 @@ function addNoteAttribute(req: Request) { new BAttribute({ ...body, noteId }).save(); } -function deleteNoteAttribute(req: Request) { +function deleteNoteAttribute(req: Request<{ noteId: string; attributeId: string }>) { const noteId = req.params.noteId; const attributeId = req.params.attributeId; @@ -111,7 +112,7 @@ function deleteNoteAttribute(req: Request) { } } -function updateNoteAttributes(req: Request) { +function updateNoteAttributes(req: Request<{ noteId: string }>) { const noteId = req.params.noteId; const incomingAttributes = req.body; @@ -193,7 +194,7 @@ function getValuesForAttribute(req: Request) { return sql.getColumn("SELECT DISTINCT value FROM attributes WHERE isDeleted = 0 AND name = ? AND type = 'label' AND value != '' ORDER BY value", [attributeName]); } -function createRelation(req: Request) { +function createRelation(req: Request<{ noteId: string; targetNoteId: string; name: string }>) { const sourceNoteId = req.params.noteId; const targetNoteId = req.params.targetNoteId; const name = req.params.name; @@ -208,7 +209,7 @@ function createRelation(req: Request) { if (!attribute) { attribute = new BAttribute({ noteId: sourceNoteId, - name: name, + name, type: "relation", value: targetNoteId }).save(); diff --git a/apps/server/src/routes/api/branches.ts b/apps/server/src/routes/api/branches.ts index 73ce03a7a8..ff224c04f1 100644 --- a/apps/server/src/routes/api/branches.ts +++ b/apps/server/src/routes/api/branches.ts @@ -1,24 +1,23 @@ -"use strict"; - -import sql from "../../services/sql.js"; -import utils from "../../services/utils.js"; -import entityChangesService from "../../services/entity_changes.js"; -import treeService from "../../services/tree.js"; -import eraseService from "../../services/erase.js"; -import becca from "../../becca/becca.js"; -import TaskContext from "../../services/task_context.js"; -import branchService from "../../services/branches.js"; -import log from "../../services/log.js"; -import ValidationError from "../../errors/validation_error.js"; -import eventService from "../../services/events.js"; import type { Request } from "express"; +import becca from "../../becca/becca.js"; +import ValidationError from "../../errors/validation_error.js"; +import branchService from "../../services/branches.js"; +import entityChangesService from "../../services/entity_changes.js"; +import eraseService from "../../services/erase.js"; +import eventService from "../../services/events.js"; +import log from "../../services/log.js"; +import sql from "../../services/sql.js"; +import TaskContext from "../../services/task_context.js"; +import treeService from "../../services/tree.js"; +import utils from "../../services/utils.js"; + /** * Code in this file deals with moving and cloning branches. The relationship between note and parent note is unique * for not deleted branches. There may be multiple deleted note-parent note relationships. */ -function moveBranchToParent(req: Request) { +function moveBranchToParent(req: Request<{ branchId: string, parentBranchId: string }>) { const { branchId, parentBranchId } = req.params; const branchToMove = becca.getBranch(branchId); @@ -31,7 +30,7 @@ function moveBranchToParent(req: Request) { return branchService.moveBranchToBranch(branchToMove, targetParentBranch, branchId); } -function moveBranchBeforeNote(req: Request) { +function moveBranchBeforeNote(req: Request<{ branchId: string, beforeBranchId: string }>) { const { branchId, beforeBranchId } = req.params; const branchToMove = becca.getBranchOrThrow(branchId); @@ -79,7 +78,7 @@ function moveBranchBeforeNote(req: Request) { return { success: true }; } -function moveBranchAfterNote(req: Request) { +function moveBranchAfterNote(req: Request<{ branchId: string, afterBranchId: string }>) { const { branchId, afterBranchId } = req.params; const branchToMove = becca.getBranchOrThrow(branchId); @@ -128,7 +127,7 @@ function moveBranchAfterNote(req: Request) { return { success: true }; } -function setExpanded(req: Request) { +function setExpanded(req: Request<{ branchId: string, expanded: string }>) { const { branchId } = req.params; const expanded = parseInt(req.params.expanded); @@ -150,7 +149,7 @@ function setExpanded(req: Request) { } } -function setExpandedForSubtree(req: Request) { +function setExpandedForSubtree(req: Request<{ branchId: string, expanded: string }>) { const { branchId } = req.params; const expanded = parseInt(req.params.expanded); @@ -232,7 +231,7 @@ function setExpandedForSubtree(req: Request) { * - session: [] * tags: ["data"] */ -function deleteBranch(req: Request) { +function deleteBranch(req: Request<{ branchId: string }>) { const last = req.query.last === "true"; const eraseNotes = req.query.eraseNotes === "true"; const branch = becca.getBranchOrThrow(req.params.branchId); @@ -256,11 +255,11 @@ function deleteBranch(req: Request) { } return { - noteDeleted: noteDeleted + noteDeleted }; } -function setPrefix(req: Request) { +function setPrefix(req: Request<{ branchId: string }>) { const branchId = req.params.branchId; //TriliumNextTODO: req.body arrives as string, so req.body.prefix will be undefined – did the code below ever even work? const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix; @@ -272,7 +271,7 @@ function setPrefix(req: Request) { function setPrefixBatch(req: Request) { const { branchIds, prefix } = req.body; - + if (!Array.isArray(branchIds)) { throw new ValidationError("branchIds must be an array"); } diff --git a/apps/server/src/routes/api/clipper.ts b/apps/server/src/routes/api/clipper.ts index 133c35a88e..b5560c715b 100644 --- a/apps/server/src/routes/api/clipper.ts +++ b/apps/server/src/routes/api/clipper.ts @@ -38,7 +38,7 @@ async function addClipping(req: Request) { if (!clippingNote) { clippingNote = noteService.createNewNote({ parentNoteId: clipperInbox.noteId, - title: title, + title, content: "", type: "text" }).note; @@ -188,7 +188,7 @@ export function processContent(images: Image[], note: BNote, content: string) { return rewrittenContent; } -function openNote(req: Request) { +function openNote(req: Request<{ noteId: string }>) { if (utils.isElectron) { ws.sendMessageToAllClients({ type: "openNote", @@ -198,11 +198,11 @@ function openNote(req: Request) { return { result: "ok" }; - } else { - return { - result: "open-in-browser" - }; - } + } + return { + result: "open-in-browser" + }; + } function handshake() { @@ -212,7 +212,7 @@ function handshake() { }; } -async function findNotesByUrl(req: Request) { +async function findNotesByUrl(req: Request<{ noteUrl: string }>) { const pageUrl = req.params.noteUrl; const clipperInbox = await getClipperInboxNote(); const foundPage = findClippingNote(clipperInbox, pageUrl, null); diff --git a/apps/server/src/routes/api/cloning.ts b/apps/server/src/routes/api/cloning.ts index 175fcfd9b4..ac28ca70c6 100644 --- a/apps/server/src/routes/api/cloning.ts +++ b/apps/server/src/routes/api/cloning.ts @@ -1,29 +1,28 @@ -"use strict"; - import type { Request } from "express"; + import cloningService from "../../services/cloning.js"; -function cloneNoteToBranch(req: Request) { +function cloneNoteToBranch(req: Request<{ noteId: string; parentBranchId: string }>) { const { noteId, parentBranchId } = req.params; const { prefix } = req.body; return cloningService.cloneNoteToBranch(noteId, parentBranchId, prefix); } -function cloneNoteToParentNote(req: Request) { +function cloneNoteToParentNote(req: Request<{ noteId: string; parentNoteId: string }>) { const { noteId, parentNoteId } = req.params; const { prefix } = req.body; return cloningService.cloneNoteToParentNote(noteId, parentNoteId, prefix); } -function cloneNoteAfter(req: Request) { +function cloneNoteAfter(req: Request<{ noteId: string; afterBranchId: string }>) { const { noteId, afterBranchId } = req.params; return cloningService.cloneNoteAfter(noteId, afterBranchId); } -function toggleNoteInParent(req: Request) { +function toggleNoteInParent(req: Request<{ noteId: string; parentNoteId: string; present: string }>) { const { noteId, parentNoteId, present } = req.params; return cloningService.toggleNoteInParent(present === "true", noteId, parentNoteId); diff --git a/apps/server/src/routes/api/etapi_tokens.ts b/apps/server/src/routes/api/etapi_tokens.ts index bcb2970285..30a700b766 100644 --- a/apps/server/src/routes/api/etapi_tokens.ts +++ b/apps/server/src/routes/api/etapi_tokens.ts @@ -1,6 +1,7 @@ -import type { Request } from "express"; -import etapiTokenService from "../../services/etapi_tokens.js"; import { EtapiToken, PostTokensResponse } from "@triliumnext/commons"; +import type { Request } from "express"; + +import etapiTokenService from "../../services/etapi_tokens.js"; function getTokens() { const tokens = etapiTokenService.getTokens(); @@ -14,11 +15,11 @@ function createToken(req: Request) { return etapiTokenService.createToken(req.body.tokenName) satisfies PostTokensResponse; } -function patchToken(req: Request) { +function patchToken(req: Request<{ etapiTokenId: string }>) { etapiTokenService.renameToken(req.params.etapiTokenId, req.body.name); } -function deleteToken(req: Request) { +function deleteToken(req: Request<{ etapiTokenId: string }>) { etapiTokenService.deleteToken(req.params.etapiTokenId); } diff --git a/apps/server/src/routes/api/export.ts b/apps/server/src/routes/api/export.ts index 944eee841c..adad1f6366 100644 --- a/apps/server/src/routes/api/export.ts +++ b/apps/server/src/routes/api/export.ts @@ -1,17 +1,16 @@ -"use strict"; - -import zipExportService from "../../services/export/zip.js"; -import singleExportService from "../../services/export/single.js"; -import opmlExportService from "../../services/export/opml.js"; -import becca from "../../becca/becca.js"; -import TaskContext from "../../services/task_context.js"; -import log from "../../services/log.js"; -import NotFoundError from "../../errors/not_found_error.js"; import type { Request, Response } from "express"; + +import becca from "../../becca/becca.js"; +import NotFoundError from "../../errors/not_found_error.js"; import ValidationError from "../../errors/validation_error.js"; +import opmlExportService from "../../services/export/opml.js"; +import singleExportService from "../../services/export/single.js"; +import zipExportService from "../../services/export/zip.js"; +import log from "../../services/log.js"; +import TaskContext from "../../services/task_context.js"; import { safeExtractMessageAndStackFromError } from "../../services/utils.js"; -function exportBranch(req: Request, res: Response) { +function exportBranch(req: Request<{ branchId: string; type: string; format: string; version: string; taskId: string }>, res: Response) { const { branchId, type, format, version, taskId } = req.params; const branch = becca.getBranch(branchId); diff --git a/apps/server/src/routes/api/files.ts b/apps/server/src/routes/api/files.ts index 4a6e17382b..5c47a22620 100644 --- a/apps/server/src/routes/api/files.ts +++ b/apps/server/src/routes/api/files.ts @@ -1,5 +1,3 @@ - - import chokidar from "chokidar"; import type { Request, Response } from "express"; import fs from "fs"; @@ -17,7 +15,7 @@ import protectedSessionService from "../../services/protected_session.js"; import utils from "../../services/utils.js"; import ws from "../../services/ws.js"; -function updateFile(req: Request) { +function updateFile(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); const file = req.file; @@ -46,7 +44,7 @@ function updateFile(req: Request) { }; } -function updateAttachment(req: Request) { +function updateAttachment(req: Request<{ attachmentId: string }>) { const attachment = becca.getAttachmentOrThrow(req.params.attachmentId); const file = req.file; if (!file) { @@ -103,20 +101,20 @@ function downloadAttachmentInt(attachmentId: string, res: Response, contentDispo return downloadData(attachment, res, contentDisposition); } -const downloadFile = (req: Request, res: Response) => downloadNoteInt(req.params.noteId, res, true); -const openFile = (req: Request, res: Response) => downloadNoteInt(req.params.noteId, res, false); +const downloadFile = (req: Request<{ noteId: string }>, res: Response) => downloadNoteInt(req.params.noteId, res, true); +const openFile = (req: Request<{ noteId: string }>, res: Response) => downloadNoteInt(req.params.noteId, res, false); -const downloadAttachment = (req: Request, res: Response) => downloadAttachmentInt(req.params.attachmentId, res, true); -const openAttachment = (req: Request, res: Response) => downloadAttachmentInt(req.params.attachmentId, res, false); +const downloadAttachment = (req: Request<{ attachmentId: string }>, res: Response) => downloadAttachmentInt(req.params.attachmentId, res, true); +const openAttachment = (req: Request<{ attachmentId: string }>, res: Response) => downloadAttachmentInt(req.params.attachmentId, res, false); -function fileContentProvider(req: Request) { +function fileContentProvider(req: Request<{ noteId: string }>) { // Read the file name from route params. const note = becca.getNoteOrThrow(req.params.noteId); return streamContent(note.getContent(), note.getFileName(), note.mime); } -function attachmentContentProvider(req: Request) { +function attachmentContentProvider(req: Request<{ attachmentId: string }>) { // Read the file name from route params. const attachment = becca.getAttachmentOrThrow(req.params.attachmentId); @@ -149,7 +147,7 @@ async function streamContent(content: string | Buffer, fileName: string, mimeTyp }; } -function saveNoteToTmpDir(req: Request) { +function saveNoteToTmpDir(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); const fileName = note.getFileName(); const content = note.getContent(); @@ -157,7 +155,7 @@ function saveNoteToTmpDir(req: Request) { return saveToTmpDir(fileName, content, "notes", note.noteId); } -function saveAttachmentToTmpDir(req: Request) { +function saveAttachmentToTmpDir(req: Request<{ attachmentId: string }>) { const attachment = becca.getAttachmentOrThrow(req.params.attachmentId); const fileName = attachment.getFileName(); const content = attachment.getContent(); @@ -205,7 +203,7 @@ function saveToTmpDir(fileName: string, content: string | Buffer, entityType: st }; } -function uploadModifiedFileToNote(req: Request) { +function uploadModifiedFileToNote(req: Request<{ noteId: string }>) { const noteId = req.params.noteId; const { filePath } = req.body; @@ -228,7 +226,7 @@ function uploadModifiedFileToNote(req: Request) { note.setContent(fileContent); } -function uploadModifiedFileToAttachment(req: Request) { +function uploadModifiedFileToAttachment(req: Request<{ attachmentId: string }>) { const { attachmentId } = req.params; const { filePath } = req.body; diff --git a/apps/server/src/routes/api/image.ts b/apps/server/src/routes/api/image.ts index aa24e7aae9..60854e6f24 100644 --- a/apps/server/src/routes/api/image.ts +++ b/apps/server/src/routes/api/image.ts @@ -1,20 +1,19 @@ -"use strict"; - -import imageService from "../../services/image.js"; -import becca from "../../becca/becca.js"; -import fs from "fs"; import type { Request, Response } from "express"; +import fs from "fs"; + +import becca from "../../becca/becca.js"; import type BNote from "../../becca/entities/bnote.js"; import type BRevision from "../../becca/entities/brevision.js"; +import imageService from "../../services/image.js"; import { RESOURCE_DIR } from "../../services/resource_dir.js"; -function returnImageFromNote(req: Request, res: Response) { +function returnImageFromNote(req: Request<{ noteId: string }>, res: Response) { const image = becca.getNote(req.params.noteId); return returnImageInt(image, res); } -function returnImageFromRevision(req: Request, res: Response) { +function returnImageFromRevision(req: Request<{ revisionId: string }>, res: Response) { const image = becca.getRevision(req.params.revisionId); return returnImageInt(image, res); @@ -61,7 +60,7 @@ export function renderSvgAttachment(image: BNote | BRevision, res: Response, att res.send(svg); } -function returnAttachedImage(req: Request, res: Response) { +function returnAttachedImage(req: Request<{ attachmentId: string }>, res: Response) { const attachment = becca.getAttachment(req.params.attachmentId); if (!attachment) { @@ -78,7 +77,7 @@ function returnAttachedImage(req: Request, res: Response) { res.send(attachment.getContent()); } -function updateImage(req: Request) { +function updateImage(req: Request<{ noteId: string }>) { const { noteId } = req.params; const { file } = req; diff --git a/apps/server/src/routes/api/import.ts b/apps/server/src/routes/api/import.ts index 273dc1e1da..7f3b657d24 100644 --- a/apps/server/src/routes/api/import.ts +++ b/apps/server/src/routes/api/import.ts @@ -1,21 +1,20 @@ -"use strict"; - -import enexImportService from "../../services/import/enex.js"; -import opmlImportService from "../../services/import/opml.js"; -import zipImportService from "../../services/import/zip.js"; -import singleImportService from "../../services/import/single.js"; -import cls from "../../services/cls.js"; +import type { Request } from "express"; import path from "path"; + import becca from "../../becca/becca.js"; import beccaLoader from "../../becca/becca_loader.js"; +import type BNote from "../../becca/entities/bnote.js"; +import ValidationError from "../../errors/validation_error.js"; +import cls from "../../services/cls.js"; +import enexImportService from "../../services/import/enex.js"; +import opmlImportService from "../../services/import/opml.js"; +import singleImportService from "../../services/import/single.js"; +import zipImportService from "../../services/import/zip.js"; import log from "../../services/log.js"; import TaskContext from "../../services/task_context.js"; -import ValidationError from "../../errors/validation_error.js"; -import type { Request } from "express"; -import type BNote from "../../becca/entities/bnote.js"; import { safeExtractMessageAndStackFromError } from "../../services/utils.js"; -async function importNotesToBranch(req: Request) { +async function importNotesToBranch(req: Request<{ parentNoteId: string }>) { const { parentNoteId } = req.params; const { taskId, last } = req.body; @@ -88,7 +87,7 @@ async function importNotesToBranch(req: Request) { setTimeout( () => taskContext.taskSucceeded({ - parentNoteId: parentNoteId, + parentNoteId, importedNoteId: note?.noteId }), 1000 @@ -101,7 +100,7 @@ async function importNotesToBranch(req: Request) { return note.getPojo(); } -function importAttachmentsToNote(req: Request) { +function importAttachmentsToNote(req: Request<{ parentNoteId: string }>) { const { parentNoteId } = req.params; const { taskId, last } = req.body; @@ -138,7 +137,7 @@ function importAttachmentsToNote(req: Request) { setTimeout( () => taskContext.taskSucceeded({ - parentNoteId: parentNoteId + parentNoteId }), 1000 ); diff --git a/apps/server/src/routes/api/note_map.ts b/apps/server/src/routes/api/note_map.ts index 473388af09..35b2d35456 100644 --- a/apps/server/src/routes/api/note_map.ts +++ b/apps/server/src/routes/api/note_map.ts @@ -1,11 +1,12 @@ -"use strict"; -import becca from "../../becca/becca.js"; -import type BNote from "../../becca/entities/bnote.js"; -import type BAttribute from "../../becca/entities/battribute.js"; + +import { BacklinkCountResponse, BacklinksResponse } from "@triliumnext/commons"; import type { Request } from "express"; import { HTMLElement, parse, TextNode } from "node-html-parser"; -import { BacklinkCountResponse, BacklinksResponse } from "@triliumnext/commons"; + +import becca from "../../becca/becca.js"; +import type BAttribute from "../../becca/entities/battribute.js"; +import type BNote from "../../becca/entities/bnote.js"; interface TreeLink { sourceNoteId: string; @@ -97,7 +98,7 @@ function getNeighbors(note: BNote, depth: number): string[] { return retNoteIds; } -function getLinkMap(req: Request) { +function getLinkMap(req: Request<{ noteId: string }>) { const mapRootNote = becca.getNoteOrThrow(req.params.noteId); // if the map root itself has "excludeFromNoteMap" attribute (journal typically) then there wouldn't be anything @@ -156,9 +157,9 @@ function getLinkMap(req: Request) { return false; } else if (excludeRelations.has(rel.name)) { return false; - } else { - return true; - } + } + return true; + }) .map((rel) => ({ id: `${rel.noteId}-${rel.name}-${rel.value}`, @@ -168,13 +169,13 @@ function getLinkMap(req: Request) { })); return { - notes: notes, + notes, noteIdToDescendantCountMap: buildDescendantCountMap(noteIdsArray), - links: links + links }; } -function getTreeMap(req: Request) { +function getTreeMap(req: Request<{ noteId: string }>) { const mapRootNote = becca.getNoteOrThrow(req.params.noteId); // if the map root itself has "excludeFromNoteMap" (journal typically) then there wouldn't be anything to display, // so we'll just ignore it @@ -223,9 +224,9 @@ function getTreeMap(req: Request) { updateDescendantCountMapForSearch(noteIdToDescendantCountMap, subtree.relationships); return { - notes: notes, - noteIdToDescendantCountMap: noteIdToDescendantCountMap, - links: links + notes, + noteIdToDescendantCountMap, + links }; } @@ -350,7 +351,7 @@ function getFilteredBacklinks(note: BNote): BAttribute[] { ); } -function getBacklinkCount(req: Request) { +function getBacklinkCount(req: Request<{ noteId: string }>) { const { noteId } = req.params; const note = becca.getNoteOrThrow(noteId); @@ -360,7 +361,7 @@ function getBacklinkCount(req: Request) { } satisfies BacklinkCountResponse; } -function getBacklinks(req: Request): BacklinksResponse { +function getBacklinks(req: Request<{ noteId: string }>): BacklinksResponse { const { noteId } = req.params; const note = becca.getNoteOrThrow(noteId); diff --git a/apps/server/src/routes/api/notes.ts b/apps/server/src/routes/api/notes.ts index 3c6db40549..e95ac75e96 100644 --- a/apps/server/src/routes/api/notes.ts +++ b/apps/server/src/routes/api/notes.ts @@ -1,18 +1,19 @@ -"use strict"; -import noteService from "../../services/notes.js"; -import eraseService from "../../services/erase.js"; -import treeService from "../../services/tree.js"; -import sql from "../../services/sql.js"; -import utils from "../../services/utils.js"; -import log from "../../services/log.js"; -import TaskContext from "../../services/task_context.js"; + +import type { AttributeRow, CreateChildrenResponse, DeleteNotesPreview, MetadataResponse } from "@triliumnext/commons"; +import type { Request } from "express"; + import becca from "../../becca/becca.js"; +import type BBranch from "../../becca/entities/bbranch.js"; import ValidationError from "../../errors/validation_error.js"; import blobService from "../../services/blob.js"; -import type { Request } from "express"; -import type BBranch from "../../becca/entities/bbranch.js"; -import type { AttributeRow, CreateChildrenResponse, DeleteNotesPreview, MetadataResponse } from "@triliumnext/commons"; +import eraseService from "../../services/erase.js"; +import log from "../../services/log.js"; +import noteService from "../../services/notes.js"; +import sql from "../../services/sql.js"; +import TaskContext from "../../services/task_context.js"; +import treeService from "../../services/tree.js"; +import utils from "../../services/utils.js"; /** * @swagger @@ -39,7 +40,7 @@ import type { AttributeRow, CreateChildrenResponse, DeleteNotesPreview, Metadata * - session: [] * tags: ["data"] */ -function getNote(req: Request) { +function getNote(req: Request<{ noteId: string }>) { return becca.getNoteOrThrow(req.params.noteId); } @@ -66,7 +67,7 @@ function getNote(req: Request) { * - session: [] * tags: ["data"] */ -function getNoteBlob(req: Request) { +function getNoteBlob(req: Request<{ noteId: string }>) { return blobService.getBlobPojo("notes", req.params.noteId); } @@ -93,7 +94,7 @@ function getNoteBlob(req: Request) { * - session: [] * tags: ["data"] */ -function getNoteMetadata(req: Request) { +function getNoteMetadata(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); return { @@ -126,7 +127,7 @@ function createNote(req: Request) { } satisfies CreateChildrenResponse; } -function updateNoteData(req: Request) { +function updateNoteData(req: Request<{ noteId: string }>) { const { content, attachments } = req.body; const { noteId } = req.params; @@ -170,7 +171,7 @@ function updateNoteData(req: Request) { * - session: [] * tags: ["data"] */ -function deleteNote(req: Request) { +function deleteNote(req: Request<{ noteId: string }>) { const noteId = req.params.noteId; const taskId = req.query.taskId; const eraseNotes = req.query.eraseNotes === "true"; @@ -197,7 +198,7 @@ function deleteNote(req: Request) { } } -function undeleteNote(req: Request) { +function undeleteNote(req: Request<{ noteId: string }>) { const taskContext = TaskContext.getInstance(utils.randomString(10), "undeleteNotes", null); noteService.undeleteNote(req.params.noteId, taskContext); @@ -205,7 +206,7 @@ function undeleteNote(req: Request) { taskContext.taskSucceeded(null); } -function sortChildNotes(req: Request) { +function sortChildNotes(req: Request<{ noteId: string }>) { const noteId = req.params.noteId; const { sortBy, sortDirection, foldersFirst, sortNatural, sortLocale } = req.body; @@ -216,7 +217,7 @@ function sortChildNotes(req: Request) { treeService.sortNotes(noteId, sortBy, reverse, foldersFirst, sortNatural, sortLocale); } -function protectNote(req: Request) { +function protectNote(req: Request<{ noteId: string; isProtected: string }>) { const noteId = req.params.noteId; const note = becca.notes[noteId]; const protect = !!parseInt(req.params.isProtected); @@ -229,7 +230,7 @@ function protectNote(req: Request) { taskContext.taskSucceeded(null); } -function setNoteTypeMime(req: Request) { +function setNoteTypeMime(req: Request<{ noteId: string }>) { // can't use [] destructuring because req.params is not iterable const { noteId } = req.params; const { type, mime } = req.body; @@ -240,7 +241,7 @@ function setNoteTypeMime(req: Request) { note.save(); } -function changeTitle(req: Request) { +function changeTitle(req: Request<{ noteId: string }>) { const noteId = req.params.noteId; const title = req.body.title; @@ -267,7 +268,7 @@ function changeTitle(req: Request) { return note; } -function duplicateSubtree(req: Request) { +function duplicateSubtree(req: Request<{ noteId: string; parentNoteId: string }>) { const { noteId, parentNoteId } = req.params; return noteService.duplicateSubtree(noteId, parentNoteId); @@ -342,7 +343,7 @@ function getDeleteNotesPreview(req: Request) { } satisfies DeleteNotesPreview; } -function forceSaveRevision(req: Request) { +function forceSaveRevision(req: Request<{ noteId: string }>) { const { noteId } = req.params; const note = becca.getNoteOrThrow(noteId); @@ -353,7 +354,7 @@ function forceSaveRevision(req: Request) { note.saveRevision(); } -function convertNoteToAttachment(req: Request) { +function convertNoteToAttachment(req: Request<{ noteId: string }>) { const { noteId } = req.params; const note = becca.getNoteOrThrow(noteId); diff --git a/apps/server/src/routes/api/options.ts b/apps/server/src/routes/api/options.ts index 6234321676..bb6ffb00d6 100644 --- a/apps/server/src/routes/api/options.ts +++ b/apps/server/src/routes/api/options.ts @@ -128,7 +128,7 @@ function getOptions() { return resultMap; } -function updateOption(req: Request) { +function updateOption(req: Request<{ name: string; value: string }>) { const { name, value } = req.params; if (!update(name, value)) { diff --git a/apps/server/src/routes/api/recent_changes.ts b/apps/server/src/routes/api/recent_changes.ts index 9dd2465888..3b768b534b 100644 --- a/apps/server/src/routes/api/recent_changes.ts +++ b/apps/server/src/routes/api/recent_changes.ts @@ -1,13 +1,12 @@ -"use strict"; - -import sql from "../../services/sql.js"; -import protectedSessionService from "../../services/protected_session.js"; -import noteService from "../../services/notes.js"; -import becca from "../../becca/becca.js"; -import type { Request } from "express"; import type { RecentChangeRow } from "@triliumnext/commons"; +import type { Request } from "express"; -function getRecentChanges(req: Request) { +import becca from "../../becca/becca.js"; +import noteService from "../../services/notes.js"; +import protectedSessionService from "../../services/protected_session.js"; +import sql from "../../services/sql.js"; + +function getRecentChanges(req: Request<{ ancestorNoteId: string }>) { const { ancestorNoteId } = req.params; let recentChanges: RecentChangeRow[] = []; diff --git a/apps/server/src/routes/api/revisions.ts b/apps/server/src/routes/api/revisions.ts index 9700e7f782..34dbce728e 100644 --- a/apps/server/src/routes/api/revisions.ts +++ b/apps/server/src/routes/api/revisions.ts @@ -1,18 +1,19 @@ -"use strict"; -import beccaService from "../../becca/becca_service.js"; -import utils from "../../services/utils.js"; -import sql from "../../services/sql.js"; -import cls from "../../services/cls.js"; -import path from "path"; -import becca from "../../becca/becca.js"; -import blobService from "../../services/blob.js"; -import eraseService from "../../services/erase.js"; -import type { Request, Response } from "express"; -import type BRevision from "../../becca/entities/brevision.js"; -import type BNote from "../../becca/entities/bnote.js"; -import type { NotePojo } from "../../becca/becca-interface.js"; + import { EditedNotesResponse, RevisionItem, RevisionPojo, RevisionRow } from "@triliumnext/commons"; +import type { Request, Response } from "express"; +import path from "path"; + +import becca from "../../becca/becca.js"; +import beccaService from "../../becca/becca_service.js"; +import type { NotePojo } from "../../becca/becca-interface.js"; +import type BNote from "../../becca/entities/bnote.js"; +import type BRevision from "../../becca/entities/brevision.js"; +import blobService from "../../services/blob.js"; +import cls from "../../services/cls.js"; +import eraseService from "../../services/erase.js"; +import sql from "../../services/sql.js"; +import utils from "../../services/utils.js"; interface NotePath { noteId: string; @@ -26,13 +27,13 @@ interface NotePojoWithNotePath extends NotePojo { notePath?: string[] | null; } -function getRevisionBlob(req: Request) { +function getRevisionBlob(req: Request<{ revisionId: string }>) { const preview = req.query.preview === "true"; return blobService.getBlobPojo("revisions", req.params.revisionId, { preview }); } -function getRevisions(req: Request) { +function getRevisions(req: Request<{ noteId: string }>) { return becca.getRevisionsFromQuery( ` SELECT revisions.*, @@ -45,7 +46,7 @@ function getRevisions(req: Request) { ) satisfies RevisionItem[]; } -function getRevision(req: Request) { +function getRevision(req: Request<{ revisionId: string }>) { const revision = becca.getRevisionOrThrow(req.params.revisionId); if (revision.type === "file") { @@ -85,7 +86,7 @@ function getRevisionFilename(revision: BRevision) { return filename; } -function downloadRevision(req: Request, res: Response) { +function downloadRevision(req: Request<{ revisionId: string }>, res: Response) { const revision = becca.getRevisionOrThrow(req.params.revisionId); if (!revision.isContentAvailable()) { @@ -100,13 +101,13 @@ function downloadRevision(req: Request, res: Response) { res.send(revision.getContent()); } -function eraseAllRevisions(req: Request) { +function eraseAllRevisions(req: Request<{ noteId: string }>) { const revisionIdsToErase = sql.getColumn("SELECT revisionId FROM revisions WHERE noteId = ?", [req.params.noteId]); eraseService.eraseRevisions(revisionIdsToErase); } -function eraseRevision(req: Request) { +function eraseRevision(req: Request<{ revisionId: string }>) { eraseService.eraseRevisions([req.params.revisionId]); } @@ -117,7 +118,7 @@ function eraseAllExcessRevisions() { }); } -function restoreRevision(req: Request) { +function restoreRevision(req: Request<{ revisionId: string }>) { const revision = becca.getRevision(req.params.revisionId); if (revision) { @@ -166,7 +167,7 @@ function getEditedNotesOnDate(req: Request) { ) ORDER BY isDeleted LIMIT 50`, - { date: `${req.params.date}%` } + { date: `${req.params.date}%` } ); let notes = becca.getNotes(noteIds, true); @@ -204,7 +205,7 @@ function getNotePathData(note: BNote): NotePath | undefined { return { noteId: note.noteId, - branchId: branchId, + branchId, title: noteTitle, notePath: retPath, path: retPath.join("/") diff --git a/apps/server/src/routes/api/script.ts b/apps/server/src/routes/api/script.ts index 5f6877ad3b..eda6dff878 100644 --- a/apps/server/src/routes/api/script.ts +++ b/apps/server/src/routes/api/script.ts @@ -1,11 +1,12 @@ -"use strict"; -import scriptService, { type Bundle } from "../../services/script.js"; -import attributeService from "../../services/attributes.js"; -import becca from "../../becca/becca.js"; -import syncService from "../../services/sync.js"; -import sql from "../../services/sql.js"; + import type { Request } from "express"; + +import becca from "../../becca/becca.js"; +import attributeService from "../../services/attributes.js"; +import scriptService, { type Bundle } from "../../services/script.js"; +import sql from "../../services/sql.js"; +import syncService from "../../services/sync.js"; import { safeExtractMessageAndStackFromError } from "../../services/utils.js"; interface ScriptBody { @@ -43,7 +44,7 @@ async function exec(req: Request) { } } -function run(req: Request) { +function run(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); const result = scriptService.executeNote(note, { originEntity: note }); @@ -71,23 +72,23 @@ function getStartupBundles(req: Request) { if (!process.env.TRILIUM_SAFE_MODE) { if (req.query.mobile === "true") { return getBundlesWithLabel("run", "mobileStartup"); - } else { - return getBundlesWithLabel("run", "frontendStartup"); - } - } else { - return []; - } + } + return getBundlesWithLabel("run", "frontendStartup"); + + } + return []; + } function getWidgetBundles() { if (!process.env.TRILIUM_SAFE_MODE) { return getBundlesWithLabel("widget"); - } else { - return []; - } + } + return []; + } -function getRelationBundles(req: Request) { +function getRelationBundles(req: Request<{ noteId: string, relationName: string }>) { const noteId = req.params.noteId; const note = becca.getNoteOrThrow(noteId); const relationName = req.params.relationName; @@ -116,7 +117,7 @@ function getRelationBundles(req: Request) { return bundles; } -function getBundle(req: Request) { +function getBundle(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); const { script, params } = req.body ?? {}; diff --git a/apps/server/src/routes/api/search.ts b/apps/server/src/routes/api/search.ts index cbd5845299..ba9ad38584 100644 --- a/apps/server/src/routes/api/search.ts +++ b/apps/server/src/routes/api/search.ts @@ -1,19 +1,19 @@ -"use strict"; + import type { Request } from "express"; import becca from "../../becca/becca.js"; -import SearchContext from "../../services/search/search_context.js"; -import searchService, { EMPTY_RESULT, type SearchNoteResult } from "../../services/search/services/search.js"; +import beccaService from "../../becca/becca_service.js"; +import ValidationError from "../../errors/validation_error.js"; +import attributeFormatter from "../../services/attribute_formatter.js"; import bulkActionService from "../../services/bulk_actions.js"; import cls from "../../services/cls.js"; -import attributeFormatter from "../../services/attribute_formatter.js"; -import ValidationError from "../../errors/validation_error.js"; -import type SearchResult from "../../services/search/search_result.js"; import hoistedNoteService from "../../services/hoisted_note.js"; -import beccaService from "../../becca/becca_service.js"; +import SearchContext from "../../services/search/search_context.js"; +import type SearchResult from "../../services/search/search_result.js"; +import searchService, { EMPTY_RESULT, type SearchNoteResult } from "../../services/search/services/search.js"; -function searchFromNote(req: Request): SearchNoteResult { +function searchFromNote(req: Request<{ noteId: string }>): SearchNoteResult { const note = becca.getNoteOrThrow(req.params.noteId); if (!note) { @@ -28,7 +28,7 @@ function searchFromNote(req: Request): SearchNoteResult { return searchService.searchFromNote(note); } -function searchAndExecute(req: Request) { +function searchAndExecute(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); if (!note) { @@ -45,7 +45,7 @@ function searchAndExecute(req: Request) { bulkActionService.executeActionsFromNote(note, searchResultNoteIds); } -function quickSearch(req: Request) { +function quickSearch(req: Request<{ searchString: string }>) { const { searchString } = req.params; const searchContext = new SearchContext({ @@ -82,7 +82,7 @@ function quickSearch(req: Request) { highlightedContentSnippet: result.highlightedContentSnippet, attributeSnippet: result.attributeSnippet, highlightedAttributeSnippet: result.highlightedAttributeSnippet, - icon: icon + icon }; }); @@ -90,12 +90,12 @@ function quickSearch(req: Request) { return { searchResultNoteIds: resultNoteIds, - searchResults: searchResults, + searchResults, error: searchContext.getError() }; } -function search(req: Request) { +function search(req: Request<{ searchString: string }>) { const { searchString } = req.params; const searchContext = new SearchContext({ diff --git a/apps/server/src/routes/api/similar_notes.ts b/apps/server/src/routes/api/similar_notes.ts index 6b9cbb9261..41449d4154 100644 --- a/apps/server/src/routes/api/similar_notes.ts +++ b/apps/server/src/routes/api/similar_notes.ts @@ -1,12 +1,10 @@ -"use strict"; - +import { SimilarNoteResponse } from "@triliumnext/commons"; import type { Request } from "express"; -import similarityService from "../../becca/similarity.js"; import becca from "../../becca/becca.js"; -import { SimilarNoteResponse } from "@triliumnext/commons"; +import similarityService from "../../becca/similarity.js"; -async function getSimilarNotes(req: Request) { +async function getSimilarNotes(req: Request<{ noteId: string }>) { const noteId = req.params.noteId; const _note = becca.getNoteOrThrow(noteId); diff --git a/apps/server/src/routes/api/special_notes.ts b/apps/server/src/routes/api/special_notes.ts index aa3e9b6561..5169260709 100644 --- a/apps/server/src/routes/api/special_notes.ts +++ b/apps/server/src/routes/api/special_notes.ts @@ -6,33 +6,33 @@ import dateNoteService from "../../services/date_notes.js"; import specialNotesService, { type LauncherType } from "../../services/special_notes.js"; import sql from "../../services/sql.js"; -function getInboxNote(req: Request) { +function getInboxNote(req: Request<{ date: string }>) { return specialNotesService.getInboxNote(req.params.date); } -function getDayNote(req: Request) { +function getDayNote(req: Request<{ date: string }>) { const calendarRootId = req.query.calendarRootId; const calendarRoot = typeof calendarRootId === "string" ? becca.getNoteOrThrow(calendarRootId) : null; return dateNoteService.getDayNote(req.params.date, calendarRoot); } -function getWeekFirstDayNote(req: Request) { +function getWeekFirstDayNote(req: Request<{ date: string }>) { return dateNoteService.getWeekFirstDayNote(req.params.date); } -function getWeekNote(req: Request) { +function getWeekNote(req: Request<{ week: string }>) { return dateNoteService.getWeekNote(req.params.week); } -function getMonthNote(req: Request) { +function getMonthNote(req: Request<{ month: string }>) { return dateNoteService.getMonthNote(req.params.month); } -function getQuarterNote(req: Request) { +function getQuarterNote(req: Request<{ quarter: string }>) { return dateNoteService.getQuarterNote(req.params.quarter); } -function getYearNote(req: Request) { +function getYearNote(req: Request<{ year: string }>) { return dateNoteService.getYearNote(req.params.year); } @@ -90,7 +90,7 @@ function getHoistedNote() { return becca.getNote(cls.getHoistedNoteId()); } -function createLauncher(req: Request) { +function createLauncher(req: Request<{ parentNoteId: string, launcherType: string }>) { return specialNotesService.createLauncher({ parentNoteId: req.params.parentNoteId, // TODO: Validate the parameter @@ -98,7 +98,7 @@ function createLauncher(req: Request) { }); } -function resetLauncher(req: Request) { +function resetLauncher(req: Request<{ noteId: string }>) { return specialNotesService.resetLauncher(req.params.noteId); } diff --git a/apps/server/src/routes/api/sql.ts b/apps/server/src/routes/api/sql.ts index 33cd61b5e7..89401adacc 100644 --- a/apps/server/src/routes/api/sql.ts +++ b/apps/server/src/routes/api/sql.ts @@ -1,9 +1,8 @@ -"use strict"; - -import sql from "../../services/sql.js"; -import becca from "../../becca/becca.js"; import type { Request } from "express"; + +import becca from "../../becca/becca.js"; import ValidationError from "../../errors/validation_error.js"; +import sql from "../../services/sql.js"; import { safeExtractMessageAndStackFromError } from "../../services/utils.js"; interface Table { @@ -25,7 +24,7 @@ function getSchema() { return tables; } -function execute(req: Request) { +function execute(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); const content = note.getContent(); diff --git a/apps/server/src/routes/api/stats.ts b/apps/server/src/routes/api/stats.ts index aebca079e3..4b4f2e8b58 100644 --- a/apps/server/src/routes/api/stats.ts +++ b/apps/server/src/routes/api/stats.ts @@ -1,7 +1,8 @@ -import sql from "../../services/sql.js"; -import becca from "../../becca/becca.js"; -import type { Request } from "express"; import { NoteSizeResponse, SubtreeSizeResponse } from "@triliumnext/commons"; +import type { Request } from "express"; + +import becca from "../../becca/becca.js"; +import sql from "../../services/sql.js"; function getNoteSize(req: Request) { const { noteId } = req.params; @@ -26,7 +27,7 @@ function getNoteSize(req: Request) { } satisfies NoteSizeResponse; } -function getSubtreeSize(req: Request) { +function getSubtreeSize(req: Request<{ noteId: string }>) { const note = becca.getNoteOrThrow(req.params.noteId); const subTreeNoteIds = note.getSubtreeNoteIds(); diff --git a/apps/server/src/routes/api/sync.ts b/apps/server/src/routes/api/sync.ts index 5e1c53041c..84e0683138 100644 --- a/apps/server/src/routes/api/sync.ts +++ b/apps/server/src/routes/api/sync.ts @@ -1,21 +1,22 @@ -"use strict"; -import syncService from "../../services/sync.js"; -import syncUpdateService from "../../services/sync_update.js"; -import entityChangesService from "../../services/entity_changes.js"; -import sql from "../../services/sql.js"; -import sqlInit from "../../services/sql_init.js"; -import optionService from "../../services/options.js"; -import contentHashService from "../../services/content_hash.js"; -import log from "../../services/log.js"; -import syncOptions from "../../services/sync_options.js"; -import utils, { safeExtractMessageAndStackFromError } from "../../services/utils.js"; -import ws from "../../services/ws.js"; + +import { type EntityChange,SyncTestResponse } from "@triliumnext/commons"; import type { Request } from "express"; +import { t } from "i18next"; + import ValidationError from "../../errors/validation_error.js"; import consistencyChecksService from "../../services/consistency_checks.js"; -import { t } from "i18next"; -import { SyncTestResponse, type EntityChange } from "@triliumnext/commons"; +import contentHashService from "../../services/content_hash.js"; +import entityChangesService from "../../services/entity_changes.js"; +import log from "../../services/log.js"; +import optionService from "../../services/options.js"; +import sql from "../../services/sql.js"; +import sqlInit from "../../services/sql_init.js"; +import syncService from "../../services/sync.js"; +import syncOptions from "../../services/sync_options.js"; +import syncUpdateService from "../../services/sync_update.js"; +import utils, { safeExtractMessageAndStackFromError } from "../../services/utils.js"; +import ws from "../../services/ws.js"; async function testSync(): Promise { try { @@ -287,10 +288,10 @@ function update(req: Request) { if (pageIndex !== pageCount - 1) { return; - } else { - body = JSON.parse(partialRequests[requestId].payload); - delete partialRequests[requestId]; - } + } + body = JSON.parse(partialRequests[requestId].payload); + delete partialRequests[requestId]; + } const { entities, instanceId } = body; @@ -314,7 +315,7 @@ function syncFinished() { sqlInit.setDbAsInitialized(); } -function queueSector(req: Request) { +function queueSector(req: Request<{ entityName: string; sector: string }>) { const entityName = utils.sanitizeSqlIdentifier(req.params.entityName); const sector = utils.sanitizeSqlIdentifier(req.params.sector); diff --git a/apps/server/src/routes/route_api.ts b/apps/server/src/routes/route_api.ts index 1b4ea48f24..444cc260d4 100644 --- a/apps/server/src/routes/route_api.ts +++ b/apps/server/src/routes/route_api.ts @@ -1,15 +1,17 @@ import express, { type RequestHandler } from "express"; +import type { ParamsDictionary } from "express-serve-static-core"; import multer from "multer"; -import log from "../services/log.js"; -import cls from "../services/cls.js"; -import sql from "../services/sql.js"; -import entityChangesService from "../services/entity_changes.js"; + import AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js"; import NotFoundError from "../errors/not_found_error.js"; import ValidationError from "../errors/validation_error.js"; import auth from "../services/auth.js"; -import { doubleCsrfProtection as csrfMiddleware } from "./csrf_protection.js"; +import cls from "../services/cls.js"; +import entityChangesService from "../services/entity_changes.js"; +import log from "../services/log.js"; +import sql from "../services/sql.js"; import { safeExtractMessageAndStackFromError } from "../services/utils.js"; +import { doubleCsrfProtection as csrfMiddleware } from "./csrf_protection.js"; const MAX_ALLOWED_FILE_SIZE_MB = 250; export const router = express.Router(); @@ -20,8 +22,8 @@ type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options export type ApiResultHandler = (req: express.Request, res: express.Response, result: unknown) => number; 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; +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) { @@ -67,9 +69,9 @@ export function apiResultHandler(req: express.Request, res: express.Response, re return send(res, statusCode, response); } else if (result === undefined) { return send(res, 204, ""); - } else { - return send(res, 200, result); } + return send(res, 200, result); + } function send(res: express.Response, statusCode: number, response: unknown) { @@ -81,34 +83,34 @@ function send(res: express.Response, statusCode: number, response: unknown) { res.status(statusCode).send(response); return response.length; - } else { - const json = JSON.stringify(response); - - res.setHeader("Content-Type", "application/json"); - res.status(statusCode).send(json); - - return json.length; } + const json = JSON.stringify(response); + + res.setHeader("Content-Type", "application/json"); + res.status(statusCode).send(json); + + return json.length; + } -export function apiRoute(method: HttpMethod, path: string, routeHandler: SyncRouteRequestHandler) { +export function apiRoute

(method: HttpMethod, path: string, routeHandler: SyncRouteRequestHandler

) { route(method, path, [auth.checkApiAuth, csrfMiddleware], routeHandler, apiResultHandler); } -export function asyncApiRoute(method: HttpMethod, path: string, routeHandler: ApiRequestHandler) { +export function asyncApiRoute

(method: HttpMethod, path: string, routeHandler: ApiRequestHandler

) { asyncRoute(method, path, [auth.checkApiAuth, csrfMiddleware], routeHandler, apiResultHandler); } -export function route(method: HttpMethod, path: string, middleware: express.Handler[], routeHandler: SyncRouteRequestHandler, resultHandler: ApiResultHandler | null = null) { +export function route

(method: HttpMethod, path: string, middleware: express.Handler[], routeHandler: SyncRouteRequestHandler

, resultHandler: ApiResultHandler | null = null) { internalRoute(method, path, middleware, routeHandler, resultHandler, true); } -export function asyncRoute(method: HttpMethod, path: string, middleware: express.Handler[], routeHandler: ApiRequestHandler, resultHandler: ApiResultHandler | null = null) { +export function asyncRoute

(method: HttpMethod, path: string, middleware: express.Handler[], routeHandler: ApiRequestHandler

, resultHandler: ApiResultHandler | null = null) { internalRoute(method, path, middleware, routeHandler, resultHandler, false); } -function internalRoute(method: HttpMethod, path: string, middleware: express.Handler[], routeHandler: ApiRequestHandler, resultHandler: ApiResultHandler | null = null, transactional: boolean) { - router[method](path, ...(middleware as express.Handler[]), (req: express.Request, res: express.Response, next: express.NextFunction) => { +function internalRoute

(method: HttpMethod, path: string, middleware: express.Handler[], routeHandler: ApiRequestHandler

, resultHandler: ApiResultHandler | null = null, transactional: boolean) { + router[method](path, ...(middleware as express.Handler[]), (req: express.Request

, res: express.Response, next: express.NextFunction) => { const start = Date.now(); try { @@ -193,7 +195,7 @@ export function createUploadMiddleware(): RequestHandler { const uploadMiddleware = createUploadMiddleware(); export const uploadMiddlewareWithErrorHandling = function (req: express.Request, res: express.Response, next: express.NextFunction) { - uploadMiddleware(req, res, function (err) { + uploadMiddleware(req, res, (err) => { if (err?.code === "LIMIT_FILE_SIZE") { res.setHeader("Content-Type", "text/plain").status(400).send(`Cannot upload file because it excceeded max allowed file size of ${MAX_ALLOWED_FILE_SIZE_MB} MiB`); } else { diff --git a/apps/server/src/routes/routes.ts b/apps/server/src/routes/routes.ts index 5c1fbcd167..ce9b84f0a9 100644 --- a/apps/server/src/routes/routes.ts +++ b/apps/server/src/routes/routes.ts @@ -10,14 +10,13 @@ import etapiBackupRoute from "../etapi/backup.js"; import etapiBranchRoutes from "../etapi/branches.js"; import etapiMetricsRoute from "../etapi/metrics.js"; import etapiNoteRoutes from "../etapi/notes.js"; +import etapiRevisionsRoutes from "../etapi/revisions.js"; import etapiSpecRoute from "../etapi/spec.js"; import etapiSpecialNoteRoutes from "../etapi/special_notes.js"; -import etapiRevisionsRoutes from "../etapi/revisions.js"; import auth from "../services/auth.js"; import openID from '../services/open_id.js'; import { isElectron } from "../services/utils.js"; import shareRoutes from "../share/routes.js"; - import appInfoRoute from "./api/app_info.js"; import attachmentsApiRoute from "./api/attachments.js"; import attributesRoute from "./api/attributes.js"; @@ -35,12 +34,10 @@ import fontsRoute from "./api/fonts.js"; import imageRoute from "./api/image.js"; import importRoute from "./api/import.js"; import keysRoute from "./api/keys.js"; - import loginApiRoute from "./api/login.js"; import metricsRoute from "./api/metrics.js"; import noteMapRoute from "./api/note_map.js"; import notesApiRoute from "./api/notes.js"; - import optionsApiRoute from "./api/options.js"; import otherRoute from "./api/other.js"; import passwordApiRoute from "./api/password.js"; diff --git a/packages/express-partial-content/src/ContentProvider.ts b/packages/express-partial-content/src/ContentProvider.ts index 6fb2648c34..819171b242 100644 --- a/packages/express-partial-content/src/ContentProvider.ts +++ b/packages/express-partial-content/src/ContentProvider.ts @@ -1,6 +1,8 @@ import type { Request } from "express"; import type { Content } from "./Content.js"; +import type { ParamsDictionary } from "express-serve-static-core"; + /** * @type {function (Request): Promise} */ -export type ContentProvider = (req: Request) => Promise; +export type ContentProvider

= (req: Request

) => Promise; diff --git a/packages/express-partial-content/src/createPartialContentHandler.ts b/packages/express-partial-content/src/createPartialContentHandler.ts index d3f3b15958..67e6a6005b 100644 --- a/packages/express-partial-content/src/createPartialContentHandler.ts +++ b/packages/express-partial-content/src/createPartialContentHandler.ts @@ -3,6 +3,7 @@ import { parseRangeHeader } from "./parseRangeHeader.js"; import { RangeParserError } from "./RangeParserError.js"; import type { Logger } from "./Logger.js"; import type { ContentProvider } from "./ContentProvider.js"; +import type { ParamsDictionary } from "express-serve-static-core"; import { ContentDoesNotExistError } from "./ContentDoesNotExistError.js"; import { getRangeHeader, @@ -13,8 +14,8 @@ import { setContentLengthHeader, setCacheControlHeaderNoCache } from "./utils.js"; -export function createPartialContentHandler(contentProvider: ContentProvider, logger: Logger) { - return async function handler(req: Request, res: Response) { +export function createPartialContentHandler

(contentProvider: ContentProvider

, logger: Logger) { + return async function handler(req: Request

, res: Response) { let content; try { content = await contentProvider(req);