chore(prettier): fix all files

This commit is contained in:
Elian Doran
2025-01-09 18:07:02 +02:00
parent 19ee861699
commit 4cbb529fd4
571 changed files with 23226 additions and 23940 deletions

View File

@@ -1,9 +1,9 @@
import { Router } from 'express';
import { Router } from "express";
import appInfo from "../services/app_info.js";
import eu from "./etapi_utils.js";
function register(router: Router) {
eu.route(router, 'get', '/etapi/app-info', (req, res, next) => {
eu.route(router, "get", "/etapi/app-info", (req, res, next) => {
res.status(200).json(appInfo);
});
}

View File

@@ -3,21 +3,21 @@ import eu from "./etapi_utils.js";
import mappers from "./mappers.js";
import v from "./validators.js";
import utils from "../services/utils.js";
import { Router } from 'express';
import { AttachmentRow } from '../becca/entities/rows.js';
import { ValidatorMap } from './etapi-interface.js';
import { Router } from "express";
import { AttachmentRow } from "../becca/entities/rows.js";
import { ValidatorMap } from "./etapi-interface.js";
function register(router: Router) {
const ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT: ValidatorMap = {
'ownerId': [v.notNull, v.isNoteId],
'role': [v.notNull, v.isString],
'mime': [v.notNull, v.isString],
'title': [v.notNull, v.isString],
'position': [v.notNull, v.isInteger],
'content': [v.isString],
ownerId: [v.notNull, v.isNoteId],
role: [v.notNull, v.isString],
mime: [v.notNull, v.isString],
title: [v.notNull, v.isString],
position: [v.notNull, v.isInteger],
content: [v.isString]
};
eu.route(router, 'post', '/etapi/attachments', (req, res, next) => {
eu.route(router, "post", "/etapi/attachments", (req, res, next) => {
const _params: Partial<AttachmentRow> = {};
eu.validateAndPatch(_params, req.body, ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT);
const params = _params as AttachmentRow;
@@ -30,26 +30,25 @@ function register(router: Router) {
const attachment = note.saveAttachment(params);
res.status(201).json(mappers.mapAttachmentToPojo(attachment));
}
catch (e: any) {
} catch (e: any) {
throw new eu.EtapiError(500, eu.GENERIC_CODE, e.message);
}
});
eu.route(router, 'get', '/etapi/attachments/:attachmentId', (req, res, next) => {
eu.route(router, "get", "/etapi/attachments/:attachmentId", (req, res, next) => {
const attachment = eu.getAndCheckAttachment(req.params.attachmentId);
res.json(mappers.mapAttachmentToPojo(attachment));
});
const ALLOWED_PROPERTIES_FOR_PATCH = {
'role': [v.notNull, v.isString],
'mime': [v.notNull, v.isString],
'title': [v.notNull, v.isString],
'position': [v.notNull, v.isInteger],
role: [v.notNull, v.isString],
mime: [v.notNull, v.isString],
title: [v.notNull, v.isString],
position: [v.notNull, v.isInteger]
};
eu.route(router, 'patch', '/etapi/attachments/:attachmentId', (req, res, next) => {
eu.route(router, "patch", "/etapi/attachments/:attachmentId", (req, res, next) => {
const attachment = eu.getAndCheckAttachment(req.params.attachmentId);
if (attachment.isProtected) {
@@ -62,7 +61,7 @@ function register(router: Router) {
res.json(mappers.mapAttachmentToPojo(attachment));
});
eu.route(router, 'get', '/etapi/attachments/:attachmentId/content', (req, res, next) => {
eu.route(router, "get", "/etapi/attachments/:attachmentId/content", (req, res, next) => {
const attachment = eu.getAndCheckAttachment(req.params.attachmentId);
if (attachment.isProtected) {
@@ -71,15 +70,15 @@ function register(router: Router) {
const filename = utils.formatDownloadTitle(attachment.title, attachment.role, attachment.mime);
res.setHeader('Content-Disposition', utils.getContentDisposition(filename));
res.setHeader("Content-Disposition", utils.getContentDisposition(filename));
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
res.setHeader('Content-Type', attachment.mime);
res.setHeader("Content-Type", attachment.mime);
res.send(attachment.getContent());
});
eu.route(router, 'put', '/etapi/attachments/:attachmentId/content', (req, res, next) => {
eu.route(router, "put", "/etapi/attachments/:attachmentId/content", (req, res, next) => {
const attachment = eu.getAndCheckAttachment(req.params.attachmentId);
if (attachment.isProtected) {
@@ -91,7 +90,7 @@ function register(router: Router) {
return res.sendStatus(204);
});
eu.route(router, 'delete', '/etapi/attachments/:attachmentId', (req, res, next) => {
eu.route(router, "delete", "/etapi/attachments/:attachmentId", (req, res, next) => {
const attachment = becca.getAttachment(req.params.attachmentId);
if (!attachment) {

View File

@@ -3,29 +3,29 @@ import eu from "./etapi_utils.js";
import mappers from "./mappers.js";
import attributeService from "../services/attributes.js";
import v from "./validators.js";
import { Router } from 'express';
import { AttributeRow } from '../becca/entities/rows.js';
import { ValidatorMap } from './etapi-interface.js';
import { Router } from "express";
import { AttributeRow } from "../becca/entities/rows.js";
import { ValidatorMap } from "./etapi-interface.js";
function register(router: Router) {
eu.route(router, 'get', '/etapi/attributes/:attributeId', (req, res, next) => {
eu.route(router, "get", "/etapi/attributes/:attributeId", (req, res, next) => {
const attribute = eu.getAndCheckAttribute(req.params.attributeId);
res.json(mappers.mapAttributeToPojo(attribute));
});
const ALLOWED_PROPERTIES_FOR_CREATE_ATTRIBUTE: ValidatorMap = {
'attributeId': [v.mandatory, v.notNull, v.isValidEntityId],
'noteId': [v.mandatory, v.notNull, v.isNoteId],
'type': [v.mandatory, v.notNull, v.isAttributeType],
'name': [v.mandatory, v.notNull, v.isString],
'value': [v.notNull, v.isString],
'isInheritable': [v.notNull, v.isBoolean],
'position': [v.notNull, v.isInteger]
attributeId: [v.mandatory, v.notNull, v.isValidEntityId],
noteId: [v.mandatory, v.notNull, v.isNoteId],
type: [v.mandatory, v.notNull, v.isAttributeType],
name: [v.mandatory, v.notNull, v.isString],
value: [v.notNull, v.isString],
isInheritable: [v.notNull, v.isBoolean],
position: [v.notNull, v.isInteger]
};
eu.route(router, 'post', '/etapi/attributes', (req, res, next) => {
if (req.body.type === 'relation') {
eu.route(router, "post", "/etapi/attributes", (req, res, next) => {
if (req.body.type === "relation") {
eu.getAndCheckNote(req.body.value);
}
@@ -37,27 +37,26 @@ function register(router: Router) {
const attr = attributeService.createAttribute(params);
res.status(201).json(mappers.mapAttributeToPojo(attr));
}
catch (e: any) {
} catch (e: any) {
throw new eu.EtapiError(500, eu.GENERIC_CODE, e.message);
}
});
const ALLOWED_PROPERTIES_FOR_PATCH_LABEL = {
'value': [v.notNull, v.isString],
'position': [v.notNull, v.isInteger]
value: [v.notNull, v.isString],
position: [v.notNull, v.isInteger]
};
const ALLOWED_PROPERTIES_FOR_PATCH_RELATION = {
'position': [v.notNull, v.isInteger]
position: [v.notNull, v.isInteger]
};
eu.route(router, 'patch', '/etapi/attributes/:attributeId', (req, res, next) => {
eu.route(router, "patch", "/etapi/attributes/:attributeId", (req, res, next) => {
const attribute = eu.getAndCheckAttribute(req.params.attributeId);
if (attribute.type === 'label') {
if (attribute.type === "label") {
eu.validateAndPatch(attribute, req.body, ALLOWED_PROPERTIES_FOR_PATCH_LABEL);
} else if (attribute.type === 'relation') {
} else if (attribute.type === "relation") {
eu.getAndCheckNote(req.body.value);
eu.validateAndPatch(attribute, req.body, ALLOWED_PROPERTIES_FOR_PATCH_RELATION);
@@ -68,7 +67,7 @@ function register(router: Router) {
res.json(mappers.mapAttributeToPojo(attribute));
});
eu.route(router, 'delete', '/etapi/attributes/:attributeId', (req, res, next) => {
eu.route(router, "delete", "/etapi/attributes/:attributeId", (req, res, next) => {
const attribute = becca.getAttribute(req.params.attributeId);
if (!attribute) {

View File

@@ -2,24 +2,24 @@ import becca from "../becca/becca.js";
import eu from "./etapi_utils.js";
import passwordEncryptionService from "../services/encryption/password_encryption.js";
import etapiTokenService from "../services/etapi_tokens.js";
import { RequestHandler, Router } from 'express';
import { RequestHandler, Router } from "express";
function register(router: Router, loginMiddleware: RequestHandler[]) {
eu.NOT_AUTHENTICATED_ROUTE(router, 'post', '/etapi/auth/login', loginMiddleware, (req, res, next) => {
const {password, tokenName} = req.body;
eu.NOT_AUTHENTICATED_ROUTE(router, "post", "/etapi/auth/login", loginMiddleware, (req, res, next) => {
const { password, tokenName } = req.body;
if (!passwordEncryptionService.verifyPassword(password)) {
throw new eu.EtapiError(401, "WRONG_PASSWORD", "Wrong password.");
}
const {authToken} = etapiTokenService.createToken(tokenName || "ETAPI login");
const { authToken } = etapiTokenService.createToken(tokenName || "ETAPI login");
res.status(201).json({
authToken
});
});
eu.route(router, 'post', '/etapi/auth/logout', (req, res, next) => {
eu.route(router, "post", "/etapi/auth/logout", (req, res, next) => {
const parsed = etapiTokenService.parseAuthToken(req.headers.authorization);
if (!parsed || !parsed.etapiTokenId) {
@@ -41,4 +41,4 @@ function register(router: Router, loginMiddleware: RequestHandler[]) {
export default {
register
}
};

View File

@@ -4,7 +4,7 @@ import eu from "./etapi_utils.js";
import backupService from "../services/backup.js";
function register(router: Router) {
eu.route(router, 'put', '/etapi/backup/:backupName', async (req, res, next) => {
eu.route(router, "put", "/etapi/backup/:backupName", async (req, res, next) => {
await backupService.backupNow(req.params.backupName);
res.sendStatus(204);

View File

@@ -9,21 +9,21 @@ import v from "./validators.js";
import { BranchRow } from "../becca/entities/rows.js";
function register(router: Router) {
eu.route(router, 'get', '/etapi/branches/:branchId', (req, res, next) => {
eu.route(router, "get", "/etapi/branches/:branchId", (req, res, next) => {
const branch = eu.getAndCheckBranch(req.params.branchId);
res.json(mappers.mapBranchToPojo(branch));
});
const ALLOWED_PROPERTIES_FOR_CREATE_BRANCH = {
'noteId': [v.mandatory, v.notNull, v.isNoteId],
'parentNoteId': [v.mandatory, v.notNull, v.isNoteId],
'notePosition': [v.notNull, v.isInteger],
'prefix': [v.isString],
'isExpanded': [v.notNull, v.isBoolean]
noteId: [v.mandatory, v.notNull, v.isNoteId],
parentNoteId: [v.mandatory, v.notNull, v.isNoteId],
notePosition: [v.notNull, v.isInteger],
prefix: [v.isString],
isExpanded: [v.notNull, v.isBoolean]
};
eu.route(router, 'post', '/etapi/branches', (req, res, next) => {
eu.route(router, "post", "/etapi/branches", (req, res, next) => {
const _params = {};
eu.validateAndPatch(_params, req.body, ALLOWED_PROPERTIES_FOR_CREATE_BRANCH);
const params: BranchRow = _params as BranchRow;
@@ -49,12 +49,12 @@ function register(router: Router) {
});
const ALLOWED_PROPERTIES_FOR_PATCH = {
'notePosition': [v.notNull, v.isInteger],
'prefix': [v.isString],
'isExpanded': [v.notNull, v.isBoolean]
notePosition: [v.notNull, v.isInteger],
prefix: [v.isString],
isExpanded: [v.notNull, v.isBoolean]
};
eu.route(router, 'patch', '/etapi/branches/:branchId', (req, res, next) => {
eu.route(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(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(router, "post", "/etapi/refresh-note-ordering/:parentNoteId", (req, res, next) => {
eu.getAndCheckNote(req.params.parentNoteId);
entityChangesService.putNoteReorderingEntityChange(req.params.parentNoteId, "etapi");

View File

@@ -1,3 +1,3 @@
export type ValidatorFunc = (obj: unknown) => (string | undefined);
export type ValidatorFunc = (obj: unknown) => string | undefined;
export type ValidatorMap = Record<string, ValidatorFunc[]>;

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,8 @@ 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 { NextFunction, Request, RequestHandler, Response, Router } from 'express';
import { ValidatorMap } from './etapi-interface.js';
import { NextFunction, Request, RequestHandler, Response, Router } from "express";
import { ValidatorMap } from "./etapi-interface.js";
import { ApiRequestHandler } from "../routes/routes.js";
const GENERIC_CODE = "GENERIC";
@@ -30,20 +30,21 @@ class EtapiError extends Error {
function sendError(res: Response, statusCode: number, code: string, message: string) {
return res
.set('Content-Type', 'application/json')
.set("Content-Type", "application/json")
.status(statusCode)
.send(JSON.stringify({
"status": statusCode,
"code": code,
"message": message
}));
.send(
JSON.stringify({
status: statusCode,
code: code,
message: message
})
);
}
function checkEtapiAuth(req: Request, res: Response, next: NextFunction) {
if (noAuthentication || etapiTokenService.isValidAuthHeader(req.headers.authorization)) {
next();
}
else {
} else {
sendError(res, 401, "NOT_AUTHENTICATED", "Not authenticated");
}
}
@@ -54,8 +55,8 @@ function processRequest(req: Request, res: Response, routeHandler: ApiRequestHan
cls.namespace.bindEmitter(res);
cls.init(() => {
cls.set('componentId', "etapi");
cls.set('localNowDateTime', req.headers['trilium-local-now-datetime']);
cls.set("componentId", "etapi");
cls.set("localNowDateTime", req.headers["trilium-local-now-datetime"]);
const cb = () => routeHandler(req, res, next);
@@ -85,19 +86,17 @@ function getAndCheckNote(noteId: string) {
if (note) {
return note;
}
else {
} else {
throw new EtapiError(404, "NOTE_NOT_FOUND", `Note '${noteId}' not found.`);
}
}
function getAndCheckAttachment(attachmentId: string) {
const attachment = becca.getAttachment(attachmentId, {includeContentLength: true});
const attachment = becca.getAttachment(attachmentId, { includeContentLength: true });
if (attachment) {
return attachment;
}
else {
} else {
throw new EtapiError(404, "ATTACHMENT_NOT_FOUND", `Attachment '${attachmentId}' not found.`);
}
}
@@ -107,8 +106,7 @@ function getAndCheckBranch(branchId: string) {
if (branch) {
return branch;
}
else {
} else {
throw new EtapiError(404, "BRANCH_NOT_FOUND", `Branch '${branchId}' not found.`);
}
}
@@ -118,8 +116,7 @@ function getAndCheckAttribute(attributeId: string) {
if (attribute) {
return attribute;
}
else {
} else {
throw new EtapiError(404, "ATTRIBUTE_NOT_FOUND", `Attribute '${attributeId}' not found.`);
}
}
@@ -128,8 +125,7 @@ function validateAndPatch(target: any, source: any, allowedProperties: Validator
for (const key of Object.keys(source)) {
if (!(key in allowedProperties)) {
throw new EtapiError(400, "PROPERTY_NOT_ALLOWED", `Property '${key}' is not allowed for this method.`);
}
else {
} else {
for (const validator of allowedProperties[key]) {
const validationResult = validator(source[key]);
@@ -157,4 +153,4 @@ export default {
getAndCheckBranch,
getAndCheckAttribute,
getAndCheckAttachment
}
};

View File

@@ -15,11 +15,11 @@ function mapNoteToPojo(note: BNote) {
dateModified: note.dateModified,
utcDateCreated: note.utcDateCreated,
utcDateModified: note.utcDateModified,
parentNoteIds: note.getParentNotes().map(p => p.noteId),
childNoteIds: note.getChildNotes().map(ch => ch.noteId),
parentBranchIds: note.getParentBranches().map(p => p.branchId),
childBranchIds: note.getChildBranches().map(ch => ch.branchId),
attributes: note.getAttributes().map(attr => mapAttributeToPojo(attr))
parentNoteIds: note.getParentNotes().map((p) => p.noteId),
childNoteIds: note.getChildNotes().map((ch) => ch.noteId),
parentBranchIds: note.getParentBranches().map((p) => p.branchId),
childBranchIds: note.getChildBranches().map((ch) => ch.branchId),
attributes: note.getAttributes().map((attr) => mapAttributeToPojo(attr))
};
}

View File

@@ -9,28 +9,28 @@ 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 { Request, Router } from 'express';
import { ParsedQs } from 'qs';
import { NoteParams } from '../services/note-interface.js';
import { SearchParams } from '../services/search/services/types.js';
import { ValidatorMap } from './etapi-interface.js';
import { Request, Router } from "express";
import { ParsedQs } from "qs";
import { NoteParams } from "../services/note-interface.js";
import { SearchParams } from "../services/search/services/types.js";
import { ValidatorMap } from "./etapi-interface.js";
function register(router: Router) {
eu.route(router, 'get', '/etapi/notes', (req, res, next) => {
eu.route(router, "get", "/etapi/notes", (req, res, next) => {
const { search } = req.query;
if (typeof search !== "string" || !search?.trim()) {
throw new eu.EtapiError(400, 'SEARCH_QUERY_PARAM_MANDATORY', "'search' query parameter is mandatory.");
throw new eu.EtapiError(400, "SEARCH_QUERY_PARAM_MANDATORY", "'search' query parameter is mandatory.");
}
const searchParams = parseSearchParams(req);
const searchContext = new SearchContext(searchParams);
const searchResults = searchService.findResultsWithQuery(search, searchContext);
const foundNotes = searchResults.map(sr => becca.notes[sr.noteId]);
const foundNotes = searchResults.map((sr) => becca.notes[sr.noteId]);
const resp: any = {
results: foundNotes.map(note => mappers.mapNoteToPojo(note)),
results: foundNotes.map((note) => mappers.mapNoteToPojo(note))
};
if (searchContext.debugInfo) {
@@ -40,27 +40,27 @@ function register(router: Router) {
res.json(resp);
});
eu.route(router, 'get', '/etapi/notes/:noteId', (req, res, next) => {
eu.route(router, "get", "/etapi/notes/:noteId", (req, res, next) => {
const note = eu.getAndCheckNote(req.params.noteId);
res.json(mappers.mapNoteToPojo(note));
});
const ALLOWED_PROPERTIES_FOR_CREATE_NOTE: ValidatorMap = {
'parentNoteId': [v.mandatory, v.notNull, v.isNoteId],
'title': [v.mandatory, v.notNull, v.isString],
'type': [v.mandatory, v.notNull, v.isNoteType],
'mime': [v.notNull, v.isString],
'content': [v.notNull, v.isString],
'notePosition': [v.notNull, v.isInteger],
'prefix': [v.notNull, v.isString],
'isExpanded': [v.notNull, v.isBoolean],
'noteId': [v.notNull, v.isValidEntityId],
'dateCreated': [v.notNull, v.isString, v.isLocalDateTime],
'utcDateCreated': [v.notNull, v.isString, v.isUtcDateTime]
parentNoteId: [v.mandatory, v.notNull, v.isNoteId],
title: [v.mandatory, v.notNull, v.isString],
type: [v.mandatory, v.notNull, v.isNoteType],
mime: [v.notNull, v.isString],
content: [v.notNull, v.isString],
notePosition: [v.notNull, v.isInteger],
prefix: [v.notNull, v.isString],
isExpanded: [v.notNull, v.isBoolean],
noteId: [v.notNull, v.isValidEntityId],
dateCreated: [v.notNull, v.isString, v.isLocalDateTime],
utcDateCreated: [v.notNull, v.isString, v.isUtcDateTime]
};
eu.route(router, 'post', '/etapi/create-note', (req, res, next) => {
eu.route(router, "post", "/etapi/create-note", (req, res, next) => {
const _params = {};
eu.validateAndPatch(_params, req.body, ALLOWED_PROPERTIES_FOR_CREATE_NOTE);
const params = _params as NoteParams;
@@ -72,21 +72,20 @@ function register(router: Router) {
note: mappers.mapNoteToPojo(resp.note),
branch: mappers.mapBranchToPojo(resp.branch)
});
}
catch (e: any) {
} catch (e: any) {
return eu.sendError(res, 500, eu.GENERIC_CODE, e.message);
}
});
const ALLOWED_PROPERTIES_FOR_PATCH = {
'title': [v.notNull, v.isString],
'type': [v.notNull, v.isString],
'mime': [v.notNull, v.isString],
'dateCreated': [v.notNull, v.isString, v.isLocalDateTime],
'utcDateCreated': [v.notNull, v.isString, v.isUtcDateTime]
title: [v.notNull, v.isString],
type: [v.notNull, v.isString],
mime: [v.notNull, v.isString],
dateCreated: [v.notNull, v.isString, v.isLocalDateTime],
utcDateCreated: [v.notNull, v.isString, v.isUtcDateTime]
};
eu.route(router, 'patch', '/etapi/notes/:noteId', (req, res, next) => {
eu.route(router, "patch", "/etapi/notes/:noteId", (req, res, next) => {
const note = eu.getAndCheckNote(req.params.noteId);
if (note.isProtected) {
@@ -99,7 +98,7 @@ function register(router: Router) {
res.json(mappers.mapNoteToPojo(note));
});
eu.route(router, 'delete', '/etapi/notes/:noteId', (req, res, next) => {
eu.route(router, "delete", "/etapi/notes/:noteId", (req, res, next) => {
const { noteId } = req.params;
const note = becca.getNote(noteId);
@@ -108,12 +107,12 @@ function register(router: Router) {
return res.sendStatus(204);
}
note.deleteNote(null, new TaskContext('no-progress-reporting'));
note.deleteNote(null, new TaskContext("no-progress-reporting"));
res.sendStatus(204);
});
eu.route(router, 'get', '/etapi/notes/:noteId/content', (req, res, next) => {
eu.route(router, "get", "/etapi/notes/:noteId/content", (req, res, next) => {
const note = eu.getAndCheckNote(req.params.noteId);
if (note.isProtected) {
@@ -122,15 +121,15 @@ function register(router: Router) {
const filename = utils.formatDownloadTitle(note.title, note.type, note.mime);
res.setHeader('Content-Disposition', utils.getContentDisposition(filename));
res.setHeader("Content-Disposition", utils.getContentDisposition(filename));
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
res.setHeader('Content-Type', note.mime);
res.setHeader("Content-Type", note.mime);
res.send(note.getContent());
});
eu.route(router, 'put', '/etapi/notes/:noteId/content', (req, res, next) => {
eu.route(router, "put", "/etapi/notes/:noteId/content", (req, res, next) => {
const note = eu.getAndCheckNote(req.params.noteId);
if (note.isProtected) {
@@ -144,7 +143,7 @@ function register(router: Router) {
return res.sendStatus(204);
});
eu.route(router, 'get', '/etapi/notes/:noteId/export', (req, res, next) => {
eu.route(router, "get", "/etapi/notes/:noteId/export", (req, res, next) => {
const note = eu.getAndCheckNote(req.params.noteId);
const format = req.query.format || "html";
@@ -152,7 +151,7 @@ function register(router: Router) {
throw new eu.EtapiError(400, "UNRECOGNIZED_EXPORT_FORMAT", `Unrecognized export format '${format}', supported values are 'html' (default) or 'markdown'.`);
}
const taskContext = new TaskContext('no-progress-reporting');
const taskContext = new TaskContext("no-progress-reporting");
// technically a branch is being exported (includes prefix), but it's such a minor difference yet usability pain
// (e.g. branchIds are not seen in UI), that we export "note export" instead.
@@ -161,19 +160,19 @@ function register(router: Router) {
zipExportService.exportToZip(taskContext, branch, format as "html" | "markdown", res);
});
eu.route(router, 'post', '/etapi/notes/:noteId/import', (req, res, next) => {
eu.route(router, "post", "/etapi/notes/:noteId/import", (req, res, next) => {
const note = eu.getAndCheckNote(req.params.noteId);
const taskContext = new TaskContext('no-progress-reporting');
const taskContext = new TaskContext("no-progress-reporting");
zipImportService.importZip(taskContext, req.body, note).then(importedNote => {
zipImportService.importZip(taskContext, req.body, note).then((importedNote) => {
res.status(201).json({
note: mappers.mapNoteToPojo(importedNote),
branch: mappers.mapBranchToPojo(importedNote.getParentBranches()[0]),
branch: mappers.mapBranchToPojo(importedNote.getParentBranches()[0])
});
}); // 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(router, "post", "/etapi/notes/:noteId/revision", (req, res, next) => {
const note = eu.getAndCheckNote(req.params.noteId);
note.saveRevision();
@@ -181,27 +180,25 @@ function register(router: Router) {
return res.sendStatus(204);
});
eu.route(router, 'get', '/etapi/notes/:noteId/attachments', (req, res, next) => {
eu.route(router, "get", "/etapi/notes/:noteId/attachments", (req, res, next) => {
const note = eu.getAndCheckNote(req.params.noteId);
const attachments = note.getAttachments({ includeContentLength: true })
const attachments = note.getAttachments({ includeContentLength: true });
res.json(
attachments.map(attachment => mappers.mapAttachmentToPojo(attachment))
);
res.json(attachments.map((attachment) => mappers.mapAttachmentToPojo(attachment)));
});
}
function parseSearchParams(req: Request) {
const rawSearchParams: SearchParams = {
fastSearch: parseBoolean(req.query, 'fastSearch'),
includeArchivedNotes: parseBoolean(req.query, 'includeArchivedNotes'),
ancestorNoteId: parseString(req.query['ancestorNoteId']),
ancestorDepth: parseString(req.query['ancestorDepth']), // e.g. "eq5"
orderBy: parseString(req.query['orderBy']),
fastSearch: parseBoolean(req.query, "fastSearch"),
includeArchivedNotes: parseBoolean(req.query, "includeArchivedNotes"),
ancestorNoteId: parseString(req.query["ancestorNoteId"]),
ancestorDepth: parseString(req.query["ancestorDepth"]), // e.g. "eq5"
orderBy: parseString(req.query["orderBy"]),
// TODO: Check why the order direction was provided as a number, but it's a string everywhere else.
orderDirection: parseOrderDirection(req.query, 'orderDirection') as unknown as string,
limit: parseInteger(req.query, 'limit'),
debug: parseBoolean(req.query, 'debug')
orderDirection: parseOrderDirection(req.query, "orderDirection") as unknown as string,
limit: parseInteger(req.query, "limit"),
debug: parseBoolean(req.query, "debug")
};
const searchParams: SearchParams = {};
@@ -230,11 +227,11 @@ function parseBoolean(obj: any, name: string) {
return undefined;
}
if (!['true', 'false'].includes(obj[name])) {
if (!["true", "false"].includes(obj[name])) {
throw new eu.EtapiError(400, SEARCH_PARAM_ERROR, `Cannot parse boolean '${name}' value '${obj[name]}, allowed values are 'true' and 'false'.`);
}
return obj[name] === 'true';
return obj[name] === "true";
}
function parseOrderDirection(obj: any, name: string) {
@@ -244,7 +241,7 @@ function parseOrderDirection(obj: any, name: string) {
const integer = parseInt(obj[name]);
if (!['asc', 'desc'].includes(obj[name])) {
if (!["asc", "desc"].includes(obj[name])) {
throw new eu.EtapiError(400, SEARCH_PARAM_ERROR, `Cannot parse order direction value '${obj[name]}, allowed values are 'asc' and 'desc'.`);
}

View File

@@ -4,16 +4,16 @@ import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const specPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'etapi.openapi.yaml');
const specPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "etapi.openapi.yaml");
let spec: string | null = null;
function register(router: Router) {
router.get('/etapi/etapi.openapi.yaml', (req, res, next) => {
router.get("/etapi/etapi.openapi.yaml", (req, res, next) => {
if (!spec) {
spec = fs.readFileSync(specPath, 'utf8');
spec = fs.readFileSync(specPath, "utf8");
}
res.header('Content-Type', 'text/plain'); // so that it displays in browser
res.header("Content-Type", "text/plain"); // so that it displays in browser
res.status(200).send(spec);
});
}

View File

@@ -2,10 +2,10 @@ import specialNotesService from "../services/special_notes.js";
import dateNotesService from "../services/date_notes.js";
import eu from "./etapi_utils.js";
import mappers from "./mappers.js";
import { Router } from 'express';
import { Router } from "express";
const getDateInvalidError = (date: string) => new eu.EtapiError(400, "DATE_INVALID", `Date "${date}" is not valid.`);
const getMonthInvalidError = (month: string)=> new eu.EtapiError(400, "MONTH_INVALID", `Month "${month}" is not valid.`);
const getMonthInvalidError = (month: string) => new eu.EtapiError(400, "MONTH_INVALID", `Month "${month}" is not valid.`);
const getYearInvalidError = (year: string) => new eu.EtapiError(400, "YEAR_INVALID", `Year "${year}" is not valid.`);
function isValidDate(date: string) {
@@ -17,7 +17,7 @@ function isValidDate(date: string) {
}
function register(router: Router) {
eu.route(router, 'get', '/etapi/inbox/:date', (req, res, next) => {
eu.route(router, "get", "/etapi/inbox/:date", (req, res, next) => {
const { date } = req.params;
if (!isValidDate(date)) {
@@ -28,7 +28,7 @@ function register(router: Router) {
res.json(mappers.mapNoteToPojo(note));
});
eu.route(router, 'get', '/etapi/calendar/days/:date', (req, res, next) => {
eu.route(router, "get", "/etapi/calendar/days/:date", (req, res, next) => {
const { date } = req.params;
if (!isValidDate(date)) {
@@ -39,7 +39,7 @@ function register(router: Router) {
res.json(mappers.mapNoteToPojo(note));
});
eu.route(router, 'get', '/etapi/calendar/weeks/:date', (req, res, next) => {
eu.route(router, "get", "/etapi/calendar/weeks/:date", (req, res, next) => {
const { date } = req.params;
if (!isValidDate(date)) {
@@ -50,7 +50,7 @@ function register(router: Router) {
res.json(mappers.mapNoteToPojo(note));
});
eu.route(router, 'get', '/etapi/calendar/months/:month', (req, res, next) => {
eu.route(router, "get", "/etapi/calendar/months/:month", (req, res, next) => {
const { month } = req.params;
if (!/[0-9]{4}-[0-9]{2}/.test(month)) {
@@ -61,7 +61,7 @@ function register(router: Router) {
res.json(mappers.mapNoteToPojo(note));
});
eu.route(router, 'get', '/etapi/calendar/years/:year', (req, res, next) => {
eu.route(router, "get", "/etapi/calendar/years/:year", (req, res, next) => {
const { year } = req.params;
if (!/[0-9]{4}/.test(year)) {

View File

@@ -19,7 +19,7 @@ function isString(obj: unknown) {
return;
}
if (typeof obj !== 'string') {
if (typeof obj !== "string") {
return `'${obj}' is not a string`;
}
}
@@ -45,7 +45,7 @@ function isBoolean(obj: unknown) {
return;
}
if (typeof obj !== 'boolean') {
if (typeof obj !== "boolean") {
return `'${obj}' is not a boolean`;
}
}
@@ -65,7 +65,7 @@ function isNoteId(obj: unknown) {
return;
}
if (typeof obj !== 'string') {
if (typeof obj !== "string") {
return `'${obj}' is not a valid noteId`;
}
@@ -91,7 +91,7 @@ function isAttributeType(obj: unknown) {
return;
}
if (typeof obj !== "string" || !['label', 'relation'].includes(obj)) {
if (typeof obj !== "string" || !["label", "relation"].includes(obj)) {
return `'${obj}' is not a valid attribute type, allowed types are: label, relation`;
}
}
@@ -101,7 +101,7 @@ function isValidEntityId(obj: unknown) {
return;
}
if (typeof obj !== 'string' || !/^[A-Za-z0-9_]{4,128}$/.test(obj)) {
if (typeof obj !== "string" || !/^[A-Za-z0-9_]{4,128}$/.test(obj)) {
return `'${obj}' is not a valid entityId. Only alphanumeric characters are allowed of length 4 to 32.`;
}
}