diff --git a/db/migrations/0220__migrate_images_to_attachments.js b/db/migrations/0220__migrate_images_to_attachments.js index e949626ef..a9b2bfdbf 100644 --- a/db/migrations/0220__migrate_images_to_attachments.js +++ b/db/migrations/0220__migrate_images_to_attachments.js @@ -1,6 +1,6 @@ module.exports = () => { const beccaLoader = require('../../src/becca/becca_loader.js'); - const becca = require('../../src/becca/becca.js'); + const becca = require('../../src/becca/becca'); const cls = require('../../src/services/cls'); const log = require('../../src/services/log'); const sql = require('../../src/services/sql'); @@ -13,7 +13,7 @@ module.exports = () => { for (const note of Object.values(becca.notes)) { try { - const attachment = note.convertToParentAttachment({autoConversion: true}); + const attachment = note.convertToParentAttachment({ autoConversion: true }); if (attachment) { log.info(`Auto-converted note '${note.noteId}' into attachment '${attachment.attachmentId}'.`); diff --git a/dump-db/inc/dump.js b/dump-db/inc/dump.js index 7e3c1e1b3..35191ded6 100644 --- a/dump-db/inc/dump.js +++ b/dump-db/inc/dump.js @@ -1,6 +1,6 @@ const fs = require("fs"); const sanitize = require("sanitize-filename"); -const sql = require('./sql'); +const sql = require('./sql.js'); const decryptService = require('./decrypt.js'); const dataKeyService = require('./data_key.js'); const extensionService = require('./extension.js'); @@ -74,7 +74,7 @@ function dumpDocument(documentPath, targetPath, options) { return; } - let {content} = sql.getRow("SELECT content FROM blobs WHERE blobId = ?", [noteRow.blobId]); + let { content } = sql.getRow("SELECT content FROM blobs WHERE blobId = ?", [noteRow.blobId]); if (content !== null && noteRow.isProtected && dataKey) { content = decryptService.decrypt(dataKey, content); @@ -108,7 +108,7 @@ function dumpDocument(documentPath, targetPath, options) { } try { - fs.mkdirSync(childTargetPath, {recursive: true}); + fs.mkdirSync(childTargetPath, { recursive: true }); } catch (e) { console.error(`DUMPERROR: Creating directory ${childTargetPath} failed with error '${e.message}'`); @@ -157,7 +157,7 @@ function validatePaths(documentPath, targetPath) { } if (!fs.existsSync(targetPath)) { - const ret = fs.mkdirSync(targetPath, {recursive: true}); + const ret = fs.mkdirSync(targetPath, { recursive: true }); if (!ret) { console.error(`Target path '${targetPath}' could not be created. Run with --help to see usage.`); diff --git a/package-lock.json b/package-lock.json index d7484da34..283832065 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,18 @@ { "name": "trilium", - "version": "0.63.3", + "version": "0.63.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "trilium", - "version": "0.63.3", + "version": "0.63.5", "hasInstallScript": true, "license": "AGPL-3.0-only", "dependencies": { "@braintree/sanitize-url": "6.0.4", "@electron/remote": "2.1.2", "@excalidraw/excalidraw": "0.17.3", - "@types/cls-hooked": "^4.3.8", "archiver": "7.0.0", "async-mutex": "0.4.1", "axios": "1.6.7", @@ -90,6 +89,7 @@ }, "devDependencies": { "@types/better-sqlite3": "^7.6.9", + "@types/cls-hooked": "^4.3.8", "@types/escape-html": "^1.0.4", "@types/express": "^4.17.21", "@types/ini": "^4.1.0", @@ -1201,6 +1201,7 @@ "version": "4.3.8", "resolved": "https://registry.npmjs.org/@types/cls-hooked/-/cls-hooked-4.3.8.tgz", "integrity": "sha512-tf/7H883gFA6MPlWI15EQtfNZ+oPL0gLKkOlx9UHFrun1fC/FkuyNBpTKq1B5E3T4fbvjId6WifHUdSGsMMuPg==", + "dev": true, "dependencies": { "@types/node": "*" } @@ -13991,6 +13992,7 @@ "version": "4.3.8", "resolved": "https://registry.npmjs.org/@types/cls-hooked/-/cls-hooked-4.3.8.tgz", "integrity": "sha512-tf/7H883gFA6MPlWI15EQtfNZ+oPL0gLKkOlx9UHFrun1fC/FkuyNBpTKq1B5E3T4fbvjId6WifHUdSGsMMuPg==", + "dev": true, "requires": { "@types/node": "*" } diff --git a/package.json b/package.json index 438c001ea..5466a2e90 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "@braintree/sanitize-url": "6.0.4", "@electron/remote": "2.1.2", "@excalidraw/excalidraw": "0.17.3", - "@types/cls-hooked": "^4.3.8", "archiver": "7.0.0", "async-mutex": "0.4.1", "axios": "1.6.7", @@ -111,6 +110,7 @@ }, "devDependencies": { "@types/better-sqlite3": "^7.6.9", + "@types/cls-hooked": "^4.3.8", "@types/escape-html": "^1.0.4", "@types/express": "^4.17.21", "@types/ini": "^4.1.0", diff --git a/src/becca/becca-interface.ts b/src/becca/becca-interface.ts index 4c8218797..10495fc7a 100644 --- a/src/becca/becca-interface.ts +++ b/src/becca/becca-interface.ts @@ -11,6 +11,7 @@ import BAttachment = require('./entities/battachment'); import { AttachmentRow, RevisionRow } from './entities/rows'; import BBlob = require('./entities/bblob'); import BRecentNote = require('./entities/brecent_note'); +import AbstractBeccaEntity = require('./entities/abstract_becca_entity'); interface AttachmentOpts { includeContentLength?: boolean; @@ -95,7 +96,7 @@ class Becca { return this.notes[noteId]; } - getNoteOrThrow(noteId: string): BNote | null { + getNoteOrThrow(noteId: string): BNote { const note = this.notes[noteId]; if (!note) { throw new NotFoundError(`Note '${noteId}' doesn't exist.`); @@ -190,7 +191,11 @@ class Becca { .map(row => new BAttachment(row)); } - getBlob(entity: { blobId: string }): BBlob | null { + getBlob(entity: { blobId?: string }): BBlob | null { + if (!entity.blobId) { + return null; + } + const row = sql.getRow("SELECT *, LENGTH(content) AS contentLength FROM blobs WHERE blobId = ?", [entity.blobId]); const BBlob = require('./entities/bblob'); // avoiding circular dependency problems @@ -209,8 +214,7 @@ class Becca { return this.etapiTokens[etapiTokenId]; } - /** @returns {AbstractBeccaEntity|null} */ - getEntity(entityName: string, entityId: string) { + getEntity>(entityName: string, entityId: string): AbstractBeccaEntity | null { if (!entityName || !entityId) { return null; } diff --git a/src/becca/becca_loader.js b/src/becca/becca_loader.js index f0f0ccccd..a3004d9b7 100644 --- a/src/becca/becca_loader.js +++ b/src/becca/becca_loader.js @@ -18,7 +18,7 @@ const beccaLoaded = new Promise((res, rej) => { cls.init(() => { load(); - require('../services/options_init').initStartupOptions(); + require('../services/options_init.js').initStartupOptions(); res(); }); @@ -74,7 +74,7 @@ function reload(reason) { require('../services/ws').reloadFrontend(reason || "becca reloaded"); } -eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED], ({entityName, entityRow}) => { +eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED], ({ entityName, entityRow }) => { if (!becca.loaded) { return; } @@ -97,7 +97,7 @@ eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED], ({entity postProcessEntityUpdate(entityName, entityRow); }); -eventService.subscribeBeccaLoader(eventService.ENTITY_CHANGED, ({entityName, entity}) => { +eventService.subscribeBeccaLoader(eventService.ENTITY_CHANGED, ({ entityName, entity }) => { if (!becca.loaded) { return; } @@ -124,7 +124,7 @@ function postProcessEntityUpdate(entityName, entityRow) { } } -eventService.subscribeBeccaLoader([eventService.ENTITY_DELETED, eventService.ENTITY_DELETE_SYNCED], ({entityName, entityId}) => { +eventService.subscribeBeccaLoader([eventService.ENTITY_DELETED, eventService.ENTITY_DELETE_SYNCED], ({ entityName, entityId }) => { if (!becca.loaded) { return; } diff --git a/src/becca/entities/abstract_becca_entity.ts b/src/becca/entities/abstract_becca_entity.ts index 74f1163ae..1c775b51e 100644 --- a/src/becca/entities/abstract_becca_entity.ts +++ b/src/becca/entities/abstract_becca_entity.ts @@ -18,6 +18,10 @@ interface ContentOpts { forceFrontendReload?: boolean; } +/** + * This interface contains the data that is shared across all the objects of a given derived class of {@link AbstractBeccaEntity}. + * For example, all BAttributes will share their content, but all BBranches will have another set of this data. + */ interface ConstructorData> { primaryKeyName: string; entityName: string; @@ -26,6 +30,8 @@ interface ConstructorData> { /** * Base class for all backend entities. + * + * @type T the same entity type needed for self-reference in {@link ConstructorData}. */ abstract class AbstractBeccaEntity> { @@ -33,10 +39,10 @@ abstract class AbstractBeccaEntity> { protected utcDateModified?: string; protected dateCreated?: string; protected dateModified?: string; - protected isProtected?: boolean; - protected isSynced?: boolean; - protected blobId?: string; + isProtected?: boolean; + isSynced?: boolean; + blobId?: string; protected beforeSaving() { const constructorData = (this.constructor as unknown as ConstructorData); @@ -45,7 +51,7 @@ abstract class AbstractBeccaEntity> { } } - protected getUtcDateChanged() { + getUtcDateChanged() { return this.utcDateModified || this.utcDateCreated; } @@ -69,7 +75,7 @@ abstract class AbstractBeccaEntity> { }); } - protected generateHash(isDeleted: boolean): string { + generateHash(isDeleted?: boolean): string { const constructorData = (this.constructor as unknown as ConstructorData); let contentToHash = ""; diff --git a/src/becca/entities/battachment.ts b/src/becca/entities/battachment.ts index 44935ee04..206c03286 100644 --- a/src/becca/entities/battachment.ts +++ b/src/becca/entities/battachment.ts @@ -131,7 +131,7 @@ class BAttachment extends AbstractBeccaEntity { return this._getContent(); } - setContent(content: any, opts: ContentOpts) { + setContent(content: string | Buffer, opts: ContentOpts) { this._setContent(content, opts); } diff --git a/src/becca/entities/brevision.ts b/src/becca/entities/brevision.ts index b946bd54e..ba7cc00ba 100644 --- a/src/becca/entities/brevision.ts +++ b/src/becca/entities/brevision.ts @@ -115,7 +115,7 @@ class BRevision extends AbstractBeccaEntity { } } - setContent(content: any, opts: ContentOpts = {}) { + setContent(content: string | Buffer, opts: ContentOpts = {}) { this._setContent(content, opts); } diff --git a/src/services/blob.ts b/src/services/blob.ts index cfdd939c6..fac1adfad 100644 --- a/src/services/blob.ts +++ b/src/services/blob.ts @@ -20,7 +20,7 @@ function getBlobPojo(entityName: string, entityId: string) { if (!entity.hasStringContent()) { pojo.content = null; } else { - pojo.content = processContent(pojo.content, entity.isProtected, true); + pojo.content = processContent(pojo.content, !!entity.isProtected, true); } return pojo; diff --git a/tsconfig.json b/tsconfig.json index 50d8ce89c..0ce95ff39 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,10 +3,10 @@ "moduleResolution": "Node", "declaration": false, "sourceMap": true, - "outDir": "./build", + "outDir": "./dist", "strict": true, "noImplicitAny": true, - "lib": ["ES2021"] + "lib": ["ES2022"] }, "include": [ "./src/**/*.js",