mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
Merge pull request #13 from TriliumNext/feature/typescript_backend
Convert backend to TypeScript (0% -> 19%)
This commit is contained in:
commit
adc384a971
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,4 +1,5 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"files.eol": "\n"
|
||||
"files.eol": "\n",
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
||||
|
7
_check_ts_progress.sh
Executable file
7
_check_ts_progress.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cloc HEAD \
|
||||
--git --md \
|
||||
--include-lang=javascript,typescript \
|
||||
--found=filelist.txt \
|
||||
--exclude-dir=public,libraries
|
@ -1,6 +1,6 @@
|
||||
module.exports = () => {
|
||||
const sql = require('../../src/services/sql.js');
|
||||
const utils = require('../../src/services/utils.js');
|
||||
const sql = require('../../src/services/sql');
|
||||
const utils = require('../../src/services/utils');
|
||||
|
||||
const existingBlobIds = new Set();
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
module.exports = () => {
|
||||
const beccaLoader = require('../../src/becca/becca_loader.js');
|
||||
const becca = require('../../src/becca/becca.js');
|
||||
const cls = require('../../src/services/cls.js');
|
||||
const log = require('../../src/services/log.js');
|
||||
const sql = require('../../src/services/sql.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');
|
||||
|
||||
cls.init(() => {
|
||||
// emergency disabling of image compression since it appears to make problems in migration to 0.61
|
||||
@ -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}'.`);
|
||||
|
@ -1,7 +1,7 @@
|
||||
const http = require("http");
|
||||
const ini = require("ini");
|
||||
const fs = require("fs");
|
||||
const dataDir = require('./src/services/data_dir.js');
|
||||
const dataDir = require('./src/services/data_dir');
|
||||
const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, 'utf-8'));
|
||||
|
||||
if (config.Network.https) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
const crypto = require("crypto");
|
||||
const sql = require('./sql.js');
|
||||
const sql = require('./sql');
|
||||
const decryptService = require('./decrypt.js');
|
||||
|
||||
function getDataKey(password) {
|
||||
|
@ -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.`);
|
||||
|
@ -2,12 +2,11 @@
|
||||
"restartable": "rs",
|
||||
"ignore": [".git", "node_modules/**/node_modules", "src/public/"],
|
||||
"verbose": false,
|
||||
"execMap": {
|
||||
"js": "node --harmony"
|
||||
},
|
||||
"exec": "ts-node",
|
||||
"watch": ["src/"],
|
||||
"signal": "SIGTERM",
|
||||
"env": {
|
||||
"NODE_ENV": "development"
|
||||
},
|
||||
"ext": "js,json"
|
||||
"ext": "ts,js,json"
|
||||
}
|
||||
|
589
package-lock.json
generated
589
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"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": {
|
||||
@ -88,6 +88,14 @@
|
||||
"trilium": "src/www.js"
|
||||
},
|
||||
"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",
|
||||
"@types/mime-types": "^2.1.4",
|
||||
"@types/node": "^20.11.19",
|
||||
"@types/ws": "^8.5.10",
|
||||
"cross-env": "7.0.3",
|
||||
"electron": "25.9.8",
|
||||
"electron-builder": "24.13.3",
|
||||
@ -99,6 +107,9 @@
|
||||
"lorem-ipsum": "2.0.8",
|
||||
"nodemon": "3.1.0",
|
||||
"rcedit": "4.0.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"webpack": "5.90.3",
|
||||
"webpack-cli": "5.1.4"
|
||||
},
|
||||
@ -139,6 +150,28 @@
|
||||
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz",
|
||||
"integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A=="
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@develar/schema-utils": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz",
|
||||
@ -1105,11 +1138,54 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
|
||||
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tweenjs/tween.js": {
|
||||
"version": "21.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-21.0.0.tgz",
|
||||
"integrity": "sha512-qVfOiFh0U8ZSkLgA6tf7kj2MciqRbSCWaJZRwftVO7UbtVDNsZAXpWXqvCDtIefvjC83UJB+vHTDOGm5ibXjEA=="
|
||||
},
|
||||
"node_modules/@types/better-sqlite3": {
|
||||
"version": "7.6.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.9.tgz",
|
||||
"integrity": "sha512-FvktcujPDj9XKMJQWFcl2vVl7OdRIqsSRX9b0acWwTmwLK9CF2eqo/FRcmMLNpugKoX/avA6pb7TorDLmpgTnQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/body-parser": {
|
||||
"version": "1.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cacheable-request": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz",
|
||||
@ -1121,6 +1197,24 @@
|
||||
"@types/responselike": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cls-hooked": {
|
||||
"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": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/connect": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-scale": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
|
||||
@ -1147,6 +1241,12 @@
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/escape-html": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-1.0.4.tgz",
|
||||
"integrity": "sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/eslint": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz",
|
||||
@ -1173,6 +1273,30 @@
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "^4.17.33",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express-serve-static-core": {
|
||||
"version": "4.17.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz",
|
||||
"integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/range-parser": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/fs-extra": {
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
||||
@ -1197,6 +1321,18 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
|
||||
"integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ=="
|
||||
},
|
||||
"node_modules/@types/http-errors": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
|
||||
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/ini": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ini/-/ini-4.1.0.tgz",
|
||||
"integrity": "sha512-mTehMtc+xtnWBBvqizcqYCktKDBH2WChvx1GU3Sfe4PysFDXiNe+1YwtpVX1MDtCa4NQrSPw2+3HmvXHY3gt1w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
|
||||
@ -1241,6 +1377,18 @@
|
||||
"integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mime-types": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz",
|
||||
"integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||
@ -1253,9 +1401,12 @@
|
||||
"integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g=="
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.16.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.18.tgz",
|
||||
"integrity": "sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw=="
|
||||
"version": "20.11.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
|
||||
"integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/plist": {
|
||||
"version": "3.0.5",
|
||||
@ -1268,6 +1419,18 @@
|
||||
"xmlbuilder": ">=11.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz",
|
||||
"integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/range-parser": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/responselike": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
|
||||
@ -1276,6 +1439,27 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/send": {
|
||||
"version": "0.17.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
|
||||
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/serve-static": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
|
||||
"integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/http-errors": "*",
|
||||
"@types/mime": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/unist": {
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
|
||||
@ -1288,6 +1472,15 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
|
||||
"integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/yauzl": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz",
|
||||
@ -1568,6 +1761,15 @@
|
||||
"acorn": "^8"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
|
||||
"integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
@ -2028,6 +2230,12 @@
|
||||
"streamx": "^2.15.0"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
@ -3626,6 +3834,12 @@
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||
@ -5449,6 +5663,14 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron/node_modules/@types/node": {
|
||||
"version": "18.19.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.17.tgz",
|
||||
"integrity": "sha512-SzyGKgwPzuWp2SHhlpXKzCX0pIOfcI4V2eF37nNBJOhwlegQ83omtVQ1XxZpDE06V/d6AQvfQdPfnw0tRC//Ng==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/elkjs": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.2.tgz",
|
||||
@ -8140,6 +8362,12 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/make-fetch-happen": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.0.tgz",
|
||||
@ -11925,10 +12153,62 @@
|
||||
"node": ">=6.10"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-node": "dist/bin.js",
|
||||
"ts-node-cwd": "dist/bin-cwd.js",
|
||||
"ts-node-esm": "dist/bin-esm.js",
|
||||
"ts-node-script": "dist/bin-script.js",
|
||||
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||
"ts-script": "dist/bin-script-deprecated.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": ">=1.2.50",
|
||||
"@swc/wasm": ">=1.2.50",
|
||||
"@types/node": "*",
|
||||
"typescript": ">=2.7"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/wasm": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node/node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
|
||||
"integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/tsscmp": {
|
||||
"version": "1.0.6",
|
||||
@ -12041,6 +12321,11 @@
|
||||
"integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/unescape": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unescape/-/unescape-1.0.1.tgz",
|
||||
@ -12217,6 +12502,12 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
@ -12782,6 +13073,15 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/zip-stream": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.0.tgz",
|
||||
@ -12888,6 +13188,27 @@
|
||||
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz",
|
||||
"integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A=="
|
||||
},
|
||||
"@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@develar/schema-utils": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz",
|
||||
@ -13608,11 +13929,54 @@
|
||||
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node10": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
|
||||
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true
|
||||
},
|
||||
"@tweenjs/tween.js": {
|
||||
"version": "21.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-21.0.0.tgz",
|
||||
"integrity": "sha512-qVfOiFh0U8ZSkLgA6tf7kj2MciqRbSCWaJZRwftVO7UbtVDNsZAXpWXqvCDtIefvjC83UJB+vHTDOGm5ibXjEA=="
|
||||
},
|
||||
"@types/better-sqlite3": {
|
||||
"version": "7.6.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.9.tgz",
|
||||
"integrity": "sha512-FvktcujPDj9XKMJQWFcl2vVl7OdRIqsSRX9b0acWwTmwLK9CF2eqo/FRcmMLNpugKoX/avA6pb7TorDLmpgTnQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/body-parser": {
|
||||
"version": "1.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/cacheable-request": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz",
|
||||
@ -13624,6 +13988,24 @@
|
||||
"@types/responselike": "*"
|
||||
}
|
||||
},
|
||||
"@types/cls-hooked": {
|
||||
"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": "*"
|
||||
}
|
||||
},
|
||||
"@types/connect": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/d3-scale": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
|
||||
@ -13650,6 +14032,12 @@
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"@types/escape-html": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-1.0.4.tgz",
|
||||
"integrity": "sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/eslint": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz",
|
||||
@ -13676,6 +14064,30 @@
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "^4.17.33",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"@types/express-serve-static-core": {
|
||||
"version": "4.17.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz",
|
||||
"integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/range-parser": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"@types/fs-extra": {
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
||||
@ -13700,6 +14112,18 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
|
||||
"integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ=="
|
||||
},
|
||||
"@types/http-errors": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
|
||||
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/ini": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ini/-/ini-4.1.0.tgz",
|
||||
"integrity": "sha512-mTehMtc+xtnWBBvqizcqYCktKDBH2WChvx1GU3Sfe4PysFDXiNe+1YwtpVX1MDtCa4NQrSPw2+3HmvXHY3gt1w==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
|
||||
@ -13744,6 +14168,18 @@
|
||||
"integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mime-types": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz",
|
||||
"integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||
@ -13756,9 +14192,12 @@
|
||||
"integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "18.16.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.18.tgz",
|
||||
"integrity": "sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw=="
|
||||
"version": "20.11.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
|
||||
"integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==",
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"@types/plist": {
|
||||
"version": "3.0.5",
|
||||
@ -13771,6 +14210,18 @@
|
||||
"xmlbuilder": ">=11.0.1"
|
||||
}
|
||||
},
|
||||
"@types/qs": {
|
||||
"version": "6.9.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz",
|
||||
"integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/range-parser": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/responselike": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
|
||||
@ -13779,6 +14230,27 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/send": {
|
||||
"version": "0.17.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
|
||||
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/serve-static": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
|
||||
"integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/http-errors": "*",
|
||||
"@types/mime": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/unist": {
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
|
||||
@ -13791,6 +14263,15 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@types/ws": {
|
||||
"version": "8.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
|
||||
"integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/yauzl": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz",
|
||||
@ -14031,6 +14512,12 @@
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"acorn-walk": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
|
||||
"integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
|
||||
"dev": true
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
@ -14381,6 +14868,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true
|
||||
},
|
||||
"argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
@ -15586,6 +16079,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||
@ -16410,6 +16909,16 @@
|
||||
"@electron/get": "^2.0.0",
|
||||
"@types/node": "^18.11.18",
|
||||
"extract-zip": "^2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "18.19.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.17.tgz",
|
||||
"integrity": "sha512-SzyGKgwPzuWp2SHhlpXKzCX0pIOfcI4V2eF37nNBJOhwlegQ83omtVQ1XxZpDE06V/d6AQvfQdPfnw0tRC//Ng==",
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"electron-builder": {
|
||||
@ -19033,6 +19542,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"make-fetch-happen": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.0.tgz",
|
||||
@ -21840,10 +22355,39 @@
|
||||
"resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
|
||||
"integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
|
||||
"integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"tsscmp": {
|
||||
"version": "1.0.6",
|
||||
@ -21931,6 +22475,11 @@
|
||||
"integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==",
|
||||
"dev": true
|
||||
},
|
||||
"undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"unescape": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unescape/-/unescape-1.0.1.tgz",
|
||||
@ -22057,6 +22606,12 @@
|
||||
"sade": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
@ -22463,6 +23018,12 @@
|
||||
"pend": "~1.2.0"
|
||||
}
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"zip-stream": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.0.tgz",
|
||||
|
13
package.json
13
package.json
@ -109,6 +109,14 @@
|
||||
"yauzl": "3.1.2"
|
||||
},
|
||||
"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",
|
||||
"@types/mime-types": "^2.1.4",
|
||||
"@types/node": "^20.11.19",
|
||||
"@types/ws": "^8.5.10",
|
||||
"cross-env": "7.0.3",
|
||||
"electron": "25.9.8",
|
||||
"electron-builder": "24.13.3",
|
||||
@ -120,10 +128,13 @@
|
||||
"lorem-ipsum": "2.0.8",
|
||||
"nodemon": "3.1.0",
|
||||
"rcedit": "4.0.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"webpack": "5.90.3",
|
||||
"webpack-cli": "5.1.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"electron-installer-debian": "3.2.0"
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ const searchService = require('../../src/services/search/services/search.js');
|
||||
const BNote = require('../../src/becca/entities/bnote.js');
|
||||
const BBranch = require('../../src/becca/entities/bbranch.js');
|
||||
const SearchContext = require('../../src/services/search/search_context.js');
|
||||
const dateUtils = require('../../src/services/date_utils.js');
|
||||
const dateUtils = require('../../src/services/date_utils');
|
||||
const becca = require('../../src/becca/becca.js');
|
||||
const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking.js');
|
||||
|
||||
|
@ -5,7 +5,7 @@ const cookieParser = require('cookie-parser');
|
||||
const helmet = require('helmet');
|
||||
const compression = require('compression');
|
||||
const sessionParser = require('./routes/session_parser.js');
|
||||
const utils = require('./services/utils.js');
|
||||
const utils = require('./services/utils');
|
||||
|
||||
require('./services/handlers.js');
|
||||
require('./becca/becca_loader.js');
|
||||
|
@ -1,32 +1,52 @@
|
||||
"use strict";
|
||||
import sql = require('../services/sql');
|
||||
import NoteSet = require('../services/search/note_set');
|
||||
import NotFoundError = require('../errors/not_found_error');
|
||||
import BOption = require('./entities/boption');
|
||||
import BNote = require('./entities/bnote');
|
||||
import BEtapiToken = require('./entities/betapi_token');
|
||||
import BAttribute = require('./entities/battribute');
|
||||
import BBranch = require('./entities/bbranch');
|
||||
import BRevision = require('./entities/brevision');
|
||||
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');
|
||||
|
||||
const sql = require('../services/sql.js');
|
||||
const NoteSet = require('../services/search/note_set.js');
|
||||
const NotFoundError = require('../errors/not_found_error.js');
|
||||
interface AttachmentOpts {
|
||||
includeContentLength?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Becca is a backend cache of all notes, branches, and attributes.
|
||||
* There's a similar frontend cache Froca, and share cache Shaca.
|
||||
*/
|
||||
class Becca {
|
||||
loaded!: boolean;
|
||||
|
||||
notes!: Record<string, BNote>;
|
||||
branches!: Record<string, BBranch>;
|
||||
childParentToBranch!: Record<string, BBranch>;
|
||||
attributes!: Record<string, BAttribute>;
|
||||
/** Points from attribute type-name to list of attributes */
|
||||
attributeIndex!: Record<string, BAttribute[]>;
|
||||
options!: Record<string, BOption>;
|
||||
etapiTokens!: Record<string, BEtapiToken>;
|
||||
|
||||
allNoteSetCache: NoteSet | null;
|
||||
|
||||
constructor() {
|
||||
this.reset();
|
||||
this.allNoteSetCache = null;
|
||||
}
|
||||
|
||||
reset() {
|
||||
/** @type {Object.<String, BNote>} */
|
||||
this.notes = {};
|
||||
/** @type {Object.<String, BBranch>} */
|
||||
this.branches = {};
|
||||
/** @type {Object.<String, BBranch>} */
|
||||
this.childParentToBranch = {};
|
||||
/** @type {Object.<String, BAttribute>} */
|
||||
this.attributes = {};
|
||||
/** @type {Object.<String, BAttribute[]>} Points from attribute type-name to list of attributes */
|
||||
this.attributes = {};
|
||||
this.attributeIndex = {};
|
||||
/** @type {Object.<String, BOption>} */
|
||||
this.options = {};
|
||||
/** @type {Object.<String, BEtapiToken>} */
|
||||
this.etapiTokens = {};
|
||||
|
||||
this.dirtyNoteSetCache();
|
||||
@ -38,8 +58,7 @@ class Becca {
|
||||
return this.getNote('root');
|
||||
}
|
||||
|
||||
/** @returns {BAttribute[]} */
|
||||
findAttributes(type, name) {
|
||||
findAttributes(type: string, name: string): BAttribute[] {
|
||||
name = name.trim().toLowerCase();
|
||||
|
||||
if (name.startsWith('#') || name.startsWith('~')) {
|
||||
@ -49,9 +68,8 @@ class Becca {
|
||||
return this.attributeIndex[`${type}-${name}`] || [];
|
||||
}
|
||||
|
||||
/** @returns {BAttribute[]} */
|
||||
findAttributesWithPrefix(type, name) {
|
||||
const resArr = [];
|
||||
findAttributesWithPrefix(type: string, name: string): BAttribute[] {
|
||||
const resArr: BAttribute[][] = [];
|
||||
const key = `${type}-${name}`;
|
||||
|
||||
for (const idx in this.attributeIndex) {
|
||||
@ -69,18 +87,16 @@ class Becca {
|
||||
}
|
||||
}
|
||||
|
||||
addNote(noteId, note) {
|
||||
addNote(noteId: string, note: BNote) {
|
||||
this.notes[noteId] = note;
|
||||
this.dirtyNoteSetCache();
|
||||
}
|
||||
|
||||
/** @returns {BNote|null} */
|
||||
getNote(noteId) {
|
||||
getNote(noteId: string): BNote | null {
|
||||
return this.notes[noteId];
|
||||
}
|
||||
|
||||
/** @returns {BNote|null} */
|
||||
getNoteOrThrow(noteId) {
|
||||
getNoteOrThrow(noteId: string): BNote {
|
||||
const note = this.notes[noteId];
|
||||
if (!note) {
|
||||
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
|
||||
@ -89,9 +105,8 @@ class Becca {
|
||||
return note;
|
||||
}
|
||||
|
||||
/** @returns {BNote[]} */
|
||||
getNotes(noteIds, ignoreMissing = false) {
|
||||
const filteredNotes = [];
|
||||
getNotes(noteIds: string[], ignoreMissing: boolean = false): BNote[] {
|
||||
const filteredNotes: BNote[] = [];
|
||||
|
||||
for (const noteId of noteIds) {
|
||||
const note = this.notes[noteId];
|
||||
@ -110,13 +125,11 @@ class Becca {
|
||||
return filteredNotes;
|
||||
}
|
||||
|
||||
/** @returns {BBranch|null} */
|
||||
getBranch(branchId) {
|
||||
getBranch(branchId: string): BBranch | null {
|
||||
return this.branches[branchId];
|
||||
}
|
||||
|
||||
/** @returns {BBranch|null} */
|
||||
getBranchOrThrow(branchId) {
|
||||
getBranchOrThrow(branchId: string): BBranch | null {
|
||||
const branch = this.getBranch(branchId);
|
||||
if (!branch) {
|
||||
throw new NotFoundError(`Branch '${branchId}' was not found in becca.`);
|
||||
@ -124,13 +137,11 @@ class Becca {
|
||||
return branch;
|
||||
}
|
||||
|
||||
/** @returns {BAttribute|null} */
|
||||
getAttribute(attributeId) {
|
||||
getAttribute(attributeId: string): BAttribute | null {
|
||||
return this.attributes[attributeId];
|
||||
}
|
||||
|
||||
/** @returns {BAttribute} */
|
||||
getAttributeOrThrow(attributeId) {
|
||||
getAttributeOrThrow(attributeId: string): BAttribute {
|
||||
const attribute = this.getAttribute(attributeId);
|
||||
if (!attribute) {
|
||||
throw new NotFoundError(`Attribute '${attributeId}' does not exist.`);
|
||||
@ -139,21 +150,18 @@ class Becca {
|
||||
return attribute;
|
||||
}
|
||||
|
||||
/** @returns {BBranch|null} */
|
||||
getBranchFromChildAndParent(childNoteId, parentNoteId) {
|
||||
getBranchFromChildAndParent(childNoteId: string, parentNoteId: string): BBranch | null {
|
||||
return this.childParentToBranch[`${childNoteId}-${parentNoteId}`];
|
||||
}
|
||||
|
||||
/** @returns {BRevision|null} */
|
||||
getRevision(revisionId) {
|
||||
getRevision(revisionId: string): BRevision | null {
|
||||
const row = sql.getRow("SELECT * FROM revisions WHERE revisionId = ?", [revisionId]);
|
||||
|
||||
const BRevision = require('./entities/brevision.js'); // avoiding circular dependency problems
|
||||
const BRevision = require('./entities/brevision'); // avoiding circular dependency problems
|
||||
return row ? new BRevision(row) : null;
|
||||
}
|
||||
|
||||
/** @returns {BAttachment|null} */
|
||||
getAttachment(attachmentId, opts = {}) {
|
||||
getAttachment(attachmentId: string, opts: AttachmentOpts = {}): BAttachment | null {
|
||||
opts.includeContentLength = !!opts.includeContentLength;
|
||||
|
||||
const query = opts.includeContentLength
|
||||
@ -163,14 +171,13 @@ class Becca {
|
||||
WHERE attachmentId = ? AND isDeleted = 0`
|
||||
: `SELECT * FROM attachments WHERE attachmentId = ? AND isDeleted = 0`;
|
||||
|
||||
const BAttachment = require('./entities/battachment.js'); // avoiding circular dependency problems
|
||||
const BAttachment = require('./entities/battachment'); // avoiding circular dependency problems
|
||||
|
||||
return sql.getRows(query, [attachmentId])
|
||||
.map(row => new BAttachment(row))[0];
|
||||
}
|
||||
|
||||
/** @returns {BAttachment} */
|
||||
getAttachmentOrThrow(attachmentId, opts = {}) {
|
||||
getAttachmentOrThrow(attachmentId: string, opts: AttachmentOpts = {}): BAttachment {
|
||||
const attachment = this.getAttachment(attachmentId, opts);
|
||||
if (!attachment) {
|
||||
throw new NotFoundError(`Attachment '${attachmentId}' has not been found.`);
|
||||
@ -178,38 +185,36 @@ class Becca {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
/** @returns {BAttachment[]} */
|
||||
getAttachments(attachmentIds) {
|
||||
const BAttachment = require('./entities/battachment.js'); // avoiding circular dependency problems
|
||||
return sql.getManyRows("SELECT * FROM attachments WHERE attachmentId IN (???) AND isDeleted = 0", attachmentIds)
|
||||
getAttachments(attachmentIds: string[]): BAttachment[] {
|
||||
const BAttachment = require('./entities/battachment'); // avoiding circular dependency problems
|
||||
return sql.getManyRows<AttachmentRow>("SELECT * FROM attachments WHERE attachmentId IN (???) AND isDeleted = 0", attachmentIds)
|
||||
.map(row => new BAttachment(row));
|
||||
}
|
||||
|
||||
/** @returns {BBlob|null} */
|
||||
getBlob(entity) {
|
||||
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.js'); // avoiding circular dependency problems
|
||||
const BBlob = require('./entities/bblob'); // avoiding circular dependency problems
|
||||
return row ? new BBlob(row) : null;
|
||||
}
|
||||
|
||||
/** @returns {BOption|null} */
|
||||
getOption(name) {
|
||||
getOption(name: string): BOption | null {
|
||||
return this.options[name];
|
||||
}
|
||||
|
||||
/** @returns {BEtapiToken[]} */
|
||||
getEtapiTokens() {
|
||||
getEtapiTokens(): BEtapiToken[] {
|
||||
return Object.values(this.etapiTokens);
|
||||
}
|
||||
|
||||
/** @returns {BEtapiToken|null} */
|
||||
getEtapiToken(etapiTokenId) {
|
||||
getEtapiToken(etapiTokenId: string): BEtapiToken | null {
|
||||
return this.etapiTokens[etapiTokenId];
|
||||
}
|
||||
|
||||
/** @returns {AbstractBeccaEntity|null} */
|
||||
getEntity(entityName, entityId) {
|
||||
getEntity<T extends AbstractBeccaEntity<T>>(entityName: string, entityId: string): AbstractBeccaEntity<T> | null {
|
||||
if (!entityName || !entityId) {
|
||||
return null;
|
||||
}
|
||||
@ -231,22 +236,20 @@ class Becca {
|
||||
throw new Error(`Unknown entity name '${camelCaseEntityName}' (original argument '${entityName}')`);
|
||||
}
|
||||
|
||||
return this[camelCaseEntityName][entityId];
|
||||
return (this as any)[camelCaseEntityName][entityId];
|
||||
}
|
||||
|
||||
/** @returns {BRecentNote[]} */
|
||||
getRecentNotesFromQuery(query, params = []) {
|
||||
getRecentNotesFromQuery(query: string, params = []): BRecentNote[] {
|
||||
const rows = sql.getRows(query, params);
|
||||
|
||||
const BRecentNote = require('./entities/brecent_note.js'); // avoiding circular dependency problems
|
||||
const BRecentNote = require('./entities/brecent_note'); // avoiding circular dependency problems
|
||||
return rows.map(row => new BRecentNote(row));
|
||||
}
|
||||
|
||||
/** @returns {BRevision[]} */
|
||||
getRevisionsFromQuery(query, params = []) {
|
||||
const rows = sql.getRows(query, params);
|
||||
getRevisionsFromQuery(query: string, params = []): BRevision[] {
|
||||
const rows = sql.getRows<RevisionRow>(query, params);
|
||||
|
||||
const BRevision = require('./entities/brevision.js'); // avoiding circular dependency problems
|
||||
const BRevision = require('./entities/brevision'); // avoiding circular dependency problems
|
||||
return rows.map(row => new BRevision(row));
|
||||
}
|
||||
|
||||
@ -260,8 +263,8 @@ class Becca {
|
||||
if (!this.allNoteSetCache) {
|
||||
const allNotes = [];
|
||||
|
||||
for (const noteId in becca.notes) {
|
||||
const note = becca.notes[noteId];
|
||||
for (const noteId in this.notes) {
|
||||
const note = this.notes[noteId];
|
||||
|
||||
// in the process of loading data sometimes we create "skeleton" note instances which are expected to be filled later
|
||||
// in case of inconsistent data this might not work and search will then crash on these
|
||||
@ -277,6 +280,4 @@ class Becca {
|
||||
}
|
||||
}
|
||||
|
||||
const becca = new Becca();
|
||||
|
||||
module.exports = becca;
|
||||
export = Becca;
|
7
src/becca/becca.ts
Normal file
7
src/becca/becca.ts
Normal file
@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import Becca = require("./becca-interface");
|
||||
|
||||
const becca = new Becca();
|
||||
|
||||
export = becca;
|
@ -1,17 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('../services/sql.js');
|
||||
const eventService = require('../services/events.js');
|
||||
const becca = require('./becca.js');
|
||||
const sqlInit = require('../services/sql_init.js');
|
||||
const log = require('../services/log.js');
|
||||
const BNote = require('./entities/bnote.js');
|
||||
const BBranch = require('./entities/bbranch.js');
|
||||
const BAttribute = require('./entities/battribute.js');
|
||||
const BOption = require('./entities/boption.js');
|
||||
const BEtapiToken = require('./entities/betapi_token.js');
|
||||
const cls = require('../services/cls.js');
|
||||
const entityConstructor = require('../becca/entity_constructor.js');
|
||||
const sql = require('../services/sql');
|
||||
const eventService = require('../services/events');
|
||||
const becca = require('./becca');
|
||||
const sqlInit = require('../services/sql_init');
|
||||
const log = require('../services/log');
|
||||
const BNote = require('./entities/bnote');
|
||||
const BBranch = require('./entities/bbranch');
|
||||
const BAttribute = require('./entities/battribute');
|
||||
const BOption = require('./entities/boption');
|
||||
const BEtapiToken = require('./entities/betapi_token');
|
||||
const cls = require('../services/cls');
|
||||
const entityConstructor = require('../becca/entity_constructor');
|
||||
|
||||
const beccaLoaded = new Promise((res, rej) => {
|
||||
sqlInit.dbReady.then(() => {
|
||||
@ -71,10 +71,10 @@ function load() {
|
||||
function reload(reason) {
|
||||
load();
|
||||
|
||||
require('../services/ws.js').reloadFrontend(reason || "becca reloaded");
|
||||
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;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
const becca = require('./becca.js');
|
||||
const cls = require('../services/cls.js');
|
||||
const log = require('../services/log.js');
|
||||
const becca = require('./becca');
|
||||
const cls = require('../services/cls');
|
||||
const log = require('../services/log');
|
||||
|
||||
function isNotePathArchived(notePath) {
|
||||
const noteId = notePath[notePath.length - 1];
|
||||
|
@ -1,66 +1,86 @@
|
||||
"use strict";
|
||||
|
||||
const utils = require('../../services/utils.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const entityChangesService = require('../../services/entity_changes.js');
|
||||
const eventService = require('../../services/events.js');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const cls = require('../../services/cls.js');
|
||||
const log = require('../../services/log.js');
|
||||
const protectedSessionService = require('../../services/protected_session.js');
|
||||
const blobService = require('../../services/blob.js');
|
||||
import utils = require('../../services/utils');
|
||||
import sql = require('../../services/sql');
|
||||
import entityChangesService = require('../../services/entity_changes');
|
||||
import eventService = require('../../services/events');
|
||||
import dateUtils = require('../../services/date_utils');
|
||||
import cls = require('../../services/cls');
|
||||
import log = require('../../services/log');
|
||||
import protectedSessionService = require('../../services/protected_session');
|
||||
import blobService = require('../../services/blob');
|
||||
import Becca = require('../becca-interface');
|
||||
|
||||
let becca = null;
|
||||
let becca: Becca | null = null;
|
||||
|
||||
interface ContentOpts {
|
||||
forceSave?: boolean;
|
||||
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<T extends AbstractBeccaEntity<T>> {
|
||||
primaryKeyName: string;
|
||||
entityName: string;
|
||||
hashedProperties: (keyof T)[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all backend entities.
|
||||
*
|
||||
* @type T the same entity type needed for self-reference in {@link ConstructorData}.
|
||||
*/
|
||||
class AbstractBeccaEntity {
|
||||
/** @protected */
|
||||
beforeSaving() {
|
||||
if (!this[this.constructor.primaryKeyName]) {
|
||||
this[this.constructor.primaryKeyName] = utils.newEntityId();
|
||||
abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> {
|
||||
|
||||
protected utcDateCreated?: string;
|
||||
protected utcDateModified?: string;
|
||||
protected dateCreated?: string;
|
||||
protected dateModified?: string;
|
||||
|
||||
isProtected?: boolean;
|
||||
isSynced?: boolean;
|
||||
blobId?: string;
|
||||
|
||||
protected beforeSaving() {
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
if (!(this as any)[constructorData.primaryKeyName]) {
|
||||
(this as any)[constructorData.primaryKeyName] = utils.newEntityId();
|
||||
}
|
||||
}
|
||||
|
||||
/** @protected */
|
||||
getUtcDateChanged() {
|
||||
return this.utcDateModified || this.utcDateCreated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @returns {Becca}
|
||||
*/
|
||||
get becca() {
|
||||
protected get becca(): Becca {
|
||||
if (!becca) {
|
||||
becca = require('../becca.js');
|
||||
becca = require('../becca');
|
||||
}
|
||||
|
||||
return becca;
|
||||
return becca as Becca;
|
||||
}
|
||||
|
||||
/** @protected */
|
||||
putEntityChange(isDeleted) {
|
||||
protected putEntityChange(isDeleted: boolean) {
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
entityChangesService.putEntityChange({
|
||||
entityName: this.constructor.entityName,
|
||||
entityId: this[this.constructor.primaryKeyName],
|
||||
entityName: constructorData.entityName,
|
||||
entityId: (this as any)[constructorData.primaryKeyName],
|
||||
hash: this.generateHash(isDeleted),
|
||||
isErased: false,
|
||||
utcDateChanged: this.getUtcDateChanged(),
|
||||
isSynced: this.constructor.entityName !== 'options' || !!this.isSynced
|
||||
isSynced: constructorData.entityName !== 'options' || !!this.isSynced
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @returns {string}
|
||||
*/
|
||||
generateHash(isDeleted) {
|
||||
generateHash(isDeleted?: boolean): string {
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
let contentToHash = "";
|
||||
|
||||
for (const propertyName of this.constructor.hashedProperties) {
|
||||
contentToHash += `|${this[propertyName]}`;
|
||||
for (const propertyName of constructorData.hashedProperties) {
|
||||
contentToHash += `|${(this as any)[propertyName]}`;
|
||||
}
|
||||
|
||||
if (isDeleted) {
|
||||
@ -70,31 +90,33 @@ class AbstractBeccaEntity {
|
||||
return utils.hash(contentToHash).substr(0, 10);
|
||||
}
|
||||
|
||||
/** @protected */
|
||||
getPojoToSave() {
|
||||
protected getPojoToSave() {
|
||||
return this.getPojo();
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @abstract
|
||||
*/
|
||||
getPojo() {
|
||||
throw new Error(`Unimplemented getPojo() for entity '${this.constructor.name}'`)
|
||||
hasStringContent(): boolean {
|
||||
// TODO: Not sure why some entities don't implement it.
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract getPojo(): {};
|
||||
|
||||
get isDeleted(): boolean {
|
||||
// TODO: Not sure why some entities don't implement it.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves entity - executes SQL, but doesn't commit the transaction on its own
|
||||
*
|
||||
* @returns {this}
|
||||
*/
|
||||
save(opts = {}) {
|
||||
const entityName = this.constructor.entityName;
|
||||
const primaryKeyName = this.constructor.primaryKeyName;
|
||||
save(): this {
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
const entityName = constructorData.entityName;
|
||||
const primaryKeyName = constructorData.primaryKeyName;
|
||||
|
||||
const isNewEntity = !this[primaryKeyName];
|
||||
const isNewEntity = !(this as any)[primaryKeyName];
|
||||
|
||||
this.beforeSaving(opts);
|
||||
this.beforeSaving();
|
||||
|
||||
const pojo = this.getPojoToSave();
|
||||
|
||||
@ -124,14 +146,14 @@ class AbstractBeccaEntity {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @protected */
|
||||
_setContent(content, opts = {}) {
|
||||
protected _setContent(content: string | Buffer, opts: ContentOpts = {}) {
|
||||
// client code asks to save entity even if blobId didn't change (something else was changed)
|
||||
opts.forceSave = !!opts.forceSave;
|
||||
opts.forceFrontendReload = !!opts.forceFrontendReload;
|
||||
|
||||
if (content === null || content === undefined) {
|
||||
throw new Error(`Cannot set null content to ${this.constructor.primaryKeyName} '${this[this.constructor.primaryKeyName]}'`);
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
throw new Error(`Cannot set null content to ${constructorData.primaryKeyName} '${(this as any)[constructorData.primaryKeyName]}'`);
|
||||
}
|
||||
|
||||
if (this.hasStringContent()) {
|
||||
@ -140,32 +162,36 @@ class AbstractBeccaEntity {
|
||||
content = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
||||
}
|
||||
|
||||
const unencryptedContentForHashCalculation = this.#getUnencryptedContentForHashCalculation(content);
|
||||
const unencryptedContentForHashCalculation = this.getUnencryptedContentForHashCalculation(content);
|
||||
|
||||
if (this.isProtected) {
|
||||
if (protectedSessionService.isProtectedSessionAvailable()) {
|
||||
content = protectedSessionService.encrypt(content);
|
||||
const encryptedContent = protectedSessionService.encrypt(content);
|
||||
if (!encryptedContent) {
|
||||
throw new Error(`Unable to encrypt the content of the entity.`);
|
||||
}
|
||||
content = encryptedContent;
|
||||
} else {
|
||||
throw new Error(`Cannot update content of blob since protected session is not available.`);
|
||||
}
|
||||
}
|
||||
|
||||
sql.transactional(() => {
|
||||
const newBlobId = this.#saveBlob(content, unencryptedContentForHashCalculation, opts);
|
||||
const newBlobId = this.saveBlob(content, unencryptedContentForHashCalculation, opts);
|
||||
const oldBlobId = this.blobId;
|
||||
|
||||
if (newBlobId !== oldBlobId || opts.forceSave) {
|
||||
this.blobId = newBlobId;
|
||||
this.save();
|
||||
|
||||
if (newBlobId !== oldBlobId) {
|
||||
this.#deleteBlobIfNotUsed(oldBlobId);
|
||||
if (oldBlobId && newBlobId !== oldBlobId) {
|
||||
this.deleteBlobIfNotUsed(oldBlobId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#deleteBlobIfNotUsed(oldBlobId) {
|
||||
private deleteBlobIfNotUsed(oldBlobId: string) {
|
||||
if (sql.getValue("SELECT 1 FROM notes WHERE blobId = ? LIMIT 1", [oldBlobId])) {
|
||||
return;
|
||||
}
|
||||
@ -184,7 +210,7 @@ class AbstractBeccaEntity {
|
||||
sql.execute("DELETE FROM entity_changes WHERE entityName = 'blobs' AND entityId = ?", [oldBlobId]);
|
||||
}
|
||||
|
||||
#getUnencryptedContentForHashCalculation(unencryptedContent) {
|
||||
private getUnencryptedContentForHashCalculation(unencryptedContent: Buffer | string) {
|
||||
if (this.isProtected) {
|
||||
// a "random" prefix makes sure that the calculated hash/blobId is different for a decrypted/encrypted content
|
||||
const encryptedPrefixSuffix = "t$[nvQg7q)&_ENCRYPTED_?M:Bf&j3jr_";
|
||||
@ -196,7 +222,7 @@ class AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
#saveBlob(content, unencryptedContentForHashCalculation, opts = {}) {
|
||||
private saveBlob(content: string | Buffer, unencryptedContentForHashCalculation: string | Buffer, opts: ContentOpts = {}) {
|
||||
/*
|
||||
* We're using the unencrypted blob for the hash calculation, because otherwise the random IV would
|
||||
* cause every content blob to be unique which would balloon the database size (esp. with revisioning).
|
||||
@ -243,41 +269,37 @@ class AbstractBeccaEntity {
|
||||
return newBlobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @returns {string|Buffer}
|
||||
*/
|
||||
_getContent() {
|
||||
const row = sql.getRow(`SELECT content FROM blobs WHERE blobId = ?`, [this.blobId]);
|
||||
protected _getContent(): string | Buffer {
|
||||
const row = sql.getRow<{ content: string | Buffer }>(`SELECT content FROM blobs WHERE blobId = ?`, [this.blobId]);
|
||||
|
||||
if (!row) {
|
||||
throw new Error(`Cannot find content for ${this.constructor.primaryKeyName} '${this[this.constructor.primaryKeyName]}', blobId '${this.blobId}'`);
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
throw new Error(`Cannot find content for ${constructorData.primaryKeyName} '${(this as any)[constructorData.primaryKeyName]}', blobId '${this.blobId}'`);
|
||||
}
|
||||
|
||||
return blobService.processContent(row.content, this.isProtected, this.hasStringContent());
|
||||
return blobService.processContent(row.content, this.isProtected || false, this.hasStringContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the entity as (soft) deleted. It will be completely erased later.
|
||||
*
|
||||
* This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
|
||||
*
|
||||
* @param [deleteId=null]
|
||||
*/
|
||||
markAsDeleted(deleteId = null) {
|
||||
const entityId = this[this.constructor.primaryKeyName];
|
||||
const entityName = this.constructor.entityName;
|
||||
markAsDeleted(deleteId: string | null = null) {
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
const entityId = (this as any)[constructorData.primaryKeyName];
|
||||
const entityName = constructorData.entityName;
|
||||
|
||||
this.utcDateModified = dateUtils.utcNowDateTime();
|
||||
|
||||
sql.execute(`UPDATE ${entityName} SET isDeleted = 1, deleteId = ?, utcDateModified = ?
|
||||
WHERE ${this.constructor.primaryKeyName} = ?`,
|
||||
WHERE ${constructorData.primaryKeyName} = ?`,
|
||||
[deleteId, this.utcDateModified, entityId]);
|
||||
|
||||
if (this.dateModified) {
|
||||
this.dateModified = dateUtils.localNowDateTime();
|
||||
|
||||
sql.execute(`UPDATE ${entityName} SET dateModified = ? WHERE ${this.constructor.primaryKeyName} = ?`,
|
||||
sql.execute(`UPDATE ${entityName} SET dateModified = ? WHERE ${constructorData.primaryKeyName} = ?`,
|
||||
[this.dateModified, entityId]);
|
||||
}
|
||||
|
||||
@ -289,13 +311,14 @@ class AbstractBeccaEntity {
|
||||
}
|
||||
|
||||
markAsDeletedSimple() {
|
||||
const entityId = this[this.constructor.primaryKeyName];
|
||||
const entityName = this.constructor.entityName;
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
const entityId = (this as any)[constructorData.primaryKeyName];
|
||||
const entityName = constructorData.entityName;
|
||||
|
||||
this.utcDateModified = dateUtils.utcNowDateTime();
|
||||
|
||||
sql.execute(`UPDATE ${entityName} SET isDeleted = 1, utcDateModified = ?
|
||||
WHERE ${this.constructor.primaryKeyName} = ?`,
|
||||
WHERE ${constructorData.primaryKeyName} = ?`,
|
||||
[this.utcDateModified, entityId]);
|
||||
|
||||
log.info(`Marking ${entityName} ${entityId} as deleted`);
|
||||
@ -306,4 +329,4 @@ class AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AbstractBeccaEntity;
|
||||
export = AbstractBeccaEntity;
|
@ -1,29 +1,57 @@
|
||||
"use strict";
|
||||
|
||||
const utils = require('../../services/utils.js');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const protectedSessionService = require('../../services/protected_session.js');
|
||||
const log = require('../../services/log.js');
|
||||
import utils = require('../../services/utils');
|
||||
import dateUtils = require('../../services/date_utils');
|
||||
import AbstractBeccaEntity = require('./abstract_becca_entity');
|
||||
import sql = require('../../services/sql');
|
||||
import protectedSessionService = require('../../services/protected_session');
|
||||
import log = require('../../services/log');
|
||||
import { AttachmentRow } from './rows';
|
||||
import BNote = require('./bnote');
|
||||
import BBranch = require('./bbranch');
|
||||
|
||||
const attachmentRoleToNoteTypeMapping = {
|
||||
'image': 'image',
|
||||
'file': 'file'
|
||||
};
|
||||
|
||||
interface ContentOpts {
|
||||
// TODO: Found in bnote.ts, to check if it's actually used and not a typo.
|
||||
forceSave?: boolean;
|
||||
|
||||
/** will also save this BAttachment entity */
|
||||
forceFullSave?: boolean;
|
||||
/** override frontend heuristics on when to reload, instruct to reload */
|
||||
forceFrontendReload?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attachment represent data related/attached to the note. Conceptually similar to attributes, but intended for
|
||||
* larger amounts of data and generally not accessible to the user.
|
||||
*
|
||||
* @extends AbstractBeccaEntity
|
||||
*/
|
||||
class BAttachment extends AbstractBeccaEntity {
|
||||
class BAttachment extends AbstractBeccaEntity<BAttachment> {
|
||||
static get entityName() { return "attachments"; }
|
||||
static get primaryKeyName() { return "attachmentId"; }
|
||||
static get hashedProperties() { return ["attachmentId", "ownerId", "role", "mime", "title", "blobId", "utcDateScheduledForErasureSince"]; }
|
||||
|
||||
constructor(row) {
|
||||
noteId?: number;
|
||||
attachmentId?: string;
|
||||
/** either noteId or revisionId to which this attachment belongs */
|
||||
ownerId: string;
|
||||
role: string;
|
||||
mime: string;
|
||||
title: string;
|
||||
type?: keyof typeof attachmentRoleToNoteTypeMapping;
|
||||
position?: number;
|
||||
blobId?: string;
|
||||
isProtected?: boolean;
|
||||
dateModified?: string;
|
||||
utcDateScheduledForErasureSince?: string;
|
||||
/** optionally added to the entity */
|
||||
contentLength?: number;
|
||||
isDecrypted?: boolean;
|
||||
|
||||
constructor(row: AttachmentRow) {
|
||||
super();
|
||||
|
||||
if (!row.ownerId?.trim()) {
|
||||
@ -36,43 +64,23 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
throw new Error("'title' must be given to initialize a Attachment entity");
|
||||
}
|
||||
|
||||
/** @type {string} */
|
||||
this.attachmentId = row.attachmentId;
|
||||
/**
|
||||
* either noteId or revisionId to which this attachment belongs
|
||||
* @type {string}
|
||||
*/
|
||||
this.ownerId = row.ownerId;
|
||||
/** @type {string} */
|
||||
this.role = row.role;
|
||||
/** @type {string} */
|
||||
this.mime = row.mime;
|
||||
/** @type {string} */
|
||||
this.title = row.title;
|
||||
/** @type {int} */
|
||||
this.position = row.position;
|
||||
/** @type {string} */
|
||||
this.blobId = row.blobId;
|
||||
/** @type {boolean} */
|
||||
this.isProtected = !!row.isProtected;
|
||||
/** @type {string} */
|
||||
this.dateModified = row.dateModified;
|
||||
/** @type {string} */
|
||||
this.utcDateModified = row.utcDateModified;
|
||||
/** @type {string} */
|
||||
this.utcDateScheduledForErasureSince = row.utcDateScheduledForErasureSince;
|
||||
|
||||
/**
|
||||
* optionally added to the entity
|
||||
* @type {int}
|
||||
*/
|
||||
this.contentLength = row.contentLength;
|
||||
|
||||
this.decrypt();
|
||||
}
|
||||
|
||||
/** @returns {BAttachment} */
|
||||
copy() {
|
||||
copy(): BAttachment {
|
||||
return new BAttachment({
|
||||
ownerId: this.ownerId,
|
||||
role: this.role,
|
||||
@ -83,14 +91,13 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
});
|
||||
}
|
||||
|
||||
/** @returns {BNote} */
|
||||
getNote() {
|
||||
getNote(): BNote {
|
||||
return this.becca.notes[this.ownerId];
|
||||
}
|
||||
|
||||
/** @returns {boolean} true if the note has string content (not binary) */
|
||||
hasStringContent() {
|
||||
return utils.isStringNote(this.type, this.mime);
|
||||
/** @returns true if the note has string content (not binary) */
|
||||
hasStringContent(): boolean {
|
||||
return this.type !== undefined && utils.isStringNote(this.type, this.mime);
|
||||
}
|
||||
|
||||
isContentAvailable() {
|
||||
@ -111,33 +118,26 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
|
||||
if (!this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
|
||||
try {
|
||||
this.title = protectedSessionService.decryptString(this.title);
|
||||
this.title = protectedSessionService.decryptString(this.title) || "";
|
||||
this.isDecrypted = true;
|
||||
}
|
||||
catch (e) {
|
||||
catch (e: any) {
|
||||
log.error(`Could not decrypt attachment ${this.attachmentId}: ${e.message} ${e.stack}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {string|Buffer} */
|
||||
getContent() {
|
||||
getContent(): string | Buffer {
|
||||
return this._getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content
|
||||
* @param {object} [opts]
|
||||
* @param {object} [opts.forceSave=false] - will also save this BAttachment entity
|
||||
* @param {object} [opts.forceFrontendReload=false] - override frontend heuristics on when to reload, instruct to reload
|
||||
*/
|
||||
setContent(content, opts) {
|
||||
setContent(content: string | Buffer, opts: ContentOpts) {
|
||||
this._setContent(content, opts);
|
||||
}
|
||||
|
||||
/** @returns {{note: BNote, branch: BBranch}} */
|
||||
convertToNote() {
|
||||
if (this.type === 'search') {
|
||||
convertToNote(): { note: BNote, branch: BBranch } {
|
||||
// TODO: can this ever be "search"?
|
||||
if (this.type as string === 'search') {
|
||||
throw new Error(`Note of type search cannot have child notes`);
|
||||
}
|
||||
|
||||
@ -154,12 +154,12 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
throw new Error(`Cannot convert protected attachment outside of protected session`);
|
||||
}
|
||||
|
||||
const noteService = require('../../services/notes.js');
|
||||
const noteService = require('../../services/notes');
|
||||
|
||||
const { note, branch } = noteService.createNewNote({
|
||||
parentNoteId: this.ownerId,
|
||||
title: this.title,
|
||||
type: attachmentRoleToNoteTypeMapping[this.role],
|
||||
type: (attachmentRoleToNoteTypeMapping as any)[this.role],
|
||||
mime: this.mime,
|
||||
content: this.getContent(),
|
||||
isProtected: this.isProtected
|
||||
@ -196,9 +196,9 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
super.beforeSaving();
|
||||
|
||||
if (this.position === undefined || this.position === null) {
|
||||
this.position = 10 + sql.getValue(`SELECT COALESCE(MAX(position), 0)
|
||||
FROM attachments
|
||||
WHERE ownerId = ?`, [this.noteId]);
|
||||
this.position = 10 + sql.getValue<number>(`SELECT COALESCE(MAX(position), 0)
|
||||
FROM attachments
|
||||
WHERE ownerId = ?`, [this.noteId]);
|
||||
}
|
||||
|
||||
this.dateModified = dateUtils.localNowDateTime();
|
||||
@ -211,7 +211,7 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
ownerId: this.ownerId,
|
||||
role: this.role,
|
||||
mime: this.mime,
|
||||
title: this.title,
|
||||
title: this.title || undefined,
|
||||
position: this.position,
|
||||
blobId: this.blobId,
|
||||
isProtected: !!this.isProtected,
|
||||
@ -229,7 +229,7 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
|
||||
if (pojo.isProtected) {
|
||||
if (this.isDecrypted) {
|
||||
pojo.title = protectedSessionService.encrypt(pojo.title);
|
||||
pojo.title = protectedSessionService.encrypt(pojo.title || "") || undefined;
|
||||
}
|
||||
else {
|
||||
// updating protected note outside of protected session means we will keep original ciphertexts
|
||||
@ -241,4 +241,4 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BAttachment;
|
||||
export = BAttachment;
|
@ -1,30 +1,34 @@
|
||||
"use strict";
|
||||
|
||||
const BNote = require('./bnote.js');
|
||||
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const promotedAttributeDefinitionParser = require('../../services/promoted_attribute_definition_parser.js');
|
||||
const {sanitizeAttributeName} = require('../../services/sanitize_attribute_name.js');
|
||||
import BNote = require('./bnote');
|
||||
import AbstractBeccaEntity = require('./abstract_becca_entity');
|
||||
import dateUtils = require('../../services/date_utils');
|
||||
import promotedAttributeDefinitionParser = require('../../services/promoted_attribute_definition_parser');
|
||||
import sanitizeAttributeName = require('../../services/sanitize_attribute_name');
|
||||
import { AttributeRow, AttributeType } from './rows';
|
||||
|
||||
|
||||
/**
|
||||
* There are currently only two types of attributes, labels or relations.
|
||||
* @typedef {"label" | "relation"} AttributeType
|
||||
*/
|
||||
interface SavingOpts {
|
||||
skipValidation?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute is an abstract concept which has two real uses - label (key - value pair)
|
||||
* and relation (representing named relationship between source and target note)
|
||||
*
|
||||
* @extends AbstractBeccaEntity
|
||||
*/
|
||||
class BAttribute extends AbstractBeccaEntity {
|
||||
class BAttribute extends AbstractBeccaEntity<BAttribute> {
|
||||
static get entityName() { return "attributes"; }
|
||||
static get primaryKeyName() { return "attributeId"; }
|
||||
static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable"]; }
|
||||
|
||||
constructor(row) {
|
||||
attributeId!: string;
|
||||
noteId!: string;
|
||||
type!: AttributeType;
|
||||
name!: string;
|
||||
position!: number;
|
||||
value!: string;
|
||||
isInheritable!: boolean;
|
||||
|
||||
constructor(row: AttributeRow) {
|
||||
super();
|
||||
|
||||
if (!row) {
|
||||
@ -35,7 +39,7 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
this.init();
|
||||
}
|
||||
|
||||
updateFromRow(row) {
|
||||
updateFromRow(row: AttributeRow) {
|
||||
this.update([
|
||||
row.attributeId,
|
||||
row.noteId,
|
||||
@ -48,22 +52,14 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
]);
|
||||
}
|
||||
|
||||
update([attributeId, noteId, type, name, value, isInheritable, position, utcDateModified]) {
|
||||
/** @type {string} */
|
||||
update([attributeId, noteId, type, name, value, isInheritable, position, utcDateModified]: any[]) {
|
||||
this.attributeId = attributeId;
|
||||
/** @type {string} */
|
||||
this.noteId = noteId;
|
||||
/** @type {AttributeType} */
|
||||
this.type = type;
|
||||
/** @type {string} */
|
||||
this.name = name;
|
||||
/** @type {int} */
|
||||
this.position = position;
|
||||
/** @type {string} */
|
||||
this.value = value || "";
|
||||
/** @type {boolean} */
|
||||
this.isInheritable = !!isInheritable;
|
||||
/** @type {string} */
|
||||
this.utcDateModified = utcDateModified;
|
||||
|
||||
return this;
|
||||
@ -182,12 +178,12 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
return !(this.attributeId in this.becca.attributes);
|
||||
}
|
||||
|
||||
beforeSaving(opts = {}) {
|
||||
beforeSaving(opts: SavingOpts = {}) {
|
||||
if (!opts.skipValidation) {
|
||||
this.validate();
|
||||
}
|
||||
|
||||
this.name = sanitizeAttributeName(this.name);
|
||||
this.name = sanitizeAttributeName.sanitizeAttributeName(this.name);
|
||||
|
||||
if (!this.value) {
|
||||
// null value isn't allowed
|
||||
@ -226,7 +222,7 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
};
|
||||
}
|
||||
|
||||
createClone(type, name, value, isInheritable) {
|
||||
createClone(type: AttributeType, name: string, value: string, isInheritable: boolean) {
|
||||
return new BAttribute({
|
||||
noteId: this.noteId,
|
||||
type: type,
|
||||
@ -239,4 +235,4 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BAttribute;
|
||||
export = BAttribute;
|
@ -1,25 +1,29 @@
|
||||
import { BlobRow } from "./rows";
|
||||
|
||||
// TODO: Why this does not extend the abstract becca?
|
||||
class BBlob {
|
||||
static get entityName() { return "blobs"; }
|
||||
static get primaryKeyName() { return "blobId"; }
|
||||
static get hashedProperties() { return ["blobId", "content"]; }
|
||||
|
||||
constructor(row) {
|
||||
/** @type {string} */
|
||||
blobId: string;
|
||||
content: string | Buffer;
|
||||
contentLength: number;
|
||||
dateModified: string;
|
||||
utcDateModified: string;
|
||||
|
||||
constructor(row: BlobRow) {
|
||||
this.blobId = row.blobId;
|
||||
/** @type {string|Buffer} */
|
||||
this.content = row.content;
|
||||
/** @type {int} */
|
||||
this.contentLength = row.contentLength;
|
||||
/** @type {string} */
|
||||
this.dateModified = row.dateModified;
|
||||
/** @type {string} */
|
||||
this.utcDateModified = row.utcDateModified;
|
||||
}
|
||||
|
||||
getPojo() {
|
||||
return {
|
||||
blobId: this.blobId,
|
||||
content: this.content,
|
||||
content: this.content || null,
|
||||
contentLength: this.contentLength,
|
||||
dateModified: this.dateModified,
|
||||
utcDateModified: this.utcDateModified
|
||||
@ -27,4 +31,4 @@ class BBlob {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BBlob;
|
||||
export = BBlob;
|
@ -1,12 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
const BNote = require('./bnote.js');
|
||||
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const TaskContext = require('../../services/task_context.js');
|
||||
const cls = require('../../services/cls.js');
|
||||
const log = require('../../services/log.js');
|
||||
import BNote = require('./bnote');
|
||||
import AbstractBeccaEntity = require('./abstract_becca_entity');
|
||||
import dateUtils = require('../../services/date_utils');
|
||||
import utils = require('../../services/utils');
|
||||
import TaskContext = require('../../services/task_context');
|
||||
import cls = require('../../services/cls');
|
||||
import log = require('../../services/log');
|
||||
import { BranchRow } from './rows';
|
||||
|
||||
/**
|
||||
* Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple
|
||||
@ -14,16 +15,22 @@ const log = require('../../services/log.js');
|
||||
*
|
||||
* Note that you should not rely on the branch's identity, since it can change easily with a note's move.
|
||||
* Always check noteId instead.
|
||||
*
|
||||
* @extends AbstractBeccaEntity
|
||||
*/
|
||||
class BBranch extends AbstractBeccaEntity {
|
||||
class BBranch extends AbstractBeccaEntity<BBranch> {
|
||||
static get entityName() { return "branches"; }
|
||||
static get primaryKeyName() { return "branchId"; }
|
||||
// notePosition is not part of hash because it would produce a lot of updates in case of reordering
|
||||
static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "prefix"]; }
|
||||
|
||||
constructor(row) {
|
||||
branchId?: string;
|
||||
noteId!: string;
|
||||
parentNoteId!: string;
|
||||
prefix!: string | null;
|
||||
notePosition!: number;
|
||||
isExpanded!: boolean;
|
||||
utcDateModified?: string;
|
||||
|
||||
constructor(row: BranchRow) {
|
||||
super();
|
||||
|
||||
if (!row) {
|
||||
@ -34,7 +41,7 @@ class BBranch extends AbstractBeccaEntity {
|
||||
this.init();
|
||||
}
|
||||
|
||||
updateFromRow(row) {
|
||||
updateFromRow(row: BranchRow) {
|
||||
this.update([
|
||||
row.branchId,
|
||||
row.noteId,
|
||||
@ -46,20 +53,13 @@ class BBranch extends AbstractBeccaEntity {
|
||||
]);
|
||||
}
|
||||
|
||||
update([branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified]) {
|
||||
/** @type {string} */
|
||||
update([branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified]: any) {
|
||||
this.branchId = branchId;
|
||||
/** @type {string} */
|
||||
this.noteId = noteId;
|
||||
/** @type {string} */
|
||||
this.parentNoteId = parentNoteId;
|
||||
/** @type {string|null} */
|
||||
this.prefix = prefix;
|
||||
/** @type {int} */
|
||||
this.notePosition = notePosition;
|
||||
/** @type {boolean} */
|
||||
this.isExpanded = !!isExpanded;
|
||||
/** @type {string} */
|
||||
this.utcDateModified = utcDateModified;
|
||||
|
||||
return this;
|
||||
@ -83,18 +83,18 @@ class BBranch extends AbstractBeccaEntity {
|
||||
}
|
||||
|
||||
const parentNote = this.parentNote;
|
||||
|
||||
if (!childNote.parents.includes(parentNote)) {
|
||||
childNote.parents.push(parentNote);
|
||||
}
|
||||
|
||||
if (!parentNote.children.includes(childNote)) {
|
||||
parentNote.children.push(childNote);
|
||||
if (parentNote) {
|
||||
if (!childNote.parents.includes(parentNote)) {
|
||||
childNote.parents.push(parentNote);
|
||||
}
|
||||
|
||||
if (!parentNote.children.includes(childNote)) {
|
||||
parentNote.children.push(childNote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {BNote} */
|
||||
get childNote() {
|
||||
get childNote(): BNote {
|
||||
if (!(this.noteId in this.becca.notes)) {
|
||||
// entities can come out of order in sync/import, create skeleton which will be filled later
|
||||
this.becca.addNote(this.noteId, new BNote({noteId: this.noteId}));
|
||||
@ -103,13 +103,12 @@ class BBranch extends AbstractBeccaEntity {
|
||||
return this.becca.notes[this.noteId];
|
||||
}
|
||||
|
||||
/** @returns {BNote} */
|
||||
getNote() {
|
||||
getNote(): BNote {
|
||||
return this.childNote;
|
||||
}
|
||||
|
||||
/** @returns {BNote|undefined} - root branch will have undefined parent, all other branches have to have a parent note */
|
||||
get parentNote() {
|
||||
/** @returns root branch will have undefined parent, all other branches have to have a parent note */
|
||||
get parentNote(): BNote | undefined {
|
||||
if (!(this.parentNoteId in this.becca.notes) && this.parentNoteId !== 'none') {
|
||||
// entities can come out of order in sync/import, create skeleton which will be filled later
|
||||
this.becca.addNote(this.parentNoteId, new BNote({noteId: this.parentNoteId}));
|
||||
@ -119,7 +118,7 @@ class BBranch extends AbstractBeccaEntity {
|
||||
}
|
||||
|
||||
get isDeleted() {
|
||||
return !(this.branchId in this.becca.branches);
|
||||
return (this.branchId == undefined || !(this.branchId in this.becca.branches));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,12 +137,11 @@ class BBranch extends AbstractBeccaEntity {
|
||||
/**
|
||||
* Delete a branch. If this is a last note's branch, delete the note as well.
|
||||
*
|
||||
* @param {string} [deleteId] - optional delete identified
|
||||
* @param {TaskContext} [taskContext]
|
||||
* @param deleteId - optional delete identified
|
||||
*
|
||||
* @returns {boolean} - true if note has been deleted, false otherwise
|
||||
* @returns true if note has been deleted, false otherwise
|
||||
*/
|
||||
deleteBranch(deleteId, taskContext) {
|
||||
deleteBranch(deleteId: string, taskContext: TaskContext): boolean {
|
||||
if (!deleteId) {
|
||||
deleteId = utils.randomString(10);
|
||||
}
|
||||
@ -161,7 +159,7 @@ class BBranch extends AbstractBeccaEntity {
|
||||
|
||||
if (parentBranches.length === 1 && parentBranches[0] === this) {
|
||||
// needs to be run before branches and attributes are deleted and thus attached relations disappear
|
||||
const handlers = require('../../services/handlers.js');
|
||||
const handlers = require('../../services/handlers');
|
||||
handlers.runAttachedRelations(note, 'runOnNoteDeletion', note);
|
||||
}
|
||||
}
|
||||
@ -182,7 +180,9 @@ class BBranch extends AbstractBeccaEntity {
|
||||
}
|
||||
|
||||
for (const childBranch of note.getChildBranches()) {
|
||||
childBranch.deleteBranch(deleteId, taskContext);
|
||||
if (childBranch) {
|
||||
childBranch.deleteBranch(deleteId, taskContext);
|
||||
}
|
||||
}
|
||||
|
||||
// first delete children and then parent - this will show up better in recent changes
|
||||
@ -222,11 +222,17 @@ class BBranch extends AbstractBeccaEntity {
|
||||
if (this.notePosition === undefined || this.notePosition === null) {
|
||||
let maxNotePos = 0;
|
||||
|
||||
for (const childBranch of this.parentNote.getChildBranches()) {
|
||||
if (maxNotePos < childBranch.notePosition
|
||||
&& childBranch.noteId !== '_hidden' // hidden has a very large notePosition to always stay last
|
||||
) {
|
||||
maxNotePos = childBranch.notePosition;
|
||||
if (this.parentNote) {
|
||||
for (const childBranch of this.parentNote.getChildBranches()) {
|
||||
if (!childBranch) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (maxNotePos < childBranch.notePosition
|
||||
&& childBranch.noteId !== '_hidden' // hidden has a very large notePosition to always stay last
|
||||
) {
|
||||
maxNotePos = childBranch.notePosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,7 +267,7 @@ class BBranch extends AbstractBeccaEntity {
|
||||
};
|
||||
}
|
||||
|
||||
createClone(parentNoteId, notePosition) {
|
||||
createClone(parentNoteId: string, notePosition: number) {
|
||||
const existingBranch = this.becca.getBranchFromChildAndParent(this.noteId, parentNoteId);
|
||||
|
||||
if (existingBranch) {
|
||||
@ -279,4 +285,4 @@ class BBranch extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BBranch;
|
||||
export = BBranch;
|
@ -1,7 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
|
||||
import { EtapiTokenRow } from "./rows";
|
||||
|
||||
import dateUtils = require('../../services/date_utils');
|
||||
import AbstractBeccaEntity = require('./abstract_becca_entity');
|
||||
|
||||
/**
|
||||
* EtapiToken is an entity representing token used to authenticate against Trilium REST API from client applications.
|
||||
@ -11,15 +13,18 @@ const AbstractBeccaEntity = require('./abstract_becca_entity.js');
|
||||
*
|
||||
* The format user is presented with is "<etapiTokenId>_<tokenHash>". This is also called "authToken" to distinguish it
|
||||
* from tokenHash and token.
|
||||
*
|
||||
* @extends AbstractBeccaEntity
|
||||
*/
|
||||
class BEtapiToken extends AbstractBeccaEntity {
|
||||
class BEtapiToken extends AbstractBeccaEntity<BEtapiToken> {
|
||||
static get entityName() { return "etapi_tokens"; }
|
||||
static get primaryKeyName() { return "etapiTokenId"; }
|
||||
static get hashedProperties() { return ["etapiTokenId", "name", "tokenHash", "utcDateCreated", "utcDateModified", "isDeleted"]; }
|
||||
|
||||
constructor(row) {
|
||||
etapiTokenId!: string;
|
||||
name!: string;
|
||||
tokenHash!: string;
|
||||
private _isDeleted!: boolean;
|
||||
|
||||
constructor(row: EtapiTokenRow) {
|
||||
super();
|
||||
|
||||
if (!row) {
|
||||
@ -30,19 +35,17 @@ class BEtapiToken extends AbstractBeccaEntity {
|
||||
this.init();
|
||||
}
|
||||
|
||||
updateFromRow(row) {
|
||||
/** @type {string} */
|
||||
get isDeleted() {
|
||||
return this._isDeleted;
|
||||
}
|
||||
|
||||
updateFromRow(row: EtapiTokenRow) {
|
||||
this.etapiTokenId = row.etapiTokenId;
|
||||
/** @type {string} */
|
||||
this.name = row.name;
|
||||
/** @type {string} */
|
||||
this.tokenHash = row.tokenHash;
|
||||
/** @type {string} */
|
||||
this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime();
|
||||
/** @type {string} */
|
||||
this.utcDateModified = row.utcDateModified || this.utcDateCreated;
|
||||
/** @type {boolean} */
|
||||
this.isDeleted = !!row.isDeleted;
|
||||
this._isDeleted = !!row.isDeleted;
|
||||
|
||||
if (this.etapiTokenId) {
|
||||
this.becca.etapiTokens[this.etapiTokenId] = this;
|
||||
@ -75,4 +78,4 @@ class BEtapiToken extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BEtapiToken;
|
||||
export = BEtapiToken;
|
File diff suppressed because it is too large
Load Diff
@ -1,33 +1,32 @@
|
||||
"use strict";
|
||||
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
|
||||
import dateUtils = require('../../services/date_utils');
|
||||
import AbstractBeccaEntity = require('./abstract_becca_entity');
|
||||
import { OptionRow } from './rows';
|
||||
|
||||
/**
|
||||
* Option represents a name-value pair, either directly configurable by the user or some system property.
|
||||
*
|
||||
* @extends AbstractBeccaEntity
|
||||
*/
|
||||
class BOption extends AbstractBeccaEntity {
|
||||
class BOption extends AbstractBeccaEntity<BOption> {
|
||||
static get entityName() { return "options"; }
|
||||
static get primaryKeyName() { return "name"; }
|
||||
static get hashedProperties() { return ["name", "value"]; }
|
||||
|
||||
constructor(row) {
|
||||
name!: string;
|
||||
value!: string;
|
||||
isSynced!: boolean;
|
||||
|
||||
constructor(row: OptionRow) {
|
||||
super();
|
||||
|
||||
this.updateFromRow(row);
|
||||
this.becca.options[this.name] = this;
|
||||
}
|
||||
|
||||
updateFromRow(row) {
|
||||
/** @type {string} */
|
||||
updateFromRow(row: OptionRow) {
|
||||
this.name = row.name;
|
||||
/** @type {string} */
|
||||
this.value = row.value;
|
||||
/** @type {boolean} */
|
||||
this.isSynced = !!row.isSynced;
|
||||
/** @type {string} */
|
||||
this.utcDateModified = row.utcDateModified;
|
||||
}
|
||||
|
||||
@ -47,4 +46,4 @@ class BOption extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BOption;
|
||||
export = BOption;
|
@ -1,25 +1,26 @@
|
||||
"use strict";
|
||||
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
|
||||
import { RecentNoteRow } from "./rows";
|
||||
|
||||
import dateUtils = require('../../services/date_utils');
|
||||
import AbstractBeccaEntity = require('./abstract_becca_entity');
|
||||
|
||||
/**
|
||||
* RecentNote represents recently visited note.
|
||||
*
|
||||
* @extends AbstractBeccaEntity
|
||||
*/
|
||||
class BRecentNote extends AbstractBeccaEntity {
|
||||
class BRecentNote extends AbstractBeccaEntity<BRecentNote> {
|
||||
static get entityName() { return "recent_notes"; }
|
||||
static get primaryKeyName() { return "noteId"; }
|
||||
|
||||
constructor(row) {
|
||||
noteId: string;
|
||||
notePath: string;
|
||||
utcDateCreated: string;
|
||||
|
||||
constructor(row: RecentNoteRow) {
|
||||
super();
|
||||
|
||||
/** @type {string} */
|
||||
this.noteId = row.noteId;
|
||||
/** @type {string} */
|
||||
this.notePath = row.notePath;
|
||||
/** @type {string} */
|
||||
this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime();
|
||||
}
|
||||
|
||||
@ -32,4 +33,4 @@ class BRecentNote extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BRecentNote;
|
||||
export = BRecentNote;
|
@ -1,59 +1,67 @@
|
||||
"use strict";
|
||||
|
||||
const protectedSessionService = require('../../services/protected_session.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const becca = require('../becca.js');
|
||||
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const BAttachment = require('./battachment.js');
|
||||
import protectedSessionService = require('../../services/protected_session');
|
||||
import utils = require('../../services/utils');
|
||||
import dateUtils = require('../../services/date_utils');
|
||||
import becca = require('../becca');
|
||||
import AbstractBeccaEntity = require('./abstract_becca_entity');
|
||||
import sql = require('../../services/sql');
|
||||
import BAttachment = require('./battachment');
|
||||
import { AttachmentRow, RevisionRow } from './rows';
|
||||
|
||||
interface ContentOpts {
|
||||
/** will also save this BRevision entity */
|
||||
forceSave?: boolean;
|
||||
}
|
||||
|
||||
interface GetByIdOpts {
|
||||
includeContentLength?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revision represents a snapshot of note's title and content at some point in the past.
|
||||
* It's used for seamless note versioning.
|
||||
*
|
||||
* @extends AbstractBeccaEntity
|
||||
*/
|
||||
class BRevision extends AbstractBeccaEntity {
|
||||
class BRevision extends AbstractBeccaEntity<BRevision> {
|
||||
static get entityName() { return "revisions"; }
|
||||
static get primaryKeyName() { return "revisionId"; }
|
||||
static get hashedProperties() { return ["revisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated",
|
||||
"utcDateLastEdited", "utcDateCreated", "utcDateModified", "blobId"]; }
|
||||
|
||||
constructor(row, titleDecrypted = false) {
|
||||
revisionId?: string;
|
||||
noteId: string;
|
||||
type: string;
|
||||
mime: string;
|
||||
isProtected: boolean;
|
||||
title: string;
|
||||
blobId?: string;
|
||||
dateLastEdited?: string;
|
||||
dateCreated: string;
|
||||
utcDateLastEdited?: string;
|
||||
utcDateCreated: string;
|
||||
contentLength?: number;
|
||||
content?: string;
|
||||
|
||||
constructor(row: RevisionRow, titleDecrypted = false) {
|
||||
super();
|
||||
|
||||
/** @type {string} */
|
||||
this.revisionId = row.revisionId;
|
||||
/** @type {string} */
|
||||
this.noteId = row.noteId;
|
||||
/** @type {string} */
|
||||
this.type = row.type;
|
||||
/** @type {string} */
|
||||
this.mime = row.mime;
|
||||
/** @type {boolean} */
|
||||
this.isProtected = !!row.isProtected;
|
||||
/** @type {string} */
|
||||
this.title = row.title;
|
||||
/** @type {string} */
|
||||
this.blobId = row.blobId;
|
||||
/** @type {string} */
|
||||
this.dateLastEdited = row.dateLastEdited;
|
||||
/** @type {string} */
|
||||
this.dateCreated = row.dateCreated;
|
||||
/** @type {string} */
|
||||
this.utcDateLastEdited = row.utcDateLastEdited;
|
||||
/** @type {string} */
|
||||
this.utcDateCreated = row.utcDateCreated;
|
||||
/** @type {string} */
|
||||
this.utcDateModified = row.utcDateModified;
|
||||
/** @type {int} */
|
||||
this.contentLength = row.contentLength;
|
||||
|
||||
if (this.isProtected && !titleDecrypted) {
|
||||
this.title = protectedSessionService.isProtectedSessionAvailable()
|
||||
? protectedSessionService.decryptString(this.title)
|
||||
: "[protected]";
|
||||
const decryptedTitle = protectedSessionService.isProtectedSessionAvailable() ? protectedSessionService.decryptString(this.title) : null;
|
||||
this.title = decryptedTitle || "[protected]";
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,8 +69,8 @@ class BRevision extends AbstractBeccaEntity {
|
||||
return becca.notes[this.noteId];
|
||||
}
|
||||
|
||||
/** @returns {boolean} true if the note has string content (not binary) */
|
||||
hasStringContent() {
|
||||
/** @returns true if the note has string content (not binary) */
|
||||
hasStringContent(): boolean {
|
||||
return utils.isStringNote(this.type, this.mime);
|
||||
}
|
||||
|
||||
@ -80,16 +88,14 @@ class BRevision extends AbstractBeccaEntity {
|
||||
*
|
||||
* This is the same approach as is used for Note's content.
|
||||
*/
|
||||
|
||||
/** @returns {string|Buffer} */
|
||||
getContent() {
|
||||
return this._getContent();
|
||||
// TODO: initial declaration included Buffer, but everywhere it's treated as a string.
|
||||
getContent(): string {
|
||||
return this._getContent() as string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {*}
|
||||
* @throws Error in case of invalid JSON */
|
||||
getJsonContent() {
|
||||
getJsonContent(): {} | null {
|
||||
const content = this.getContent();
|
||||
|
||||
if (!content || !content.trim()) {
|
||||
@ -99,8 +105,8 @@ class BRevision extends AbstractBeccaEntity {
|
||||
return JSON.parse(content);
|
||||
}
|
||||
|
||||
/** @returns {*|null} valid object or null if the content cannot be parsed as JSON */
|
||||
getJsonContentSafely() {
|
||||
/** @returns valid object or null if the content cannot be parsed as JSON */
|
||||
getJsonContentSafely(): {} | null {
|
||||
try {
|
||||
return this.getJsonContent();
|
||||
}
|
||||
@ -109,18 +115,12 @@ class BRevision extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content
|
||||
* @param {object} [opts]
|
||||
* @param {object} [opts.forceSave=false] - will also save this BRevision entity
|
||||
*/
|
||||
setContent(content, opts) {
|
||||
setContent(content: string | Buffer, opts: ContentOpts = {}) {
|
||||
this._setContent(content, opts);
|
||||
}
|
||||
|
||||
/** @returns {BAttachment[]} */
|
||||
getAttachments() {
|
||||
return sql.getRows(`
|
||||
getAttachments(): BAttachment[] {
|
||||
return sql.getRows<AttachmentRow>(`
|
||||
SELECT attachments.*
|
||||
FROM attachments
|
||||
WHERE ownerId = ?
|
||||
@ -128,8 +128,7 @@ class BRevision extends AbstractBeccaEntity {
|
||||
.map(row => new BAttachment(row));
|
||||
}
|
||||
|
||||
/** @returns {BAttachment|null} */
|
||||
getAttachmentById(attachmentId, opts = {}) {
|
||||
getAttachmentById(attachmentId: String, opts: GetByIdOpts = {}): BAttachment | null {
|
||||
opts.includeContentLength = !!opts.includeContentLength;
|
||||
|
||||
const query = opts.includeContentLength
|
||||
@ -139,13 +138,12 @@ class BRevision extends AbstractBeccaEntity {
|
||||
WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`
|
||||
: `SELECT * FROM attachments WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`;
|
||||
|
||||
return sql.getRows(query, [this.revisionId, attachmentId])
|
||||
return sql.getRows<AttachmentRow>(query, [this.revisionId, attachmentId])
|
||||
.map(row => new BAttachment(row))[0];
|
||||
}
|
||||
|
||||
/** @returns {BAttachment[]} */
|
||||
getAttachmentsByRole(role) {
|
||||
return sql.getRows(`
|
||||
getAttachmentsByRole(role: string): BAttachment[] {
|
||||
return sql.getRows<AttachmentRow>(`
|
||||
SELECT attachments.*
|
||||
FROM attachments
|
||||
WHERE ownerId = ?
|
||||
@ -155,8 +153,7 @@ class BRevision extends AbstractBeccaEntity {
|
||||
.map(row => new BAttachment(row));
|
||||
}
|
||||
|
||||
/** @returns {BAttachment} */
|
||||
getAttachmentByTitle(title) {
|
||||
getAttachmentByTitle(title: string): BAttachment {
|
||||
// cannot use SQL to filter by title since it can be encrypted
|
||||
return this.getAttachments().filter(attachment => attachment.title === title)[0];
|
||||
}
|
||||
@ -181,7 +178,7 @@ class BRevision extends AbstractBeccaEntity {
|
||||
type: this.type,
|
||||
mime: this.mime,
|
||||
isProtected: this.isProtected,
|
||||
title: this.title,
|
||||
title: this.title || undefined,
|
||||
blobId: this.blobId,
|
||||
dateLastEdited: this.dateLastEdited,
|
||||
dateCreated: this.dateCreated,
|
||||
@ -200,7 +197,7 @@ class BRevision extends AbstractBeccaEntity {
|
||||
|
||||
if (pojo.isProtected) {
|
||||
if (protectedSessionService.isProtectedSessionAvailable()) {
|
||||
pojo.title = protectedSessionService.encrypt(this.title);
|
||||
pojo.title = protectedSessionService.encrypt(this.title) || undefined;
|
||||
}
|
||||
else {
|
||||
// updating protected note outside of protected session means we will keep original ciphertexts
|
||||
@ -212,4 +209,4 @@ class BRevision extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BRevision;
|
||||
export = BRevision;
|
106
src/becca/entities/rows.ts
Normal file
106
src/becca/entities/rows.ts
Normal file
@ -0,0 +1,106 @@
|
||||
// TODO: Booleans should probably be numbers instead (as SQLite does not have booleans.);
|
||||
|
||||
export interface AttachmentRow {
|
||||
attachmentId?: string;
|
||||
ownerId?: string;
|
||||
role: string;
|
||||
mime: string;
|
||||
title?: string;
|
||||
position?: number;
|
||||
blobId?: string;
|
||||
isProtected?: boolean;
|
||||
dateModified?: string;
|
||||
utcDateModified?: string;
|
||||
utcDateScheduledForErasureSince?: string;
|
||||
contentLength?: number;
|
||||
content?: string;
|
||||
}
|
||||
|
||||
export interface RevisionRow {
|
||||
revisionId?: string;
|
||||
noteId: string;
|
||||
type: string;
|
||||
mime: string;
|
||||
isProtected?: boolean;
|
||||
title: string;
|
||||
blobId?: string;
|
||||
dateLastEdited?: string;
|
||||
dateCreated: string;
|
||||
utcDateLastEdited?: string;
|
||||
utcDateCreated: string;
|
||||
utcDateModified: string;
|
||||
contentLength?: number;
|
||||
}
|
||||
|
||||
export interface RecentNoteRow {
|
||||
noteId: string;
|
||||
notePath: string;
|
||||
utcDateCreated?: string;
|
||||
}
|
||||
|
||||
export interface OptionRow {
|
||||
name: string;
|
||||
value: string;
|
||||
isSynced: boolean;
|
||||
utcDateModified: string;
|
||||
}
|
||||
|
||||
export interface EtapiTokenRow {
|
||||
etapiTokenId: string;
|
||||
name: string;
|
||||
tokenHash: string;
|
||||
utcDateCreated?: string;
|
||||
utcDateModified?: string;
|
||||
isDeleted: boolean;
|
||||
}
|
||||
|
||||
export interface BlobRow {
|
||||
blobId: string;
|
||||
content: string | Buffer;
|
||||
contentLength: number;
|
||||
dateModified: string;
|
||||
utcDateModified: string;
|
||||
}
|
||||
|
||||
export type AttributeType = "label" | "relation";
|
||||
|
||||
export interface AttributeRow {
|
||||
attributeId?: string;
|
||||
noteId: string;
|
||||
type: AttributeType;
|
||||
name: string;
|
||||
position: number;
|
||||
value: string;
|
||||
isInheritable: boolean;
|
||||
utcDateModified?: string;
|
||||
}
|
||||
|
||||
export interface BranchRow {
|
||||
branchId?: string;
|
||||
noteId: string;
|
||||
parentNoteId: string;
|
||||
prefix: string | null;
|
||||
notePosition: number;
|
||||
isExpanded: boolean;
|
||||
utcDateModified?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* There are many different Note types, some of which are entirely opaque to the
|
||||
* end user. Those types should be used only for checking against, they are
|
||||
* not for direct use.
|
||||
*/
|
||||
export type NoteType = ("file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code");
|
||||
|
||||
export interface NoteRow {
|
||||
noteId: string;
|
||||
title: string;
|
||||
type: NoteType;
|
||||
mime: string;
|
||||
isProtected: boolean;
|
||||
blobId: string;
|
||||
dateCreated: string;
|
||||
dateModified: string;
|
||||
utcDateCreated: string;
|
||||
utcDateModified: string;
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
const BAttachment = require('./entities/battachment.js');
|
||||
const BAttribute = require('./entities/battribute.js');
|
||||
const BBlob = require('./entities/bblob.js');
|
||||
const BBranch = require('./entities/bbranch.js');
|
||||
const BEtapiToken = require('./entities/betapi_token.js');
|
||||
const BNote = require('./entities/bnote.js');
|
||||
const BOption = require('./entities/boption.js');
|
||||
const BRecentNote = require('./entities/brecent_note.js');
|
||||
const BRevision = require('./entities/brevision.js');
|
||||
const BAttachment = require('./entities/battachment');
|
||||
const BAttribute = require('./entities/battribute');
|
||||
const BBlob = require('./entities/bblob');
|
||||
const BBranch = require('./entities/bbranch');
|
||||
const BEtapiToken = require('./entities/betapi_token');
|
||||
const BNote = require('./entities/bnote');
|
||||
const BOption = require('./entities/boption');
|
||||
const BRecentNote = require('./entities/brecent_note');
|
||||
const BRevision = require('./entities/brevision');
|
||||
|
||||
const ENTITY_NAME_TO_ENTITY = {
|
||||
"attachments": BAttachment,
|
||||
|
@ -1,7 +1,7 @@
|
||||
const becca = require('./becca.js');
|
||||
const log = require('../services/log.js');
|
||||
const beccaService = require('./becca_service.js');
|
||||
const dateUtils = require('../services/date_utils.js');
|
||||
const becca = require('./becca');
|
||||
const log = require('../services/log');
|
||||
const beccaService = require('./becca_service');
|
||||
const dateUtils = require('../services/date_utils');
|
||||
const {JSDOM} = require("jsdom");
|
||||
|
||||
const DEBUG = false;
|
||||
|
@ -1,7 +0,0 @@
|
||||
class NotFoundError {
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NotFoundError;
|
9
src/errors/not_found_error.ts
Normal file
9
src/errors/not_found_error.ts
Normal file
@ -0,0 +1,9 @@
|
||||
class NotFoundError {
|
||||
message: string;
|
||||
|
||||
constructor(message: string) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
export = NotFoundError;
|
@ -1,5 +1,7 @@
|
||||
class ValidationError {
|
||||
constructor(message) {
|
||||
message: string;
|
||||
|
||||
constructor(message: string) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
const appInfo = require('../services/app_info.js');
|
||||
const eu = require('./etapi_utils.js');
|
||||
const eu = require('./etapi_utils');
|
||||
|
||||
function register(router) {
|
||||
eu.route(router, 'get', '/etapi/app-info', (req, res, next) => {
|
||||
|
@ -1,8 +1,8 @@
|
||||
const becca = require('../becca/becca.js');
|
||||
const eu = require('./etapi_utils.js');
|
||||
const becca = require('../becca/becca');
|
||||
const eu = require('./etapi_utils');
|
||||
const mappers = require('./mappers.js');
|
||||
const v = require('./validators.js');
|
||||
const utils = require('../services/utils.js');
|
||||
const utils = require('../services/utils');
|
||||
|
||||
function register(router) {
|
||||
const ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
const becca = require('../becca/becca.js');
|
||||
const eu = require('./etapi_utils.js');
|
||||
const becca = require('../becca/becca');
|
||||
const eu = require('./etapi_utils');
|
||||
const mappers = require('./mappers.js');
|
||||
const attributeService = require('../services/attributes.js');
|
||||
const v = require('./validators.js');
|
||||
|
@ -1,6 +1,6 @@
|
||||
const becca = require('../becca/becca.js');
|
||||
const eu = require('./etapi_utils.js');
|
||||
const passwordEncryptionService = require('../services/encryption/password_encryption.js');
|
||||
const becca = require('../becca/becca');
|
||||
const eu = require('./etapi_utils');
|
||||
const passwordEncryptionService = require('../services/encryption/password_encryption');
|
||||
const etapiTokenService = require('../services/etapi_tokens.js');
|
||||
|
||||
function register(router, loginMiddleware) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
const eu = require('./etapi_utils.js');
|
||||
const eu = require('./etapi_utils');
|
||||
const backupService = require('../services/backup.js');
|
||||
|
||||
function register(router) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
const becca = require('../becca/becca.js');
|
||||
const eu = require('./etapi_utils.js');
|
||||
const becca = require('../becca/becca');
|
||||
const eu = require('./etapi_utils');
|
||||
const mappers = require('./mappers.js');
|
||||
const BBranch = require('../becca/entities/bbranch.js');
|
||||
const entityChangesService = require('../services/entity_changes.js');
|
||||
const BBranch = require('../becca/entities/bbranch');
|
||||
const entityChangesService = require('../services/entity_changes');
|
||||
const v = require('./validators.js');
|
||||
|
||||
function register(router) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
const cls = require('../services/cls.js');
|
||||
const sql = require('../services/sql.js');
|
||||
const log = require('../services/log.js');
|
||||
const becca = require('../becca/becca.js');
|
||||
const cls = require('../services/cls');
|
||||
const sql = require('../services/sql');
|
||||
const log = require('../services/log');
|
||||
const becca = require('../becca/becca');
|
||||
const etapiTokenService = require('../services/etapi_tokens.js');
|
||||
const config = require('../services/config.js');
|
||||
const config = require('../services/config');
|
||||
const GENERIC_CODE = "GENERIC";
|
||||
|
||||
const noAuthentication = config.General && config.General.noAuthentication === true;
|
||||
|
@ -1,9 +1,9 @@
|
||||
const becca = require('../becca/becca.js');
|
||||
const utils = require('../services/utils.js');
|
||||
const eu = require('./etapi_utils.js');
|
||||
const becca = require('../becca/becca');
|
||||
const utils = require('../services/utils');
|
||||
const eu = require('./etapi_utils');
|
||||
const mappers = require('./mappers.js');
|
||||
const noteService = require('../services/notes.js');
|
||||
const TaskContext = require('../services/task_context.js');
|
||||
const TaskContext = require('../services/task_context');
|
||||
const v = require('./validators.js');
|
||||
const searchService = require('../services/search/services/search.js');
|
||||
const SearchContext = require('../services/search/search_context.js');
|
||||
|
@ -1,6 +1,6 @@
|
||||
const specialNotesService = require('../services/special_notes.js');
|
||||
const dateNotesService = require('../services/date_notes.js');
|
||||
const eu = require('./etapi_utils.js');
|
||||
const eu = require('./etapi_utils');
|
||||
const mappers = require('./mappers.js');
|
||||
|
||||
const getDateInvalidError = date => new eu.EtapiError(400, "DATE_INVALID", `Date "${date}" is not valid.`);
|
||||
|
@ -1,5 +1,5 @@
|
||||
const noteTypeService = require('../services/note_types.js');
|
||||
const dateUtils = require('../services/date_utils.js');
|
||||
const dateUtils = require('../services/date_utils');
|
||||
|
||||
function mandatory(obj) {
|
||||
if (obj === undefined ) {
|
||||
@ -64,7 +64,7 @@ function isNoteId(obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
const becca = require('../becca/becca.js');
|
||||
const becca = require('../becca/becca');
|
||||
|
||||
if (typeof obj !== 'string') {
|
||||
return `'${obj}' is not a valid noteId`;
|
||||
|
@ -1,6 +1,6 @@
|
||||
const becca = require('../../becca/becca.js');
|
||||
const blobService = require('../../services/blob.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const blobService = require('../../services/blob');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
const imageService = require("../../services/image.js");
|
||||
|
||||
function getAttachmentBlob(req) {
|
||||
|
@ -1,11 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('../../services/sql.js');
|
||||
const log = require('../../services/log.js');
|
||||
const sql = require('../../services/sql');
|
||||
const log = require('../../services/log');
|
||||
const attributeService = require('../../services/attributes.js');
|
||||
const BAttribute = require('../../becca/entities/battribute.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const BAttribute = require('../../becca/entities/battribute');
|
||||
const becca = require('../../becca/becca');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
|
||||
function getEffectiveNoteAttributes(req) {
|
||||
const note = becca.getNote(req.params.noteId);
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
const beccaService = require('../../becca/becca_service.js');
|
||||
const searchService = require('../../services/search/services/search.js');
|
||||
const log = require('../../services/log.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const cls = require('../../services/cls.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const log = require('../../services/log');
|
||||
const utils = require('../../services/utils');
|
||||
const cls = require('../../services/cls');
|
||||
const becca = require('../../becca/becca');
|
||||
|
||||
function getAutocomplete(req) {
|
||||
const query = req.query.query.trim();
|
||||
|
@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require('fs');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const {LOG_DIR} = require('../../services/data_dir.js');
|
||||
const dateUtils = require('../../services/date_utils');
|
||||
const {LOG_DIR} = require('../../services/data_dir');
|
||||
|
||||
function getBackendLog() {
|
||||
const file = `${LOG_DIR}/trilium-${dateUtils.localNowDate()}.log`;
|
||||
|
@ -1,16 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('../../services/sql.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const entityChangesService = require('../../services/entity_changes.js');
|
||||
const sql = require('../../services/sql');
|
||||
const utils = require('../../services/utils');
|
||||
const entityChangesService = require('../../services/entity_changes');
|
||||
const treeService = require('../../services/tree.js');
|
||||
const eraseService = require('../../services/erase.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const TaskContext = require('../../services/task_context.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const TaskContext = require('../../services/task_context');
|
||||
const branchService = require('../../services/branches.js');
|
||||
const log = require('../../services/log.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const eventService = require("../../services/events.js");
|
||||
const log = require('../../services/log');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
const eventService = require("../../services/events");
|
||||
|
||||
/**
|
||||
* Code in this file deals with moving and cloning branches. The relationship between note and parent note is unique
|
||||
|
@ -1,4 +1,4 @@
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const bulkActionService = require('../../services/bulk_actions.js');
|
||||
|
||||
function execute(req) {
|
||||
|
@ -4,12 +4,12 @@ const attributeService = require('../../services/attributes.js');
|
||||
const cloneService = require('../../services/cloning.js');
|
||||
const noteService = require('../../services/notes.js');
|
||||
const dateNoteService = require('../../services/date_notes.js');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const dateUtils = require('../../services/date_utils');
|
||||
const imageService = require('../../services/image.js');
|
||||
const appInfo = require('../../services/app_info.js');
|
||||
const ws = require('../../services/ws.js');
|
||||
const log = require('../../services/log.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const ws = require('../../services/ws');
|
||||
const log = require('../../services/log');
|
||||
const utils = require('../../services/utils');
|
||||
const path = require('path');
|
||||
const htmlSanitizer = require('../../services/html_sanitizer.js');
|
||||
const {formatAttrForSearch} = require('../../services/attribute_formatter.js');
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('../../services/sql.js');
|
||||
const log = require('../../services/log.js');
|
||||
const sql = require('../../services/sql');
|
||||
const log = require('../../services/log');
|
||||
const backupService = require('../../services/backup.js');
|
||||
const anonymizationService = require('../../services/anonymization.js');
|
||||
const consistencyChecksService = require('../../services/consistency_checks.js');
|
||||
|
@ -3,10 +3,10 @@
|
||||
const zipExportService = require('../../services/export/zip.js');
|
||||
const singleExportService = require('../../services/export/single.js');
|
||||
const opmlExportService = require('../../services/export/opml.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const TaskContext = require('../../services/task_context.js');
|
||||
const log = require('../../services/log.js');
|
||||
const NotFoundError = require('../../errors/not_found_error.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const TaskContext = require('../../services/task_context');
|
||||
const log = require('../../services/log');
|
||||
const NotFoundError = require('../../errors/not_found_error');
|
||||
|
||||
function exportBranch(req, res) {
|
||||
const {branchId, type, format, version, taskId} = req.params;
|
||||
|
@ -1,16 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
const protectedSessionService = require('../../services/protected_session.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const log = require('../../services/log.js');
|
||||
const protectedSessionService = require('../../services/protected_session');
|
||||
const utils = require('../../services/utils');
|
||||
const log = require('../../services/log');
|
||||
const noteService = require('../../services/notes.js');
|
||||
const tmp = require('tmp');
|
||||
const fs = require('fs');
|
||||
const { Readable } = require('stream');
|
||||
const chokidar = require('chokidar');
|
||||
const ws = require('../../services/ws.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const ws = require('../../services/ws');
|
||||
const becca = require('../../becca/becca');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
|
||||
function updateFile(req) {
|
||||
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||
|
@ -1,4 +1,4 @@
|
||||
const optionService = require('../../services/options.js');
|
||||
const optionService = require('../../services/options');
|
||||
|
||||
function getFontCss(req, res) {
|
||||
res.setHeader('Content-Type', 'text/css');
|
||||
|
@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
const imageService = require('../../services/image.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const RESOURCE_DIR = require('../../services/resource_dir.js').RESOURCE_DIR;
|
||||
const becca = require('../../becca/becca');
|
||||
const RESOURCE_DIR = require('../../services/resource_dir').RESOURCE_DIR;
|
||||
const fs = require('fs');
|
||||
|
||||
function returnImageFromNote(req, res) {
|
||||
|
@ -4,13 +4,13 @@ const enexImportService = require('../../services/import/enex.js');
|
||||
const opmlImportService = require('../../services/import/opml.js');
|
||||
const zipImportService = require('../../services/import/zip.js');
|
||||
const singleImportService = require('../../services/import/single.js');
|
||||
const cls = require('../../services/cls.js');
|
||||
const cls = require('../../services/cls');
|
||||
const path = require('path');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const beccaLoader = require('../../becca/becca_loader.js');
|
||||
const log = require('../../services/log.js');
|
||||
const TaskContext = require('../../services/task_context.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const log = require('../../services/log');
|
||||
const TaskContext = require('../../services/task_context');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
|
||||
async function importNotesToBranch(req) {
|
||||
const {parentNoteId} = req.params;
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const keyboardActions = require('../../services/keyboard_actions.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
|
||||
function getKeyboardActions() {
|
||||
return keyboardActions.getKeyboardActions();
|
||||
|
@ -1,16 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
const options = require('../../services/options.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const instanceId = require('../../services/instance_id.js');
|
||||
const passwordEncryptionService = require('../../services/encryption/password_encryption.js');
|
||||
const protectedSessionService = require('../../services/protected_session.js');
|
||||
const options = require('../../services/options');
|
||||
const utils = require('../../services/utils');
|
||||
const dateUtils = require('../../services/date_utils');
|
||||
const instanceId = require('../../services/instance_id');
|
||||
const passwordEncryptionService = require('../../services/encryption/password_encryption');
|
||||
const protectedSessionService = require('../../services/protected_session');
|
||||
const appInfo = require('../../services/app_info.js');
|
||||
const eventService = require('../../services/events.js');
|
||||
const eventService = require('../../services/events');
|
||||
const sqlInit = require('../../services/sql_init.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const ws = require('../../services/ws.js');
|
||||
const sql = require('../../services/sql');
|
||||
const ws = require('../../services/ws');
|
||||
const etapiTokenService = require('../../services/etapi_tokens.js');
|
||||
|
||||
function loginSync(req) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const { JSDOM } = require("jsdom");
|
||||
|
||||
function buildDescendantCountMap(noteIdsToCount) {
|
||||
|
@ -3,13 +3,13 @@
|
||||
const noteService = require('../../services/notes.js');
|
||||
const eraseService = require('../../services/erase.js');
|
||||
const treeService = require('../../services/tree.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const log = require('../../services/log.js');
|
||||
const TaskContext = require('../../services/task_context.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const blobService = require('../../services/blob.js');
|
||||
const sql = require('../../services/sql');
|
||||
const utils = require('../../services/utils');
|
||||
const log = require('../../services/log');
|
||||
const TaskContext = require('../../services/task_context');
|
||||
const becca = require('../../becca/becca');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
const blobService = require('../../services/blob');
|
||||
|
||||
function getNote(req) {
|
||||
return becca.getNoteOrThrow(req.params.noteId);
|
||||
|
@ -1,9 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
const optionService = require('../../services/options.js');
|
||||
const log = require('../../services/log.js');
|
||||
const optionService = require('../../services/options');
|
||||
const log = require('../../services/log');
|
||||
const searchService = require('../../services/search/services/search.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
|
||||
// options allowed to be updated directly in the Options dialog
|
||||
const ALLOWED_OPTIONS = new Set([
|
||||
|
@ -1,4 +1,4 @@
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const markdownService = require('../../services/import/markdown.js');
|
||||
|
||||
function getIconUsage() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const passwordService = require('../../services/encryption/password.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const passwordService = require('../../services/encryption/password');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
|
||||
function changePassword(req) {
|
||||
if (passwordService.isPasswordSet()) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('../../services/sql.js');
|
||||
const protectedSessionService = require('../../services/protected_session.js');
|
||||
const sql = require('../../services/sql');
|
||||
const protectedSessionService = require('../../services/protected_session');
|
||||
const noteService = require('../../services/notes.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
|
||||
function getRecentChanges(req) {
|
||||
const {ancestorNoteId} = req.params;
|
||||
|
@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
const BRecentNote = require('../../becca/entities/brecent_note.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const dateUtils = require('../../services/date_utils.js');
|
||||
const BRecentNote = require('../../becca/entities/brecent_note');
|
||||
const sql = require('../../services/sql');
|
||||
const dateUtils = require('../../services/date_utils');
|
||||
|
||||
function addRecentNote(req) {
|
||||
new BRecentNote({
|
||||
|
@ -1,5 +1,5 @@
|
||||
const becca = require('../../becca/becca.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const sql = require('../../services/sql');
|
||||
|
||||
function getRelationMap(req) {
|
||||
const {relationMapNoteId, noteIds} = req.body;
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
const beccaService = require('../../becca/becca_service.js');
|
||||
const revisionService = require('../../services/revisions.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const cls = require('../../services/cls.js');
|
||||
const utils = require('../../services/utils');
|
||||
const sql = require('../../services/sql');
|
||||
const cls = require('../../services/cls');
|
||||
const path = require('path');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const blobService = require('../../services/blob.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const blobService = require('../../services/blob');
|
||||
const eraseService = require("../../services/erase.js");
|
||||
|
||||
function getRevisionBlob(req) {
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
const scriptService = require('../../services/script.js');
|
||||
const attributeService = require('../../services/attributes.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const syncService = require('../../services/sync.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const sql = require('../../services/sql');
|
||||
|
||||
// The async/await here is very confusing, because the body.script may, but may not be async. If it is async, then we
|
||||
// need to await it and make the complete response including metadata available in a Promise, so that the route detects
|
||||
|
@ -1,12 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const SearchContext = require('../../services/search/search_context.js');
|
||||
const searchService = require('../../services/search/services/search.js');
|
||||
const bulkActionService = require('../../services/bulk_actions.js');
|
||||
const cls = require('../../services/cls.js');
|
||||
const cls = require('../../services/cls');
|
||||
const {formatAttrForSearch} = require('../../services/attribute_formatter.js');
|
||||
const ValidationError = require('../../errors/validation_error.js');
|
||||
const ValidationError = require('../../errors/validation_error');
|
||||
|
||||
function searchFromNote(req) {
|
||||
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||
|
@ -3,7 +3,7 @@
|
||||
const imageType = require('image-type');
|
||||
const imageService = require('../../services/image.js');
|
||||
const noteService = require('../../services/notes.js');
|
||||
const {sanitizeAttributeName} = require('../../services/sanitize_attribute_name.js');
|
||||
const {sanitizeAttributeName} = require('../../services/sanitize_attribute_name');
|
||||
const specialNotesService = require('../../services/special_notes.js');
|
||||
|
||||
function uploadImage(req) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const sqlInit = require('../../services/sql_init.js');
|
||||
const setupService = require('../../services/setup.js');
|
||||
const log = require('../../services/log.js');
|
||||
const log = require('../../services/log');
|
||||
const appInfo = require('../../services/app_info.js');
|
||||
|
||||
function getStatus() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const similarityService = require('../../becca/similarity.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
|
||||
async function getSimilarNotes(req) {
|
||||
const noteId = req.params.noteId;
|
||||
|
@ -1,10 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
const dateNoteService = require('../../services/date_notes.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const cls = require('../../services/cls.js');
|
||||
const sql = require('../../services/sql');
|
||||
const cls = require('../../services/cls');
|
||||
const specialNotesService = require('../../services/special_notes.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const becca = require('../../becca/becca');
|
||||
|
||||
function getInboxNote(req) {
|
||||
return specialNotesService.getInboxNote(req.params.date);
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('../../services/sql.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const sql = require('../../services/sql');
|
||||
const becca = require('../../becca/becca');
|
||||
|
||||
function getSchema() {
|
||||
const tableNames = sql.getColumn(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
|
||||
|
@ -1,5 +1,5 @@
|
||||
const sql = require('../../services/sql.js');
|
||||
const becca = require('../../becca/becca.js');
|
||||
const sql = require('../../services/sql');
|
||||
const becca = require('../../becca/becca');
|
||||
|
||||
function getNoteSize(req) {
|
||||
const {noteId} = req.params;
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
const syncService = require('../../services/sync.js');
|
||||
const syncUpdateService = require('../../services/sync_update.js');
|
||||
const entityChangesService = require('../../services/entity_changes.js');
|
||||
const sql = require('../../services/sql.js');
|
||||
const entityChangesService = require('../../services/entity_changes');
|
||||
const sql = require('../../services/sql');
|
||||
const sqlInit = require('../../services/sql_init.js');
|
||||
const optionService = require('../../services/options.js');
|
||||
const optionService = require('../../services/options');
|
||||
const contentHashService = require('../../services/content_hash.js');
|
||||
const log = require('../../services/log.js');
|
||||
const log = require('../../services/log');
|
||||
const syncOptions = require('../../services/sync_options.js');
|
||||
const utils = require('../../services/utils.js');
|
||||
const ws = require('../../services/ws.js');
|
||||
const utils = require('../../services/utils');
|
||||
const ws = require('../../services/ws');
|
||||
|
||||
async function testSync() {
|
||||
try {
|
||||
|
@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
const becca = require('../../becca/becca.js');
|
||||
const log = require('../../services/log.js');
|
||||
const NotFoundError = require('../../errors/not_found_error.js');
|
||||
const becca = require('../../becca/becca');
|
||||
const log = require('../../services/log');
|
||||
const NotFoundError = require('../../errors/not_found_error');
|
||||
|
||||
function getNotesAndBranchesAndAttributes(noteIds) {
|
||||
noteIds = new Set(noteIds);
|
||||
|
@ -1,7 +1,7 @@
|
||||
const assetPath = require('../services/asset_path.js');
|
||||
const path = require("path");
|
||||
const express = require("express");
|
||||
const env = require('../services/env.js');
|
||||
const env = require('../services/env');
|
||||
|
||||
const persistentCacheStatic = (root, options) => {
|
||||
if (!env.isDev()) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
const log = require('../services/log.js');
|
||||
const log = require('../services/log');
|
||||
const fileService = require('./api/files.js');
|
||||
const scriptService = require('../services/script.js');
|
||||
const cls = require('../services/cls.js');
|
||||
const sql = require('../services/sql.js');
|
||||
const becca = require('../becca/becca.js');
|
||||
const cls = require('../services/cls');
|
||||
const sql = require('../services/sql');
|
||||
const becca = require('../becca/becca');
|
||||
|
||||
function handleRequest(req, res) {
|
||||
// express puts content after first slash into 0 index element
|
||||
|
@ -1,4 +1,4 @@
|
||||
const log = require('../services/log.js');
|
||||
const log = require('../services/log');
|
||||
|
||||
function register(app) {
|
||||
app.use((err, req, res, next) => {
|
||||
|
@ -1,13 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('../services/sql.js');
|
||||
const sql = require('../services/sql');
|
||||
const attributeService = require('../services/attributes.js');
|
||||
const config = require('../services/config.js');
|
||||
const optionService = require('../services/options.js');
|
||||
const log = require('../services/log.js');
|
||||
const env = require('../services/env.js');
|
||||
const utils = require('../services/utils.js');
|
||||
const protectedSessionService = require('../services/protected_session.js');
|
||||
const config = require('../services/config');
|
||||
const optionService = require('../services/options');
|
||||
const log = require('../services/log');
|
||||
const env = require('../services/env');
|
||||
const utils = require('../services/utils');
|
||||
const protectedSessionService = require('../services/protected_session');
|
||||
const packageJson = require('../../package.json');
|
||||
const assetPath = require('../services/asset_path.js');
|
||||
const appPath = require('../services/app_path.js');
|
||||
|
@ -1,13 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
const utils = require('../services/utils.js');
|
||||
const optionService = require('../services/options.js');
|
||||
const myScryptService = require('../services/encryption/my_scrypt.js');
|
||||
const log = require('../services/log.js');
|
||||
const passwordService = require('../services/encryption/password.js');
|
||||
const utils = require('../services/utils');
|
||||
const optionService = require('../services/options');
|
||||
const myScryptService = require('../services/encryption/my_scrypt');
|
||||
const log = require('../services/log');
|
||||
const passwordService = require('../services/encryption/password');
|
||||
const assetPath = require('../services/asset_path.js');
|
||||
const appPath = require('../services/app_path.js');
|
||||
const ValidationError = require('../errors/validation_error.js');
|
||||
const ValidationError = require('../errors/validation_error');
|
||||
|
||||
function loginPage(req, res) {
|
||||
res.render('login', {
|
||||
|
@ -1,20 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
const utils = require('../services/utils.js');
|
||||
const utils = require('../services/utils');
|
||||
const multer = require('multer');
|
||||
const log = require('../services/log.js');
|
||||
const log = require('../services/log');
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const auth = require('../services/auth.js');
|
||||
const cls = require('../services/cls.js');
|
||||
const sql = require('../services/sql.js');
|
||||
const entityChangesService = require('../services/entity_changes.js');
|
||||
const cls = require('../services/cls');
|
||||
const sql = require('../services/sql');
|
||||
const entityChangesService = require('../services/entity_changes');
|
||||
const csurf = require('csurf');
|
||||
const { createPartialContentHandler } = require("express-partial-content");
|
||||
const rateLimit = require("express-rate-limit");
|
||||
const AbstractBeccaEntity = require('../becca/entities/abstract_becca_entity.js');
|
||||
const NotFoundError = require('../errors/not_found_error.js');
|
||||
const ValidationError = require('../errors/validation_error.js');
|
||||
const AbstractBeccaEntity = require('../becca/entities/abstract_becca_entity');
|
||||
const NotFoundError = require('../errors/not_found_error');
|
||||
const ValidationError = require('../errors/validation_error');
|
||||
|
||||
// page routes
|
||||
const setupRoute = require('./setup.js');
|
||||
@ -31,7 +31,7 @@ const cloningApiRoute = require('./api/cloning.js');
|
||||
const revisionsApiRoute = require('./api/revisions.js');
|
||||
const recentChangesApiRoute = require('./api/recent_changes.js');
|
||||
const optionsApiRoute = require('./api/options.js');
|
||||
const passwordApiRoute = require('./api/password.js');
|
||||
const passwordApiRoute = require('./api/password');
|
||||
const syncApiRoute = require('./api/sync.js');
|
||||
const loginApiRoute = require('./api/login.js');
|
||||
const recentNotesRoute = require('./api/recent_notes.js');
|
||||
@ -39,7 +39,7 @@ const appInfoRoute = require('./api/app_info.js');
|
||||
const exportRoute = require('./api/export.js');
|
||||
const importRoute = require('./api/import.js');
|
||||
const setupApiRoute = require('./api/setup.js');
|
||||
const sqlRoute = require('./api/sql.js');
|
||||
const sqlRoute = require('./api/sql');
|
||||
const databaseRoute = require('./api/database.js');
|
||||
const imageRoute = require('./api/image.js');
|
||||
const attributesRoute = require('./api/attributes.js');
|
||||
|
@ -1,6 +1,6 @@
|
||||
const session = require("express-session");
|
||||
const sessionSecret = require('../services/session_secret.js');
|
||||
const dataDir = require('../services/data_dir.js');
|
||||
const dataDir = require('../services/data_dir');
|
||||
const FileStore = require('session-file-store')(session);
|
||||
|
||||
const sessionParser = session({
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const sqlInit = require('../services/sql_init.js');
|
||||
const setupService = require('../services/setup.js');
|
||||
const utils = require('../services/utils.js');
|
||||
const utils = require('../services/utils');
|
||||
const assetPath = require('../services/asset_path.js');
|
||||
const appPath = require('../services/app_path.js');
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
const BUILTIN_ATTRIBUTES = require('./builtin_attributes.js');
|
||||
const fs = require("fs-extra");
|
||||
const dataDir = require('./data_dir.js');
|
||||
const dateUtils = require('./date_utils.js');
|
||||
const dataDir = require('./data_dir');
|
||||
const dateUtils = require('./date_utils');
|
||||
const Database = require("better-sqlite3");
|
||||
const sql = require('./sql.js');
|
||||
const sql = require('./sql');
|
||||
const path = require("path");
|
||||
|
||||
function getFullAnonymizationScript() {
|
||||
|
@ -1,12 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
const path = require('path');
|
||||
const {ELECTRON_APP_ROOT_DIR} = require('./resource_dir.js');
|
||||
const log = require('./log.js');
|
||||
const {ELECTRON_APP_ROOT_DIR} = require('./resource_dir');
|
||||
const log = require('./log');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const config = require('./config.js');
|
||||
const utils = require('./utils.js');
|
||||
const config = require('./config');
|
||||
const utils = require('./utils');
|
||||
|
||||
const template = `[Desktop Entry]
|
||||
Type=Application
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const build = require('./build.js');
|
||||
const packageJson = require('../../package.json');
|
||||
const {TRILIUM_DATA_DIR} = require('./data_dir.js');
|
||||
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
||||
|
||||
const APP_DB_VERSION = 228;
|
||||
const SYNC_VERSION = 32;
|
||||
|
@ -1,5 +1,5 @@
|
||||
const assetPath = require('./asset_path.js');
|
||||
const env = require('./env.js');
|
||||
const env = require('./env');
|
||||
|
||||
module.exports = env.isDev()
|
||||
? assetPath + "/app"
|
||||
|
@ -1,9 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
const searchService = require('./search/services/search.js');
|
||||
const sql = require('./sql.js');
|
||||
const becca = require('../becca/becca.js');
|
||||
const BAttribute = require('../becca/entities/battribute.js');
|
||||
const sql = require('./sql');
|
||||
const becca = require('../becca/becca');
|
||||
const BAttribute = require('../becca/entities/battribute');
|
||||
const {formatAttrForSearch} = require('./attribute_formatter.js');
|
||||
const BUILTIN_ATTRIBUTES = require('./builtin_attributes.js');
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
const etapiTokenService = require('./etapi_tokens.js');
|
||||
const log = require('./log.js');
|
||||
const log = require('./log');
|
||||
const sqlInit = require('./sql_init.js');
|
||||
const utils = require('./utils.js');
|
||||
const passwordEncryptionService = require('./encryption/password_encryption.js');
|
||||
const config = require('./config.js');
|
||||
const passwordService = require('./encryption/password.js');
|
||||
const utils = require('./utils');
|
||||
const passwordEncryptionService = require('./encryption/password_encryption');
|
||||
const config = require('./config');
|
||||
const passwordService = require('./encryption/password');
|
||||
|
||||
const noAuthentication = config.General && config.General.noAuthentication === true;
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
const log = require('./log.js');
|
||||
const log = require('./log');
|
||||
const noteService = require('./notes.js');
|
||||
const sql = require('./sql.js');
|
||||
const utils = require('./utils.js');
|
||||
const sql = require('./sql');
|
||||
const utils = require('./utils');
|
||||
const attributeService = require('./attributes.js');
|
||||
const dateNoteService = require('./date_notes.js');
|
||||
const treeService = require('./tree.js');
|
||||
const config = require('./config.js');
|
||||
const config = require('./config');
|
||||
const axios = require('axios');
|
||||
const dayjs = require('dayjs');
|
||||
const xml2js = require('xml2js');
|
||||
@ -13,15 +13,15 @@ const cloningService = require('./cloning.js');
|
||||
const appInfo = require('./app_info.js');
|
||||
const searchService = require('./search/services/search.js');
|
||||
const SearchContext = require('./search/search_context.js');
|
||||
const becca = require('../becca/becca.js');
|
||||
const ws = require('./ws.js');
|
||||
const becca = require('../becca/becca');
|
||||
const ws = require('./ws');
|
||||
const SpacedUpdate = require('./spaced_update.js');
|
||||
const specialNotesService = require('./special_notes.js');
|
||||
const branchService = require('./branches.js');
|
||||
const exportService = require('./export/zip.js');
|
||||
const syncMutex = require('./sync_mutex.js');
|
||||
const syncMutex = require('./sync_mutex');
|
||||
const backupService = require('./backup.js');
|
||||
const optionsService = require('./options.js');
|
||||
const optionsService = require('./options');
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1,13 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
const dateUtils = require('./date_utils.js');
|
||||
const optionService = require('./options.js');
|
||||
const dateUtils = require('./date_utils');
|
||||
const optionService = require('./options');
|
||||
const fs = require('fs-extra');
|
||||
const dataDir = require('./data_dir.js');
|
||||
const log = require('./log.js');
|
||||
const syncMutexService = require('./sync_mutex.js');
|
||||
const cls = require('./cls.js');
|
||||
const sql = require('./sql.js');
|
||||
const dataDir = require('./data_dir');
|
||||
const log = require('./log');
|
||||
const syncMutexService = require('./sync_mutex');
|
||||
const cls = require('./cls');
|
||||
const sql = require('./sql');
|
||||
const path = require('path');
|
||||
|
||||
function getExistingBackups() {
|
||||
|
5
src/services/blob-interface.ts
Normal file
5
src/services/blob-interface.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface Blob {
|
||||
blobId: string;
|
||||
content: string | Buffer;
|
||||
utcDateModified: string;
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
const becca = require('../becca/becca.js');
|
||||
const NotFoundError = require('../errors/not_found_error.js');
|
||||
const protectedSessionService = require('./protected_session.js');
|
||||
const utils = require('./utils.js');
|
||||
import becca = require('../becca/becca');
|
||||
import NotFoundError = require('../errors/not_found_error');
|
||||
import protectedSessionService = require('./protected_session');
|
||||
import utils = require('./utils');
|
||||
import type { Blob } from "./blob-interface";
|
||||
|
||||
function getBlobPojo(entityName, entityId) {
|
||||
function getBlobPojo(entityName: string, entityId: string) {
|
||||
const entity = becca.getEntity(entityName, entityId);
|
||||
if (!entity) {
|
||||
throw new NotFoundError(`Entity ${entityName} '${entityId}' was not found.`);
|
||||
@ -19,13 +20,13 @@ function getBlobPojo(entityName, entityId) {
|
||||
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;
|
||||
}
|
||||
|
||||
function processContent(content, isProtected, isStringContent) {
|
||||
function processContent(content: Buffer | string | null, isProtected: boolean, isStringContent: boolean) {
|
||||
if (isProtected) {
|
||||
if (protectedSessionService.isProtectedSessionAvailable()) {
|
||||
content = content === null ? null : protectedSessionService.decrypt(content);
|
||||
@ -48,11 +49,11 @@ function processContent(content, isProtected, isStringContent) {
|
||||
}
|
||||
}
|
||||
|
||||
function calculateContentHash({blobId, content}) {
|
||||
function calculateContentHash({blobId, content}: Blob) {
|
||||
return utils.hash(`${blobId}|${content.toString()}`);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export = {
|
||||
getBlobPojo,
|
||||
processContent,
|
||||
calculateContentHash
|
@ -1,5 +1,5 @@
|
||||
const treeService = require('./tree.js');
|
||||
const sql = require('./sql.js');
|
||||
const sql = require('./sql');
|
||||
|
||||
function moveBranchToNote(branchToMove, targetParentNoteId) {
|
||||
if (branchToMove.parentNoteId === targetParentNoteId) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
const log = require('./log.js');
|
||||
const log = require('./log');
|
||||
const revisionService = require('./revisions.js');
|
||||
const becca = require('../becca/becca.js');
|
||||
const becca = require('../becca/becca');
|
||||
const cloningService = require('./cloning.js');
|
||||
const branchService = require('./branches.js');
|
||||
const utils = require('./utils.js');
|
||||
const utils = require('./utils');
|
||||
const eraseService = require("./erase.js");
|
||||
|
||||
const ACTION_HANDLERS = {
|
||||
|
@ -1,11 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('./sql.js');
|
||||
const eventChangesService = require('./entity_changes.js');
|
||||
const sql = require('./sql');
|
||||
const eventChangesService = require('./entity_changes');
|
||||
const treeService = require('./tree.js');
|
||||
const BBranch = require('../becca/entities/bbranch.js');
|
||||
const becca = require('../becca/becca.js');
|
||||
const log = require('./log.js');
|
||||
const BBranch = require('../becca/entities/bbranch');
|
||||
const becca = require('../becca/becca');
|
||||
const log = require('./log');
|
||||
|
||||
function cloneNoteToParentNote(noteId, parentNoteId, prefix = null) {
|
||||
if (!(noteId in becca.notes) || !(parentNoteId in becca.notes)) {
|
||||
|
@ -1,26 +1,29 @@
|
||||
const clsHooked = require('cls-hooked');
|
||||
import clsHooked = require('cls-hooked');
|
||||
import { EntityChange } from './entity_changes_interface';
|
||||
const namespace = clsHooked.createNamespace("trilium");
|
||||
|
||||
function init(callback) {
|
||||
type Callback = (...args: any[]) => any;
|
||||
|
||||
function init(callback: Callback) {
|
||||
return namespace.runAndReturn(callback);
|
||||
}
|
||||
|
||||
function wrap(callback) {
|
||||
function wrap(callback: Callback) {
|
||||
return () => {
|
||||
try {
|
||||
init(callback);
|
||||
}
|
||||
catch (e) {
|
||||
catch (e: any) {
|
||||
console.log(`Error occurred: ${e.message}: ${e.stack}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function get(key) {
|
||||
function get(key: string) {
|
||||
return namespace.get(key);
|
||||
}
|
||||
|
||||
function set(key, value) {
|
||||
function set(key: string, value: any) {
|
||||
namespace.set(key, value);
|
||||
}
|
||||
|
||||
@ -48,7 +51,7 @@ function isEntityEventsDisabled() {
|
||||
return !!namespace.get('disableEntityEvents');
|
||||
}
|
||||
|
||||
function setMigrationRunning(running) {
|
||||
function setMigrationRunning(running: boolean) {
|
||||
namespace.set('migrationRunning', !!running);
|
||||
}
|
||||
|
||||
@ -56,7 +59,7 @@ function isMigrationRunning() {
|
||||
return !!namespace.get('migrationRunning');
|
||||
}
|
||||
|
||||
function disableSlowQueryLogging(disable) {
|
||||
function disableSlowQueryLogging(disable: boolean) {
|
||||
namespace.set('disableSlowQueryLogging', disable);
|
||||
}
|
||||
|
||||
@ -72,7 +75,7 @@ function getAndClearEntityChangeIds() {
|
||||
return entityChangeIds;
|
||||
}
|
||||
|
||||
function putEntityChange(entityChange) {
|
||||
function putEntityChange(entityChange: EntityChange) {
|
||||
if (namespace.get('ignoreEntityChangeIds')) {
|
||||
return;
|
||||
}
|
||||
@ -93,7 +96,7 @@ function ignoreEntityChangeIds() {
|
||||
namespace.set('ignoreEntityChangeIds', true);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export = {
|
||||
init,
|
||||
wrap,
|
||||
get,
|
@ -1,10 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
const ini = require('ini');
|
||||
const fs = require('fs');
|
||||
const dataDir = require('./data_dir.js');
|
||||
const path = require('path');
|
||||
const resourceDir = require('./resource_dir.js');
|
||||
import ini = require('ini');
|
||||
import fs = require('fs');
|
||||
import dataDir = require('./data_dir');
|
||||
import path = require('path');
|
||||
import resourceDir = require('./resource_dir');
|
||||
|
||||
const configSampleFilePath = path.resolve(resourceDir.RESOURCE_DIR, "config-sample.ini");
|
||||
|
||||
@ -16,4 +16,4 @@ if (!fs.existsSync(dataDir.CONFIG_INI_PATH)) {
|
||||
|
||||
const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, 'utf-8'));
|
||||
|
||||
module.exports = config;
|
||||
export = config;
|
@ -1,19 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
const sql = require('./sql.js');
|
||||
const sql = require('./sql');
|
||||
const sqlInit = require('./sql_init.js');
|
||||
const log = require('./log.js');
|
||||
const ws = require('./ws.js');
|
||||
const syncMutexService = require('./sync_mutex.js');
|
||||
const cls = require('./cls.js');
|
||||
const entityChangesService = require('./entity_changes.js');
|
||||
const optionsService = require('./options.js');
|
||||
const BBranch = require('../becca/entities/bbranch.js');
|
||||
const log = require('./log');
|
||||
const ws = require('./ws');
|
||||
const syncMutexService = require('./sync_mutex');
|
||||
const cls = require('./cls');
|
||||
const entityChangesService = require('./entity_changes');
|
||||
const optionsService = require('./options');
|
||||
const BBranch = require('../becca/entities/bbranch');
|
||||
const revisionService = require('./revisions.js');
|
||||
const becca = require('../becca/becca.js');
|
||||
const utils = require('../services/utils.js');
|
||||
const becca = require('../becca/becca');
|
||||
const utils = require('../services/utils');
|
||||
const eraseService = require('../services/erase.js');
|
||||
const {sanitizeAttributeName} = require('./sanitize_attribute_name.js');
|
||||
const {sanitizeAttributeName} = require('./sanitize_attribute_name');
|
||||
const noteTypes = require('../services/note_types.js').getNoteTypeNames();
|
||||
|
||||
class ConsistencyChecks {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user