Compare commits
499 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b811f3d399 | |||
| bbbbc3b860 | |||
| c9f27547a2 | |||
| 6bf063b92f | |||
| 590442b0d5 | |||
| 4862b324a5 | |||
| f678c4337b | |||
| 686b9c840e | |||
| 2e8b2d4b81 | |||
| 3d423d25f8 | |||
| 79123b0c63 | |||
| 595402adea | |||
| f40257b591 | |||
| b6ca2281f7 | |||
| 186650b1cf | |||
| 1dad4bc80f | |||
| d66a70f099 | |||
| 0792714e45 | |||
| 6ecbf1c528 | |||
| 5460359753 | |||
| 75ebe24abb | |||
| 3f5e5fd840 | |||
| 998db5ce95 | |||
| 7aed6d4ad4 | |||
| 99ea741275 | |||
| e6ff99198f | |||
| 7c43a49046 | |||
| 5b30bae5b2 | |||
| 947aaa6156 | |||
| 534fe87fb1 | |||
| 1652a7a2ec | |||
| 7184c648ab | |||
| be239d2230 | |||
| 439bf410ac | |||
| 5aadcb69f8 | |||
| 543c29e539 | |||
| 8bcff49198 | |||
| c0cc1e3b52 | |||
| 19550eec6a | |||
| 45f2691053 | |||
| ba2931b854 | |||
| d5c1bd1085 | |||
| 606490a611 | |||
| d99cc11d8b | |||
| 1b0690ddfc | |||
| ef92d17272 | |||
| 7fd63e8064 | |||
| d18bfb9d69 | |||
| 60d134a89b | |||
| 9b88228be9 | |||
| 0a7fcf399f | |||
| 408369fcac | |||
| c435b97e10 | |||
| e7c3dab56f | |||
| 374b1f9bb2 | |||
| 5f23a4e3c7 | |||
| 4e93209fbd | |||
| 1cff016923 | |||
| a80a857e46 | |||
| 47c5f60a85 | |||
| ec2e6f2507 | |||
| 8eb1e803b5 | |||
| 44ad22ceea | |||
| 40dfc46250 | |||
| 9775a8b7c5 | |||
| 82a437f2a8 | |||
| a64a0e52ec | |||
| 88c4171031 | |||
| b6c7e2e48f | |||
| 305d28b5b3 | |||
| a88bf68eb6 | |||
| 8ebebecd93 | |||
| f0d30dbe49 | |||
| d142d3261d | |||
| 25b49e1ca2 | |||
| c7f19e04fa | |||
| a2711cfb7b | |||
| ade6d08ded | |||
| 045f318612 | |||
| 2d67abbc12 | |||
| 5f539427a9 | |||
| f984b361ee | |||
| 3e82d30a32 | |||
| d2604e91d4 | |||
| e2b4eaf9cc | |||
| 0a69ed91b6 | |||
| 8c0ce174b5 | |||
| c8adf2a685 | |||
| a68b75f069 | |||
| 2771bd4ece | |||
| 19cf9df52c | |||
| 15168fb213 | |||
| 0d700d6951 | |||
| 67cb02ed92 | |||
| 1d1ccc8d63 | |||
| 262e4db0f2 | |||
| c814187a25 | |||
| 138be84e45 | |||
| 625d935f08 | |||
| 98d12901a5 | |||
| 1372cc1cb9 | |||
| a072016fc5 | |||
| 97230ca82a | |||
| 4c69384b5d | |||
| 6ac3c172b1 | |||
| a66e4435ba | |||
| ae29699e65 | |||
| 9022bc338a | |||
| dededcd303 | |||
| 4638351ec8 | |||
| 1ac65fff47 | |||
| 17eda952e4 | |||
| 8629993fe4 | |||
| 8297e1a835 | |||
| b517b18394 | |||
| 32e34eec90 | |||
| fb32ab9707 | |||
| 8acfb5b558 | |||
| a7ae16bb39 | |||
| c08393f04b | |||
| 88aba1c844 | |||
| 7c76d28f75 | |||
| b3c2602620 | |||
| 0865e90cae | |||
| e1d74cd2f5 | |||
| c4c2259e69 | |||
| 3e4b0d5f91 | |||
| b07df6061f | |||
| 80a1b8b44d | |||
| 45e3632c6e | |||
| 39e152b0b9 | |||
| 2a99ecc384 | |||
| 22477f90ae | |||
| d8c2ba0ed8 | |||
| 74441273a8 | |||
| ed79c1c62a | |||
| 9b9b452055 | |||
| 5fdf094e9d | |||
| e4024408bd | |||
| 602b4988ae | |||
| 071f9400d7 | |||
| 1e2a30adcc | |||
| a6de065bf4 | |||
| 3bd7231ba9 | |||
| 4bb46aeb9c | |||
| 26859e83e4 | |||
| 569bdf19be | |||
| b8eb301f34 | |||
| 10c21d3403 | |||
| a18b054dbb | |||
| 2e906af77d | |||
| 34cd2eba91 | |||
| 7fe6d1ab4d | |||
| c2eefad287 | |||
| 202fda3c30 | |||
| 4940207b15 | |||
| 79c9d7e305 | |||
| 6e042c20e9 | |||
| 7a98718e64 | |||
| 6bbb1f8404 | |||
| cecfc4cd34 | |||
| c1875a8c8f | |||
| 249e81c9eb | |||
| 5804dc52bc | |||
| 90cf913083 | |||
| fa82158e30 | |||
| de42df40bb | |||
| 6265aa99d3 | |||
| 4ab6f159e5 | |||
| b50ceaf299 | |||
| 96c8c9080d | |||
| 66d7548046 | |||
| 4b1c351195 | |||
| eb7a7e4988 | |||
| 3d75366f02 | |||
| c63c7d518c | |||
| 37697c7db7 | |||
| b1744c3867 | |||
| b0d6035a67 | |||
| 3902719008 | |||
| 291b791b67 | |||
| b552f40ae8 | |||
| 0ab137de03 | |||
| 952c3cc12f | |||
| e451237361 | |||
| 27637b0483 | |||
| 122ff3bb1d | |||
| f98f84d419 | |||
| 40ef533c5f | |||
| fd77c5e8c4 | |||
| 706b9d0f46 | |||
| 82f5553980 | |||
| c0349b3f84 | |||
| 9330241045 | |||
| b13ad5d01e | |||
| ea36b37f66 | |||
| 92ca32bd70 | |||
| 59c533cb6c | |||
| 884b6618fb | |||
| 15dee4b952 | |||
| a154dc76ce | |||
| 532ed1d3f9 | |||
| 984ce49168 | |||
| 16283d4054 | |||
| 915de23e34 | |||
| 53d4873c1f | |||
| 764d251b0a | |||
| aa233b8adb | |||
| ed47c23e23 | |||
| 5baabecdee | |||
| 17c7e2d8e7 | |||
| 5d452a1525 | |||
| f857b8a9bb | |||
| a354b54a08 | |||
| e96b56e061 | |||
| 0daa4cc89a | |||
| 99d50957dd | |||
| d4c8d24d50 | |||
| a420129631 | |||
| 090d353fd0 | |||
| b84b27692c | |||
| adc384a971 | |||
| 08f0c01eef | |||
| db2b33704f | |||
| 3eb7ed5dda | |||
| 5e5add7e47 | |||
| ac1e1ebe43 | |||
| 499bfaea9b | |||
| fa4772b91e | |||
| fa7b190c6b | |||
| 84feec2e7e | |||
| 3035473751 | |||
| 399458b52f | |||
| becac5fbad | |||
| 1e26b31090 | |||
| 0ebd03869d | |||
| a4a713f102 | |||
| 83d5d6bbd8 | |||
| 90f4c6b0d1 | |||
| 926b3e9650 | |||
| cbad58201e | |||
| 040ed39a4e | |||
| 9f6a8dc75c | |||
| bfb8aa6481 | |||
| 2bb4cccd82 | |||
| 6fad5f2b51 | |||
| 36357bdf86 | |||
| 80eaf10656 | |||
| f46ce0417d | |||
| 6f1e6402f0 | |||
| bdfa13a8a0 | |||
| d5622dfbf7 | |||
| 0948853539 | |||
| 0ad337c8e8 | |||
| 9565b0b43d | |||
| a115b14136 | |||
| bb8bfc61ed | |||
| 2d19f073d9 | |||
| ff5d5d20d9 | |||
| 8c5f680dca | |||
| 7f0102181d | |||
| 59d618f06b | |||
| cc1a545e13 | |||
| fd37fd3a45 | |||
| 052a0a44f2 | |||
| fa0ed35752 | |||
| 29d37c40c1 | |||
| 1728365fa1 | |||
| cfeb0cc6f7 | |||
| ec4bd6659a | |||
| 0903cf2646 | |||
| cbc01e1a8d | |||
| 11c7533984 | |||
| aff1c30557 | |||
| 3d9da26bb3 | |||
| 91ddabbb9b | |||
| 3030fbe60b | |||
| 5f4f30f84b | |||
| 45cb7ced2c | |||
| dbccf6b433 | |||
| 6df09cb157 | |||
| 6cedad07e5 | |||
| e4556afcc9 | |||
| d89b791914 | |||
| 43c89c0e9d | |||
| 0ba80b176c | |||
| 3ea4b7a72b | |||
| 330334dcb4 | |||
| ddcbb29a67 | |||
| 9ea4fcd667 | |||
| 0d4fb42731 | |||
| d8d729342d | |||
| 2fbd2e3c29 | |||
| 15169289f0 | |||
| 29b3fb3646 | |||
| 533a597a5c | |||
| deed58c2fc | |||
| 8acb64198c | |||
| f5b690d088 | |||
| 0f7f0ceedc | |||
| 87708aa9c3 | |||
| c63d05b582 | |||
| 460982d290 | |||
| 414964e791 | |||
| 3df6acda32 | |||
| 571c9f544c | |||
| acb31b621f | |||
| 35886c3b00 | |||
| ccc51e0123 | |||
| 0df488667e | |||
| 7018cc77a3 | |||
| 8d2eddd14d | |||
| 414515bc87 | |||
| ce60fc0c3a | |||
| 216f3f2c07 | |||
| 80e6ced5db | |||
| fbf77f3382 | |||
| 1010d11827 | |||
| 1f95e88cfd | |||
| 5d683721b1 | |||
| de7f4de05b | |||
| 669988953d | |||
| dc22d05657 | |||
| 00c692cf28 | |||
| 77fb7bc6e8 | |||
| f31d788e2e | |||
| 45582ebaac | |||
| 748a551def | |||
| d35613f510 | |||
| 3d5ef81860 | |||
| 9f99b4282a | |||
| 3b7812f829 | |||
| 1c7532df46 | |||
| a029ee268a | |||
| 1b58dbe401 | |||
| 56ca0ea5d0 | |||
| 246a90d73c | |||
| a58abffe58 | |||
| 8936a3fa3b | |||
| 6b8ee084e6 | |||
| 5916a8b5b8 | |||
| a183f21078 | |||
| 9826fed905 | |||
| a06aa9df8a | |||
| 1e91db865b | |||
| 8af5434462 | |||
| 6f0659c03c | |||
| b8ccf5ba8f | |||
| 45a6c9558f | |||
| 4df599fec2 | |||
| 030aec2f3e | |||
| 8b250e4a13 | |||
| 2f96dc2d9d | |||
| 26388ad3b6 | |||
| 2c0063a5cc | |||
| 3a20bef1a9 | |||
| 9aec3390dd | |||
| f9ba8ca87d | |||
| f51f070b2f | |||
| cf18e61a33 | |||
| 4b1d2c6bad | |||
| 06287da9d8 | |||
| eef8297ce1 | |||
| 2f15d79476 | |||
| 768aaf2d78 | |||
| 6dd2cd39aa | |||
| e04bd5aaf0 | |||
| cb14d4d8f9 | |||
| 85af0a24ee | |||
| 3a7d0d1f13 | |||
| 5309d4ad5c | |||
| 786d851293 | |||
| b63e870038 | |||
| c20d2273e6 | |||
| dc359b2a74 | |||
| d3c9e7e157 | |||
| 82a9808dea | |||
| e2a727ec8a | |||
| 7a9365457a | |||
| 28735fa16a | |||
| ff2e05fe83 | |||
| 96b6d17d77 | |||
| 78f631373b | |||
| 981221d599 | |||
| bda11fad40 | |||
| 39627a4fc4 | |||
| 094895ec72 | |||
| 15677f7178 | |||
| 3a0bb91b77 | |||
| 157f894c9b | |||
| e6dec701c0 | |||
| 450b52f6da | |||
| 4ef31eaf3d | |||
| 2d865576cf | |||
| 41e623b009 | |||
| 239786e7d1 | |||
| 89e1e47900 | |||
| 67cb926233 | |||
| 2f813dfc5d | |||
| a939599223 | |||
| fb10e0ad33 | |||
| 46bd5bc1ef | |||
| 5abfb5c08a | |||
| 9357caeb5a | |||
| 6b58e59819 | |||
| c6df25ece8 | |||
| ebd6276b5e | |||
| 92e8b155e4 | |||
| e76093e75c | |||
| 4f8073daa7 | |||
| 47fb96faa8 | |||
| 6e33553146 | |||
| 807941e6a5 | |||
| 1e30c0702e | |||
| 69b686ba3b | |||
| ace5660809 | |||
| 8bc99fd799 | |||
| f0c3a090a2 | |||
| 17e063f01d | |||
| 76c9873705 | |||
| 2c7b774356 | |||
| 390ad6d813 | |||
| 77800d073f | |||
| 1953c7896f | |||
| dff4f73366 | |||
| cd43752f61 | |||
| 23a5cea338 | |||
| e2cb3c0d14 | |||
| d6046efa1b | |||
| ee608fcf46 | |||
| 894b08a1b8 | |||
| 4e549baedc | |||
| 6b6e42e9ba | |||
| 0404b78fb8 | |||
| d63d42d87c | |||
| 37baa4cd74 | |||
| 68e03c434e | |||
| 394530921e | |||
| 57ccd5a954 | |||
| a28d8843ac | |||
| cb523faaad | |||
| f704cacdee | |||
| 8dbc592563 | |||
| 439743d2b0 | |||
| a3783131a2 | |||
| 8199073342 | |||
| 33af9a3595 | |||
| 30c3c10524 | |||
| df85a5eee4 | |||
| 0ac397e7ff | |||
| d243880099 | |||
| 2e23c521c3 | |||
| eb761b286f | |||
| d0f6ff5f98 | |||
| c35167f2f5 | |||
| 84feaabc52 | |||
| a6036859b8 | |||
| 929f7f3114 | |||
| 9e914b9016 | |||
| 947627d8a0 | |||
| ed00797179 | |||
| 93dcce2217 | |||
| 686af0c6a1 | |||
| d07f02b95f | |||
| ad74952194 | |||
| 10f3df3ed4 | |||
| 18e2e6779b | |||
| ed129c307b | |||
| 8742e4bfe9 | |||
| 3b10bb742b | |||
| 1f206a9c24 | |||
| f026646bb5 | |||
| f9bfc8ad86 | |||
| e70539ff48 | |||
| a439be79b3 | |||
| edf2dfe8f9 | |||
| 0e4c49ea5b | |||
| 52cfd138d1 | |||
| 258b97f833 | |||
| 837b17d62a | |||
| d82720f62f | |||
| cf99345962 | |||
| 9e54496d00 | |||
| 8ae6598b8a | |||
| 722299dd26 | |||
| e2b1421bf3 | |||
| 1f41d39bc7 | |||
| ce39d3b4ce | |||
| ef2ade849b | |||
| 88067c071c | |||
| f5018e9820 | |||
| 1561f402f0 | |||
| 0d7889d212 | |||
| 19a10e59e9 | |||
| 746abb02d3 | |||
| 23351298c8 | |||
| 426a8f75aa | |||
| 999cf0d9e3 | |||
| 0afc41060a |
@@ -5,3 +5,6 @@
|
||||
/docs
|
||||
/npm-debug.log
|
||||
node_modules
|
||||
|
||||
src/**/*.ts
|
||||
!src/services/asset_path.ts
|
||||
@@ -1,7 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
bin
|
||||
docs
|
||||
libraries
|
||||
coverage
|
||||
play
|
||||
-212
@@ -1,212 +0,0 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
commonjs: true,
|
||||
es2021: true,
|
||||
node: true,
|
||||
},
|
||||
// plugins: ['prettier'], // to be activated
|
||||
extends: ['eslint:recommended', 'airbnb-base', 'plugin:jsonc/recommended-with-jsonc', 'prettier'],
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.json', '*.json5', '*.jsonc'],
|
||||
parser: 'jsonc-eslint-parser',
|
||||
},
|
||||
{
|
||||
files: ['package.json'],
|
||||
parser: 'jsonc-eslint-parser',
|
||||
rules: {
|
||||
'jsonc/sort-keys': [
|
||||
'off',
|
||||
{
|
||||
pathPattern: '^$',
|
||||
order: [
|
||||
'name',
|
||||
'version',
|
||||
'private',
|
||||
'packageManager',
|
||||
'description',
|
||||
'type',
|
||||
'keywords',
|
||||
'homepage',
|
||||
'bugs',
|
||||
'license',
|
||||
'author',
|
||||
'contributors',
|
||||
'funding',
|
||||
'files',
|
||||
'main',
|
||||
'module',
|
||||
'exports',
|
||||
'unpkg',
|
||||
'jsdelivr',
|
||||
'browser',
|
||||
'bin',
|
||||
'man',
|
||||
'directories',
|
||||
'repository',
|
||||
'publishConfig',
|
||||
'scripts',
|
||||
'peerDependencies',
|
||||
'peerDependenciesMeta',
|
||||
'optionalDependencies',
|
||||
'dependencies',
|
||||
'devDependencies',
|
||||
'engines',
|
||||
'config',
|
||||
'overrides',
|
||||
'pnpm',
|
||||
'husky',
|
||||
'lint-staged',
|
||||
'eslintConfig',
|
||||
],
|
||||
},
|
||||
{
|
||||
pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies$',
|
||||
order: { type: 'asc' },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
globals: {
|
||||
$: true,
|
||||
jQuery: true,
|
||||
glob: true,
|
||||
log: true,
|
||||
EditorWatchdog: true,
|
||||
React: true,
|
||||
appState: true,
|
||||
ExcalidrawLib: true,
|
||||
elements: true,
|
||||
files: true,
|
||||
ReactDOM: true,
|
||||
// src\public\app\widgets\type_widgets\relation_map.js
|
||||
jsPlumb: true,
|
||||
panzoom: true,
|
||||
logError: true,
|
||||
// src\public\app\widgets\type_widgets\image.js
|
||||
WZoom: true,
|
||||
// \src\public\app\widgets\type_widgets\read_only_text.js
|
||||
renderMathInElement: true,
|
||||
// \src\public\app\widgets\type_widgets\editable_text.js
|
||||
BalloonEditor: true,
|
||||
FancytreeNode: true,
|
||||
CKEditorInspector: true,
|
||||
// \src\public\app\widgets\type_widgets\editable_code.js
|
||||
CodeMirror: true,
|
||||
// \src\public\app\services\resizer.js
|
||||
Split: true,
|
||||
// \src\public\app\services\content_renderer.js
|
||||
mermaid: true,
|
||||
// src\public\app\services\frontend_script_api.js
|
||||
dayjs: true,
|
||||
// \src\public\app\widgets\note_map.js
|
||||
ForceGraph: true,
|
||||
// \src\public\app\setup.js
|
||||
ko: true,
|
||||
syncInProgress: true,
|
||||
// src\public\app\services\utils.js
|
||||
logInfo: true,
|
||||
__non_webpack_require__: true,
|
||||
describe: true,
|
||||
it: true,
|
||||
expect: true
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
// eslint:recommended
|
||||
'no-unused-vars': 'off',
|
||||
'linebreak-style': 'off',
|
||||
'no-useless-escape': 'off',
|
||||
'no-empty': 'off',
|
||||
'no-constant-condition': 'off',
|
||||
'getter-return': 'off',
|
||||
'no-cond-assign': 'off',
|
||||
'no-async-promise-executor': 'off',
|
||||
'no-extra-semi': 'off',
|
||||
'no-inner-declarations': 'off',
|
||||
|
||||
// prettier
|
||||
'prettier/prettier': ['off', { endOfLine: 'auto' }],
|
||||
|
||||
// airbnb-base
|
||||
'no-console': 'off',
|
||||
'no-plusplus': 'off',
|
||||
'no-param-reassign': 'off',
|
||||
'global-require': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
'no-await-in-loop': 'off',
|
||||
radix: 'off',
|
||||
'import/order': 'off',
|
||||
'import/no-extraneous-dependencies': 'off',
|
||||
'prefer-destructuring': 'off',
|
||||
'no-shadow': 'off',
|
||||
'no-new': 'off',
|
||||
'no-restricted-syntax': 'off',
|
||||
strict: 'off',
|
||||
'class-methods-use-this': 'off',
|
||||
'no-else-return': 'off',
|
||||
'import/no-dynamic-require': 'off',
|
||||
'no-underscore-dangle': 'off',
|
||||
'prefer-template': 'off',
|
||||
'consistent-return': 'off',
|
||||
'no-continue': 'off',
|
||||
'object-shorthand': 'off',
|
||||
'one-var': 'off',
|
||||
'prefer-const': 'off',
|
||||
'spaced-comment': 'off',
|
||||
'no-loop-func': 'off',
|
||||
'arrow-body-style': 'off',
|
||||
|
||||
'guard-for-in': 'off',
|
||||
'no-return-assign': 'off',
|
||||
'dot-notation': 'off',
|
||||
|
||||
'func-names': 'off',
|
||||
'import/no-useless-path-segments': 'off',
|
||||
'default-param-last': 'off',
|
||||
'prefer-arrow-callback': 'off',
|
||||
'no-unneeded-ternary': 'off',
|
||||
'no-return-await': 'off',
|
||||
'import/extensions': 'off',
|
||||
|
||||
'no-var': 'off',
|
||||
'import/newline-after-import': 'off',
|
||||
'no-restricted-globals': 'off',
|
||||
'operator-assignment': 'off',
|
||||
'no-eval': 'off',
|
||||
'max-classes-per-file': 'off',
|
||||
'vars-on-top': 'off',
|
||||
'no-bitwise': 'off',
|
||||
'no-lonely-if': 'off',
|
||||
'no-multi-assign': 'off',
|
||||
'no-promise-executor-return': 'off',
|
||||
'no-empty-function': 'off',
|
||||
'import/no-unresolved': 'off',
|
||||
camelcase: 'off',
|
||||
eqeqeq: 'off',
|
||||
'lines-between-class-members': 'off',
|
||||
'import/no-cycle': 'off',
|
||||
'new-cap': 'off',
|
||||
'prefer-object-spread': 'off',
|
||||
'no-new-func': 'off',
|
||||
'no-unused-expressions': 'off',
|
||||
'lines-around-directive': 'off',
|
||||
'prefer-exponentiation-operator': 'off',
|
||||
'no-restricted-properties': 'off',
|
||||
'prefer-rest-params': 'off',
|
||||
'no-unreachable-loop': 'off',
|
||||
'no-alert': 'off',
|
||||
'no-useless-return': 'off',
|
||||
'no-nested-ternary': 'off',
|
||||
'prefer-regex-literals': 'off',
|
||||
'import/no-named-as-default-member': 'off',
|
||||
yoda: 'off',
|
||||
'no-script-url': 'off',
|
||||
'no-prototype-builtins':'off'
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Dev
|
||||
on:
|
||||
push:
|
||||
jobs:
|
||||
build_docker:
|
||||
name: Build Docker image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- name: Run the TypeScript build
|
||||
run: npx tsc
|
||||
- name: Create server-package.json
|
||||
run: cat package.json | grep -v electron > server-package.json
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
@@ -0,0 +1,147 @@
|
||||
name: Main
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'develop'
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
jobs:
|
||||
build_darwin-x64:
|
||||
name: Build macOS x86_64
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- run: ./bin/build-mac-x64.sh
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trilium-mac-x64.zip
|
||||
path: dist/trilium-mac-x64*.zip
|
||||
build_darwin-arm64:
|
||||
name: Build macOS aarch64
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- run: ./bin/build-mac-arm64.sh
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trilium-mac-arm64.zip
|
||||
path: dist/trilium-mac-arm64*.zip
|
||||
build_linux-x64:
|
||||
name: Build Linux x86_64
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- run: ./bin/build-linux-x64.sh
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trilium-linux-x64.tar.xz
|
||||
path: dist/trilium-linux-x64-*.tar.xz
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trilium_amd64.deb
|
||||
path: dist/trilium_*.deb
|
||||
build_linux_server-x64:
|
||||
name: Build Linux Server x86_64
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- run: ./bin/build-server.sh
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trilium-linux-x64-server.tar.xz
|
||||
path: dist/trilium-linux-x64-server-*.tar.xz
|
||||
build_windows-x64:
|
||||
name: Build Windows x86_64
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Wine
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
wget -qO - https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add -
|
||||
sudo add-apt-repository ppa:cybermax-dexter/sdl2-backport
|
||||
sudo apt-add-repository "deb https://dl.winehq.org/wine-builds/ubuntu $(lsb_release -cs) main"
|
||||
sudo apt install --install-recommends winehq-stable
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- run: ./bin/build-win-x64.sh
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trilium-windows-x64.zip
|
||||
path: dist/trilium-windows-x64-*.zip
|
||||
build_docker:
|
||||
name: Build Docker image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- name: Run the TypeScript build
|
||||
run: npx tsc
|
||||
- name: Create server-package.json
|
||||
run: cat package.json | grep -v electron > server-package.json
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/build-push-action@v6
|
||||
id: push
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
- name: Generate artifact attestation
|
||||
uses: actions/attest-build-provenance@v1
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
|
||||
subject-digest: ${{ steps.push.outputs.digest }}
|
||||
push-to-registry: true
|
||||
@@ -1,6 +1,7 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
build/
|
||||
src/public/app-dist/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
_
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
#npx lint-staged
|
||||
Generated
-6
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EslintConfiguration">
|
||||
<option name="fix-on-save" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"printWidth": 200,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"quoteProps": "as-needed",
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": false,
|
||||
"arrowParens": "always",
|
||||
"proseWrap": "preserve",
|
||||
"htmlWhitespaceSensitivity": "css",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
//https://prettier.io/docs/en/options.html
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'none',
|
||||
singleQuote: true,
|
||||
printWidth: 100,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
quoteProps: "as-needed",
|
||||
bracketSpacing: true,
|
||||
arrowParens: "avoid"
|
||||
// htmlWhitespaceSensitivity: 'ignore',
|
||||
};
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
]
|
||||
}
|
||||
Vendored
+5
-32
@@ -1,33 +1,6 @@
|
||||
{
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||
},
|
||||
"editor.formatOnSave": true,
|
||||
"eslint.format.enable": true,
|
||||
"eslint.probe": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"html",
|
||||
"vue",
|
||||
"markdown",
|
||||
"json",
|
||||
"jsonc"
|
||||
],
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"html",
|
||||
"vue",
|
||||
"markdown",
|
||||
"json",
|
||||
"jsonc"
|
||||
],
|
||||
"files.eol": "\n",
|
||||
}
|
||||
"editor.formatOnSave": false,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"files.eol": "\n",
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
||||
|
||||
+19
-11
@@ -1,6 +1,18 @@
|
||||
# !!! Don't try to build this Dockerfile directly, run it through bin/build-docker.sh script !!!
|
||||
FROM node:18.18.2-alpine
|
||||
|
||||
# Configure system dependencies
|
||||
RUN apk add --no-cache --virtual .build-dependencies \
|
||||
autoconf \
|
||||
automake \
|
||||
g++ \
|
||||
gcc \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
libpng-dev \
|
||||
python3
|
||||
|
||||
# Create app directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
@@ -9,25 +21,21 @@ COPY . .
|
||||
|
||||
COPY server-package.json package.json
|
||||
|
||||
# Copy TypeScript build artifacts into the original directory structure.
|
||||
RUN ls
|
||||
RUN cp -R build/src/* src/.
|
||||
RUN rm -r build
|
||||
|
||||
# Install app dependencies
|
||||
RUN set -x \
|
||||
&& apk add --no-cache --virtual .build-dependencies \
|
||||
autoconf \
|
||||
automake \
|
||||
g++ \
|
||||
gcc \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
libpng-dev \
|
||||
python3 \
|
||||
&& npm install \
|
||||
&& apk del .build-dependencies \
|
||||
&& npm run webpack \
|
||||
&& npm prune --omit=dev \
|
||||
&& cp src/public/app/share.js src/public/app-dist/. \
|
||||
&& cp -r src/public/app/doc_notes src/public/app-dist/. \
|
||||
&& rm -rf src/public/app
|
||||
&& rm -rf src/public/app \
|
||||
&& rm src/services/asset_path.ts
|
||||
|
||||
# Some setup tools need to be kept
|
||||
RUN apk add --no-cache su-exec shadow
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Trilium Notes
|
||||
|
||||
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
|
||||
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
|
||||
|
||||
[](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
Trilium Notes 是一个层次化的笔记应用程序,专注于建立大型个人知识库。请参阅[屏幕截图](https://github.com/zadam/trilium/wiki/Screenshot-tour)以快速了解:
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# Trilium Notes
|
||||
|
||||
## Trilium è in manutenzione - vedi i dettagli in https://github.com/zadam/trilium/issues/4620
|
||||
|
||||
Le discussioni preliminari sull'organizzazione si stanno svolgendo in [Trilium Next discussions](https://github.com/orgs/TriliumNext/discussions).
|
||||
|
||||
[](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
|
||||
|
||||
|
||||
Trilium Notes è un'applicazione per appunti ad organizzazione gerarchica, studiata per la costruzione di archivi di conoscenza personali di grandi dimensioni.
|
||||
|
||||
Vedi [fotografie](https://github.com/zadam/trilium/wiki/Screenshot-tour) per una panoramica veloce:
|
||||
|
||||
<a href="https://github.com/zadam/trilium/wiki/Screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
L'Ucraina si sta difendendo dall'aggressione russa, considera [donare all'esercito ucraino o a organizzazioni umanitarie](https://standforukraine.com/).
|
||||
|
||||
<p float="left">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/4/49/Flag_of_Ukraine.svg" alt="drawing" width="400"/>
|
||||
<img src="https://signmyrocket.com//uploads/2b2a523cd0c0e76cdbba95a89a9636b2_1676971281.jpg" alt="Trilium Notes supports Ukraine!" width="570"/>
|
||||
</p>
|
||||
|
||||
## 🎁 Funzionalità
|
||||
|
||||
|
||||
* Gli appunti possono essere organizzati in un albero di profondità arbitraria. Un singolo appunto può essere collocato in più posti nell'albero (vedi [clonazione](https://github.com/zadam/trilium/wiki/Cloning-notes))
|
||||
* Ricco editor visuale (WYSIWYG), con supporto -tra l'altro- per tabelle, immagini ed [espressioni matematiche](https://github.com/zadam/trilium/wiki/Text-notes#math-support) e con [formattazione automatica](https://github.com/zadam/trilium/wiki/Text-notes#autoformat) per markdown
|
||||
* Supporto per la modifica di [appunti con codice sorgente](https://github.com/zadam/trilium/wiki/Code-notes), con evidenziazione della sintassi
|
||||
* [Navigazione veloce](https://github.com/zadam/trilium/wiki/Note-navigation) tra gli appunti, ricerca testuale completa e [fissaggio degli appunti](https://github.com/zadam/trilium/wiki/Note-hoisting)
|
||||
* Supporto integrato ed automatico per le [revisioni degli appunti](https://github.com/zadam/trilium/wiki/Note-revisions)
|
||||
* Gli [attributi](https://github.com/zadam/trilium/wiki/Attributes) degli appunti possono essere utilizzati per l'organizzazione, per l'interrogazione e per lo scripting avanzato (prorgrammazione).
|
||||
* [Sincronizzazione](https://github.com/zadam/trilium/wiki/Synchronization) con un server di sincronizzazione auto-ospitato
|
||||
* c'è un [servizio di terze parti per ospitare server di sincronizzazione](https://trilium.cc/paid-hosting)
|
||||
* [Condivisione](https://github.com/zadam/trilium/wiki/Sharing) (pubblicazione) di appunti sull'internet pubblico
|
||||
* Robusta [crittografia](https://github.com/zadam/trilium/wiki/Protected-notes) configurabile singolarmente per ogni appunto
|
||||
* Disegno di diagrammi con Excalidraw (tipo di appunto "canvas")
|
||||
* [Mappe relazionali](https://github.com/zadam/trilium/wiki/Relation-map) e [mappe di collegamenti](https://github.com/zadam/trilium/wiki/Link-map) per visualizzare gli appunti e le loro relazioni
|
||||
* [Scripting](https://github.com/zadam/trilium/wiki/Scripts) - vedi [Esempi avanzati](https://github.com/zadam/trilium/wiki/Advanced-showcases)
|
||||
* [API REST](https://github.com/zadam/trilium/wiki/ETAPI) per l'automazione
|
||||
* Si adatta bene sia in termini di usabilità che di prestazioni fino ad oltre 100 000 appunti
|
||||
* Interfaccia utente ottimizzata per il [mobile](https://github.com/zadam/trilium/wiki/Mobile-frontend) (smartphone e tablet)
|
||||
* [Tema Notturno](https://github.com/zadam/trilium/wiki/Themes)
|
||||
* Supporto per importazione ed esportazione da e per [Evernote](https://github.com/zadam/trilium/wiki/Evernote-import) e [Markdown import](https://github.com/zadam/trilium/wiki/Markdown)
|
||||
* [Web Clipper](https://github.com/zadam/trilium/wiki/Web-clipper) per il salvataggio facile di contenuti web
|
||||
|
||||
|
||||
Dai un'occhiata a [awesome-trilium](https://github.com/Nriver/awesome-trilium) per temi, script, plugin e altro di terze parti.
|
||||
|
||||
## 🏗 Rilasci
|
||||
|
||||
|
||||
Trilium è fornito come applicazione desktop (Linux e Windows) o come applicazione web ospitata sul tuo server (Linux). La versione desktop per Mac OS è disponibile, ma [non è supportata](https://github.com/zadam/trilium/wiki/FAQ#mac-os-support).
|
||||
|
||||
* Se vuoi usare Trilium sul tuo desktop, scarica il rilascio binario per la tua piattaforma dall'[ultimo rilascio](https://github.com/zadam/trilium/releases/latest), decomprimi l'archivio e avvia l'eseguibile ```trilium```.
|
||||
* Se vuoi installare Trilium su un server, segui [questa pagina](https://github.com/zadam/trilium/wiki/Server-installation).
|
||||
* Per ora solo Chrome e Firefox sono i browser supportati (testati).
|
||||
|
||||
Trilium è anche disponibile su Flatpak:
|
||||
|
||||
[<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium)
|
||||
|
||||
## 📝 Documentazione
|
||||
|
||||
[Vedi la wiki per una lista completa delle pagine di documentazione.](https://github.com/zadam/trilium/wiki/)
|
||||
|
||||
Puoi anche leggere ["Patterns of personal knowledge base"](https://github.com/zadam/trilium/wiki/Patterns-of-personal-knowledge-base) per avere un'ispirazione su come potresti utilizzare Trilium.
|
||||
|
||||
## 💻 Contribuire
|
||||
|
||||
Usa un ambiente di sviluppo basato su browser
|
||||
|
||||
[](https://gitpod.io/#https://github.com/zadam/trilium)
|
||||
|
||||
O clona localmente ed esegui
|
||||
```
|
||||
npm install
|
||||
npm run start-server
|
||||
```
|
||||
|
||||
## 📢 Riconoscimenti
|
||||
|
||||
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - miglior editor visuale (WYSIWYG) sul mercato, squadra di sviluppo attenta e reattiva
|
||||
* [FancyTree](https://github.com/mar10/fancytree) - libreria per alberi molto ricca di funzionalità, senza pari. Trilium Notes non sarebbe lo stesso senza di essa.
|
||||
* [CodeMirror](https://github.com/codemirror/CodeMirror) - editor di codice con supporto per un'enorme quantità di linguaggi.
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - libreria per la connettività visuale senza pari. Utilizzata per [mappe relazionali](https://github.com/zadam/trilium/wiki/Relation-map) e [mappe di collegamenti](https://github.com/zadam/trilium/wiki/Link-map).
|
||||
|
||||
## 🤝 Supporto
|
||||
|
||||
È possibile supportare Trilium attraverso Github Sponsors, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
|
||||
|
||||
## 🔑 Licenza
|
||||
|
||||
Questo programma è software libero: è possibile redistribuirlo e/o modificarlo nei termini della GNU Affero General Public License come pubblicata dalla Free Software Foundation, sia la versione 3 della Licenza, o (a propria scelta) qualsiasi versione successiva.
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Trilium Notes
|
||||
|
||||
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
|
||||
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
|
||||
|
||||
Trilium Notes は、大規模な個人知識ベースの構築に焦点を当てた、階層型ノートアプリケーションです。概要は[スクリーンショット](https://github.com/zadam/trilium/wiki/Screenshot-tour)をご覧ください:
|
||||
|
||||
|
||||
@@ -1,82 +1,95 @@
|
||||
# Trilium Notes
|
||||
# TriliumNext Notes
|
||||
|
||||
[](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
|
||||
[English](https://github.com/TriliumNext/Notes/blob/master/README.md) | [Chinese](https://github.com/TriliumNext/Notes/blob/master/README-ZH_CN.md) | [Russian](https://github.com/TriliumNext/Notes/blob/master/README.ru.md) | [Japanese](https://github.com/TriliumNext/Notes/blob/master/README.ja.md) | [Italian](https://github.com/TriliumNext/Notes/blob/master/README.it.md)
|
||||
|
||||
Trilium Notes is a hierarchical note taking application with focus on building large personal knowledge bases. See [screenshots](https://github.com/zadam/trilium/wiki/Screenshot-tour) for quick overview:
|
||||
TriliumNext Notes is a hierarchical note taking application with focus on building large personal knowledge bases.
|
||||
|
||||
<a href="https://github.com/zadam/trilium/wiki/Screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a>
|
||||
See [screenshots](https://triliumnext.github.io/Docs/Wiki/Screenshot%20tour) for quick overview:
|
||||
|
||||
Ukraine is currently defending itself from Russian aggression, please consider [donating to Ukrainian Army or humanitarian charities](https://standforukraine.com/).
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/Screenshot%20tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
<p float="left">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/4/49/Flag_of_Ukraine.svg" alt="drawing" width="400"/>
|
||||
<img src="https://signmyrocket.com//uploads/2b2a523cd0c0e76cdbba95a89a9636b2_1676971281.jpg" alt="Trilium Notes supports Ukraine!" width="570"/>
|
||||
</p>
|
||||
## ⚠️ Why TriliumNext?
|
||||
|
||||
[The original Trilium project is in maintenance mode](https://github.com/zadam/trilium/issues/4620)
|
||||
|
||||
## 🗭 Discuss with us
|
||||
|
||||
Feel free to join our official discussions and community. We are focused on the development on Trilium, and would love to hear what features, suggestions, or issues you may have!
|
||||
|
||||
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions)
|
||||
- [Github Discussions](https://github.com/TriliumNext/Notes/discussions) (For Asynchronous discussions)
|
||||
- [Wiki](https://github.com/zadam/trilium/wiki) (For common how-to questions and user guides)
|
||||
|
||||
The two rooms linked above are mirrored, so you can use either XMPP or Matrix, from any client you prefer, on pretty much any platform under the sun!
|
||||
|
||||
### Unofficial Communities
|
||||
|
||||
[Trilium Rocks](https://discord.gg/aqdX9mXX4r)
|
||||
|
||||
## 🎁 Features
|
||||
|
||||
* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://github.com/zadam/trilium/wiki/Cloning-notes))
|
||||
* Rich WYSIWYG note editing including e.g. tables, images and [math](https://github.com/zadam/trilium/wiki/Text-notes#math-support) with markdown [autoformat](https://github.com/zadam/trilium/wiki/Text-notes#autoformat)
|
||||
* Support for editing [notes with source code](https://github.com/zadam/trilium/wiki/Code-notes), including syntax highlighting
|
||||
* Fast and easy [navigation between notes](https://github.com/zadam/trilium/wiki/Note-navigation), full text search and [note hoisting](https://github.com/zadam/trilium/wiki/Note-hoisting)
|
||||
* Seamless [note versioning](https://github.com/zadam/trilium/wiki/Note-revisions)
|
||||
* Note [attributes](https://github.com/zadam/trilium/wiki/Attributes) can be used for note organization, querying and advanced [scripting](https://github.com/zadam/trilium/wiki/Scripts)
|
||||
* [Synchronization](https://github.com/zadam/trilium/wiki/Synchronization) with self-hosted sync server
|
||||
* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://triliumnext.github.io/Docs/Wiki/Cloning-notes))
|
||||
* Rich WYSIWYG note editing including e.g. tables, images and [math](https://triliumnext.github.io/Docs/Wiki/Text-notes) with markdown [autoformat](https://triliumnext.github.io/Docs/Wiki/Text-notes#autoformat)
|
||||
* Support for editing [notes with source code](https://triliumnext.github.io/Docs/Wiki/Code-notes), including syntax highlighting
|
||||
* Fast and easy [navigation between notes](https://triliumnext.github.io/Docs/Wiki/Note-navigation), full text search and [note hoisting](https://triliumnext.github.io/Docs/Wiki/Note-hoisting)
|
||||
* Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/Note-revisions)
|
||||
* Note [attributes](https://triliumnext.github.io/Docs/Wiki/Attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/Scripts)
|
||||
* [Synchronization](https://triliumnext.github.io/Docs/Wiki/Synchronization) with self-hosted sync server
|
||||
* there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting)
|
||||
* [Sharing](https://github.com/zadam/trilium/wiki/Sharing) (publishing) notes to public internet
|
||||
* Strong [note encryption](https://github.com/zadam/trilium/wiki/Protected-notes) with per-note granularity
|
||||
* [Sharing](https://triliumnext.github.io/Docs/Wiki/Sharing) (publishing) notes to public internet
|
||||
* Strong [note encryption](https://triliumnext.github.io/Docs/Wiki/Protected-notes) with per-note granularity
|
||||
* Sketching diagrams with built-in Excalidraw (note type "canvas")
|
||||
* [Relation maps](https://github.com/zadam/trilium/wiki/Relation-map) and [link maps](https://github.com/zadam/trilium/wiki/Link-map) for visualizing notes and their relations
|
||||
* [Scripting](https://github.com/zadam/trilium/wiki/Scripts) - see [Advanced showcases](https://github.com/zadam/trilium/wiki/Advanced-showcases)
|
||||
* [REST API](https://github.com/zadam/trilium/wiki/ETAPI) for automation
|
||||
* [Relation maps](https://triliumnext.github.io/Docs/Wiki/Relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/Link-map) for visualizing notes and their relations
|
||||
* [Scripting](https://triliumnext.github.io/Docs/Wiki/Scripts) - see [Advanced showcases](https://triliumnext.github.io/Docs/Wiki/Advanced-showcases)
|
||||
* [REST API](https://triliumnext.github.io/Docs/Wiki/ETAPI) for automation
|
||||
* Scales well in both usability and performance upwards of 100 000 notes
|
||||
* Touch optimized [mobile frontend](https://github.com/zadam/trilium/wiki/Mobile-frontend) for smartphones and tablets
|
||||
* [Night theme](https://github.com/zadam/trilium/wiki/Themes)
|
||||
* [Evernote](https://github.com/zadam/trilium/wiki/Evernote-import) and [Markdown import & export](https://github.com/zadam/trilium/wiki/Markdown)
|
||||
* [Web Clipper](https://github.com/zadam/trilium/wiki/Web-clipper) for easy saving of web content
|
||||
* Touch optimized [mobile frontend](https://triliumnext.github.io/Docs/Wiki/Mobile-frontend) for smartphones and tablets
|
||||
* [Night theme](https://triliumnext.github.io/Docs/Wiki/Themes)
|
||||
* [Evernote](https://triliumnext.github.io/Docs/Wiki/Evernote-import) and [Markdown import & export](https://triliumnext.github.io/Docs/Wiki/Markdown)
|
||||
* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/Web-clipper) for easy saving of web content
|
||||
|
||||
Check out [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more.
|
||||
✨ Check out the following third-party resources for more TriliumNext related goodies:
|
||||
|
||||
- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more.
|
||||
- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more.
|
||||
|
||||
## 🏗 Builds
|
||||
|
||||
Trilium is provided as either desktop application (Linux and Windows) or web application hosted on your server (Linux). Mac OS desktop build is available, but it is [unsupported](https://github.com/zadam/trilium/wiki/FAQ#mac-os-support).
|
||||
Trilium is provided as either desktop application (Linux and Windows) or web application hosted on your server (Linux). Mac OS desktop build is available, but it is [unsupported](https://triliumnext.github.io/Docs/Wiki/FAQ#mac-os-support).
|
||||
|
||||
* If you want to use Trilium on the desktop, download binary release for your platform from [latest release](https://github.com/zadam/trilium/releases/latest), unzip the package and run ```trilium``` executable.
|
||||
* If you want to install Trilium on server, follow [this page](https://github.com/zadam/trilium/wiki/Server-installation).
|
||||
* Currently only recent Chrome and Firefox are supported (tested) browsers.
|
||||
* If you want to use TriliumNext on the desktop, download binary release for your platform from [latest release](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run ```trilium``` executable.
|
||||
* If you want to install TriliumNext on your own server, follow [this page](https://triliumnext.github.io/Docs/Wiki/Server-installation).
|
||||
* Currently only recent versions of Chrome and Firefox are supported (tested) browsers.
|
||||
|
||||
Trilium is also provided as a Flatpak:
|
||||
TriliumNext will also provided as a Flatpak:
|
||||
|
||||
[<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium)
|
||||
<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">
|
||||
|
||||
## 📝 Documentation
|
||||
|
||||
[See wiki for complete list of documentation pages.](https://github.com/zadam/trilium/wiki/)
|
||||
[See wiki for complete list of documentation pages.](https://triliumnext.github.io/Docs)
|
||||
|
||||
You can also read [Patterns of personal knowledge base](https://github.com/zadam/trilium/wiki/Patterns-of-personal-knowledge-base) to get some inspiration on how you might use Trilium.
|
||||
You can also read [Patterns of personal knowledge base](https://triliumnext.github.io/Docs/Wiki/Patterns-of-personal-knowledge-base) to get some inspiration on how you might use Trilium.
|
||||
|
||||
## 💻 Contribute
|
||||
|
||||
Use a browser based dev environment
|
||||
|
||||
[](https://gitpod.io/#https://github.com/zadam/trilium)
|
||||
|
||||
Or clone locally and run
|
||||
Clone locally and run
|
||||
```
|
||||
npm install
|
||||
npm run start-server
|
||||
```
|
||||
|
||||
## 📢 Shoutouts
|
||||
## 👏 Shoutouts
|
||||
|
||||
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team
|
||||
* [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. Trilium Notes would not be the same without it.
|
||||
* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://github.com/zadam/trilium/wiki/Relation-map) and [link maps](https://github.com/zadam/trilium/wiki/Link-map)
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/Relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/Link-map)
|
||||
|
||||
## 🤝 Support
|
||||
|
||||
You can support Trilium using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
|
||||
You can support the original Trilium developer using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
|
||||
Support for the TriliumNext organization will be possible in the near future.
|
||||
|
||||
## 🔑 License
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Trilium Notes
|
||||
|
||||
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
|
||||
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
|
||||
|
||||
[](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
Trilium Notes – это приложение для заметок с иерархической структурой, ориентированное на создание больших персональных баз знаний. Для быстрого ознакомления посмотрите [скриншот-тур](https://github.com/zadam/trilium/wiki/Screenshot-tour):
|
||||
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cloc HEAD \
|
||||
--git --md \
|
||||
--include-lang=javascript,typescript \
|
||||
--found=filelist.txt \
|
||||
--exclude-dir=public,libraries,views,docs
|
||||
|
||||
grep -R \.js$ filelist.txt
|
||||
rm filelist.txt
|
||||
Binary file not shown.
@@ -1,5 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if ! command -v dpkg-deb &> /dev/null; then
|
||||
echo "Missing command: dpkg-deb"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if dpkg-deb 2>&1 | grep BusyBox &> /dev/null; then
|
||||
echo "The dpkg-deb binary provided by BusyBox is not compatible. The Debian tool needs to be used instead."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Packaging debian x64 distribution..."
|
||||
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
|
||||
@@ -5,6 +5,9 @@ SERIES=${VERSION:0:4}-latest
|
||||
|
||||
cat package.json | grep -v electron > server-package.json
|
||||
|
||||
echo "Compiling typescript..."
|
||||
npx tsc
|
||||
|
||||
sudo docker build -t zadam/trilium:$VERSION --network host -t zadam/trilium:$SERIES .
|
||||
|
||||
if [[ $VERSION != *"beta"* ]]; then
|
||||
|
||||
+37
-29
@@ -1,50 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "Missing command: jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v fakeroot &> /dev/null; then
|
||||
echo "Missing command: fakeroot"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v dpkg-deb &> /dev/null; then
|
||||
echo "Missing command: dpkg-deb"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if dpkg-deb 2>&1 | grep BusyBox &> /dev/null; then
|
||||
echo "The dpkg-deb binary provided by BusyBox is not compatible. The Debian tool needs to be used instead."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SRC_DIR=./dist/trilium-linux-x64-src
|
||||
|
||||
if [ "$1" != "DONTCOPY" ]
|
||||
then
|
||||
./bin/copy-trilium.sh $SRC_DIR
|
||||
fi
|
||||
[ "$1" != "DONTCOPY" ] && ./bin/copy-trilium.sh "$SRC_DIR"
|
||||
|
||||
rm -r $SRC_DIR/src/public/app-dist/*.mobile.*
|
||||
rm -r "$SRC_DIR"/src/public/app-dist/*.mobile.*
|
||||
|
||||
echo "Copying required linux-x64 binaries"
|
||||
|
||||
cp -r bin/better-sqlite3/linux-desktop-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
|
||||
cp -r bin/better-sqlite3/linux-desktop-better_sqlite3.node "$SRC_DIR"/node_modules/better-sqlite3/build/Release/better_sqlite3.node
|
||||
|
||||
echo "Packaging linux x64 electron build"
|
||||
|
||||
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
|
||||
./node_modules/.bin/electron-packager "$SRC_DIR" --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
|
||||
|
||||
BUILD_DIR=./dist/trilium-linux-x64
|
||||
rm -rf $BUILD_DIR
|
||||
rm -rf "$BUILD_DIR"
|
||||
|
||||
mv "./dist/Trilium Notes-linux-x64" $BUILD_DIR
|
||||
mv "./dist/Trilium Notes-linux-x64" "$BUILD_DIR"
|
||||
|
||||
cp images/app-icons/png/128x128.png $BUILD_DIR/icon.png
|
||||
cp images/app-icons/png/128x128.png "$BUILD_DIR"/icon.png
|
||||
cp bin/tpl/anonymize-database.sql "$BUILD_DIR"/
|
||||
|
||||
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
|
||||
cp -r dump-db "$BUILD_DIR"/
|
||||
rm -rf "$BUILD_DIR"/dump-db/node_modules
|
||||
|
||||
cp -r dump-db $BUILD_DIR/
|
||||
rm -rf $BUILD_DIR/dump-db/node_modules
|
||||
|
||||
cp bin/tpl/trilium-portable.sh $BUILD_DIR/
|
||||
chmod 755 $BUILD_DIR/trilium-portable.sh
|
||||
|
||||
cp bin/tpl/trilium-safe-mode.sh $BUILD_DIR/
|
||||
chmod 755 $BUILD_DIR/trilium-safe-mode.sh
|
||||
|
||||
cp bin/tpl/trilium-no-cert-check.sh $BUILD_DIR/
|
||||
chmod 755 $BUILD_DIR/trilium-no-cert-check.sh
|
||||
for f in 'trilium-portable' 'trilium-safe-mode' 'trilium-no-cert-check'; do
|
||||
cp bin/tpl/"$f".sh "$BUILD_DIR"/
|
||||
chmod 755 "$BUILD_DIR"/"$f".sh
|
||||
done
|
||||
|
||||
echo "Packaging linux x64 electron distribution..."
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
|
||||
cd dist
|
||||
|
||||
tar cJf trilium-linux-x64-${VERSION}.tar.xz trilium-linux-x64
|
||||
|
||||
cd ..
|
||||
pushd dist
|
||||
tar cJf "trilium-linux-x64-${VERSION}.tar.xz" trilium-linux-x64
|
||||
popd
|
||||
|
||||
bin/build-debian.sh
|
||||
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SRC_DIR=./dist/trilium-mac-arm64-src
|
||||
|
||||
if [ "$1" != "DONTCOPY" ]
|
||||
then
|
||||
./bin/copy-trilium.sh $SRC_DIR
|
||||
fi
|
||||
|
||||
echo "Copying required mac arm64 binaries"
|
||||
|
||||
cp -r bin/better-sqlite3/mac-arm64-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
|
||||
|
||||
rm -r $SRC_DIR/src/public/app-dist/*.mobile.*
|
||||
|
||||
echo "Packaging mac arm64 electron build"
|
||||
|
||||
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=darwin --arch=arm64 --overwrite --icon=images/app-icons/mac/icon.icns
|
||||
|
||||
BUILD_DIR=./dist/trilium-mac-arm64
|
||||
rm -rf $BUILD_DIR
|
||||
|
||||
# Mac build has by default useless directory level
|
||||
mv "./dist/Trilium Notes-darwin-arm64" $BUILD_DIR
|
||||
|
||||
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
|
||||
|
||||
cp -r dump-db $BUILD_DIR/
|
||||
rm -rf $BUILD_DIR/dump-db/node_modules
|
||||
|
||||
echo "Zipping mac arm64 electron distribution..."
|
||||
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
|
||||
cd dist
|
||||
|
||||
rm trilium-mac-arm64-${VERSION}.zip
|
||||
zip -r9 --symlinks trilium-mac-arm64-${VERSION}.zip trilium-mac-arm64
|
||||
@@ -7,9 +7,9 @@ then
|
||||
./bin/copy-trilium.sh $SRC_DIR
|
||||
fi
|
||||
|
||||
echo "Copying required mac binaries"
|
||||
echo "Copying required mac x64 binaries"
|
||||
|
||||
cp -r bin/better-sqlite3/mac-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
|
||||
cp -r bin/better-sqlite3/mac-x64-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
|
||||
|
||||
rm -r $SRC_DIR/src/public/app-dist/*.mobile.*
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if ! command -v wine &> /dev/null; then
|
||||
echo "Missing command: wine"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SRC_DIR=./dist/trilium-windows-x64-src
|
||||
|
||||
if [ "$1" != "DONTCOPY" ]
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "Missing command: jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v fakeroot &> /dev/null; then
|
||||
echo "Missing command: fakeroot"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v dpkg-deb &> /dev/null; then
|
||||
echo "Missing command: dpkg-deb"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if dpkg-deb 2>&1 | grep BusyBox &> /dev/null; then
|
||||
echo "The dpkg-deb binary provided by BusyBox is not compatible. The Debian tool needs to be used instead."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v wine &> /dev/null; then
|
||||
echo "Missing command: wine"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Deleting existing builds"
|
||||
|
||||
rm -rf dist/*
|
||||
@@ -13,11 +38,15 @@ cp -r $SRC_DIR ./dist/trilium-linux-x64-src
|
||||
cp -r $SRC_DIR ./dist/trilium-linux-x64-server
|
||||
cp -r $SRC_DIR ./dist/trilium-windows-x64-src
|
||||
cp -r $SRC_DIR ./dist/trilium-mac-x64-src
|
||||
cp -r $SRC_DIR ./dist/trilium-mac-arm64-src
|
||||
|
||||
set -e
|
||||
bin/build-win-x64.sh DONTCOPY
|
||||
|
||||
bin/build-mac-x64.sh DONTCOPY
|
||||
|
||||
bin/build-mac-arm64.sh DONTCOPY
|
||||
|
||||
bin/build-linux-x64.sh DONTCOPY
|
||||
|
||||
bin/build-server.sh DONTCOPY
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import fs from "fs-extra";
|
||||
import path from "path";
|
||||
|
||||
const DEST_DIR = "./dist";
|
||||
const DEST_DIR_SRC = path.join(DEST_DIR, "src");
|
||||
const DEST_DIR_NODE_MODULES = path.join(DEST_DIR, "node_modules");
|
||||
|
||||
async function copyNodeModuleFileOrFolder(source: string) {
|
||||
const adjustedSource = source.substring(13);
|
||||
const destination = path.join(DEST_DIR_NODE_MODULES, adjustedSource);
|
||||
|
||||
console.log(`Copying ${source} to ${destination}`);
|
||||
await fs.ensureDir(path.dirname(destination));
|
||||
await fs.copy(source, destination);
|
||||
}
|
||||
|
||||
const copy = async () => {
|
||||
for (const srcFile of fs.readdirSync("build")) {
|
||||
const destFile = path.join(DEST_DIR, path.basename(srcFile));
|
||||
console.log(`Copying source ${srcFile} -> ${destFile}.`);
|
||||
fs.copySync(path.join("build", srcFile), destFile, { recursive: true });
|
||||
}
|
||||
|
||||
const filesToCopy = ["config-sample.ini"];
|
||||
for (const file of filesToCopy) {
|
||||
console.log(`Copying ${file}`);
|
||||
await fs.copy(file, path.join(DEST_DIR, file));
|
||||
}
|
||||
|
||||
const dirsToCopy = ["images", "libraries", "db"];
|
||||
for (const dir of dirsToCopy) {
|
||||
console.log(`Copying ${dir}`);
|
||||
await fs.copy(dir, path.join(DEST_DIR, dir));
|
||||
}
|
||||
|
||||
const srcDirsToCopy = ["./src/public", "./src/views", "./build"];
|
||||
for (const dir of srcDirsToCopy) {
|
||||
console.log(`Copying ${dir}`);
|
||||
await fs.copy(dir, path.join(DEST_DIR_SRC, path.basename(dir)));
|
||||
}
|
||||
|
||||
const nodeModulesFile = [
|
||||
"node_modules/react/umd/react.production.min.js",
|
||||
"node_modules/react/umd/react.development.js",
|
||||
"node_modules/react-dom/umd/react-dom.production.min.js",
|
||||
"node_modules/react-dom/umd/react-dom.development.js",
|
||||
"node_modules/katex/dist/katex.min.js",
|
||||
"node_modules/katex/dist/contrib/mhchem.min.js",
|
||||
"node_modules/katex/dist/contrib/auto-render.min.js",
|
||||
];
|
||||
|
||||
for (const file of nodeModulesFile) {
|
||||
await copyNodeModuleFileOrFolder(file);
|
||||
}
|
||||
|
||||
const nodeModulesFolder = [
|
||||
"node_modules/@excalidraw/excalidraw/dist/",
|
||||
"node_modules/katex/dist/",
|
||||
"node_modules/dayjs/",
|
||||
"node_modules/force-graph/dist/",
|
||||
"node_modules/boxicons/css/",
|
||||
"node_modules/boxicons/fonts/",
|
||||
"node_modules/mermaid/dist/",
|
||||
"node_modules/jquery/dist/",
|
||||
"node_modules/jquery-hotkeys/",
|
||||
"node_modules/print-this/",
|
||||
"node_modules/split.js/dist/",
|
||||
"node_modules/panzoom/dist/",
|
||||
];
|
||||
|
||||
for (const folder of nodeModulesFolder) {
|
||||
await copyNodeModuleFileOrFolder(folder);
|
||||
}
|
||||
};
|
||||
|
||||
copy()
|
||||
.then(() => console.log("Copying complete!"))
|
||||
.catch((err) => console.error("Error during copy:", err));
|
||||
+43
-28
@@ -1,50 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
shopt -s globstar
|
||||
|
||||
if [[ $# -eq 0 ]] ; then
|
||||
echo "Missing argument of target directory"
|
||||
exit 1
|
||||
fi
|
||||
if ! [[ $(which npm) ]]; then
|
||||
echo "Missing npm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
n exec 18.18.2 npm run webpack
|
||||
# Trigger the TypeScript build
|
||||
echo TypeScript build start
|
||||
npx tsc
|
||||
echo TypeScript build finished
|
||||
|
||||
DIR=$1
|
||||
# Copy the TypeScript artifacts
|
||||
DIR="$1"
|
||||
rm -rf "$DIR"
|
||||
mkdir -pv "$DIR"
|
||||
|
||||
rm -rf $DIR
|
||||
mkdir $DIR
|
||||
echo Webpack start
|
||||
npm run webpack
|
||||
echo Webpack finish
|
||||
|
||||
echo "Copying Trilium to build directory $DIR"
|
||||
|
||||
cp -r images $DIR/
|
||||
cp -r libraries $DIR/
|
||||
cp -r src $DIR/
|
||||
cp -r db $DIR/
|
||||
cp -r package.json $DIR/
|
||||
cp -r package-lock.json $DIR/
|
||||
cp -r README.md $DIR/
|
||||
cp -r LICENSE $DIR/
|
||||
cp -r config-sample.ini $DIR/
|
||||
cp -r electron.js $DIR/
|
||||
cp webpack-* $DIR/
|
||||
for d in 'images' 'libraries' 'src' 'db'; do
|
||||
cp -r "$d" "$DIR"/
|
||||
done
|
||||
|
||||
for f in 'package.json' 'package-lock.json' 'README.md' 'LICENSE' 'config-sample.ini'; do
|
||||
cp "$f" "$DIR"/
|
||||
done
|
||||
|
||||
script_dir=$(realpath $(dirname $0))
|
||||
cp -Rv "$script_dir/../build/src" "$DIR"
|
||||
cp "$script_dir/../build/electron.js" "$DIR"
|
||||
|
||||
# run in subshell (so we return to original dir)
|
||||
(cd $DIR && n exec 18.18.2 npm install --only=prod)
|
||||
(cd $DIR && npm install --only=prod)
|
||||
|
||||
if [[ -d "$DIR"/node_modules ]]; then
|
||||
# cleanup of useless files in dependencies
|
||||
rm -r $DIR/node_modules/image-q/demo
|
||||
rm -r $DIR/node_modules/better-sqlite3/Release
|
||||
rm -r $DIR/node_modules/better-sqlite3/deps/sqlite3.tar.gz
|
||||
rm -r $DIR/node_modules/@jimp/plugin-print/fonts
|
||||
rm -r $DIR/node_modules/jimp/browser
|
||||
rm -r $DIR/node_modules/jimp/fonts
|
||||
for d in 'image-q/demo' 'better-sqlite3/Release' 'better-sqlite3/deps/sqlite3.tar.gz' '@jimp/plugin-print/fonts' 'jimp/browser' 'jimp/fonts'; do
|
||||
[[ -e "$DIR"/node_modules/"$d" ]] && rm -rv "$DIR"/node_modules/"$d"
|
||||
done
|
||||
|
||||
# delete all tests (there are often large images as test file for jimp etc.)
|
||||
find $DIR/node_modules -name test -exec rm -rf {} \;
|
||||
find $DIR/node_modules -name docs -exec rm -rf {} \;
|
||||
find $DIR/node_modules -name demo -exec rm -rf {} \;
|
||||
for d in 'test' 'docs' 'demo'; do
|
||||
find "$DIR"/node_modules -name "$d" -exec rm -rf {} \;
|
||||
done
|
||||
fi
|
||||
|
||||
find $DIR/libraries -name "*.map" -type f -delete
|
||||
|
||||
cp $DIR/src/public/app/share.js $DIR/src/public/app-dist/
|
||||
cp -r $DIR/src/public/app/doc_notes $DIR/src/public/app-dist/
|
||||
d="$DIR"/src/public
|
||||
[[ -d "$d"/app-dist ]] || mkdir -pv "$d"/app-dist
|
||||
cp "$d"/app/share.js "$d"/app-dist/
|
||||
cp -r "$d"/app/doc_notes "$d"/app-dist/
|
||||
|
||||
rm -rf $DIR/src/public/app
|
||||
rm -rf "$d"/app
|
||||
unset f d DIR
|
||||
|
||||
+11
-3
@@ -7,6 +7,11 @@ if [[ $# -eq 0 ]] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "Missing command: jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$1
|
||||
|
||||
if ! [[ ${VERSION} =~ ^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}(-.+)?$ ]] ;
|
||||
@@ -22,13 +27,14 @@ fi
|
||||
|
||||
echo "Releasing Trilium $VERSION"
|
||||
|
||||
jq '.version = "'$VERSION'"' package.json|sponge package.json
|
||||
jq '.version = "'$VERSION'"' package.json > package.json.tmp
|
||||
mv package.json.tmp package.json
|
||||
|
||||
git add package.json
|
||||
|
||||
echo 'module.exports = { buildDate:"'`date --iso-8601=seconds`'", buildRevision: "'`git log -1 --format="%H"`'" };' > src/services/build.js
|
||||
echo 'export = { buildDate:"'`date --iso-8601=seconds`'", buildRevision: "'`git log -1 --format="%H"`'" };' > src/services/build.ts
|
||||
|
||||
git add src/services/build.js
|
||||
git add src/services/build.ts
|
||||
|
||||
TAG=v$VERSION
|
||||
|
||||
@@ -48,6 +54,7 @@ LINUX_X64_BUILD=trilium-linux-x64-$VERSION.tar.xz
|
||||
DEBIAN_X64_BUILD=trilium_${VERSION}_amd64.deb
|
||||
WINDOWS_X64_BUILD=trilium-windows-x64-$VERSION.zip
|
||||
MAC_X64_BUILD=trilium-mac-x64-$VERSION.zip
|
||||
MAC_ARM64_BUILD=trilium-mac-arm64-$VERSION.zip
|
||||
SERVER_BUILD=trilium-linux-x64-server-$VERSION.tar.xz
|
||||
|
||||
echo "Creating release in GitHub"
|
||||
@@ -68,4 +75,5 @@ gh release create "$TAG" \
|
||||
"dist/$LINUX_X64_BUILD" \
|
||||
"dist/$WINDOWS_X64_BUILD" \
|
||||
"dist/$MAC_X64_BUILD" \
|
||||
"dist/$MAC_ARM64_BUILD" \
|
||||
"dist/$SERVER_BUILD"
|
||||
|
||||
BIN
Binary file not shown.
@@ -8,3 +8,6 @@ CREATE TABLE IF NOT EXISTS "blobs" (
|
||||
|
||||
ALTER TABLE notes ADD blobId TEXT DEFAULT NULL;
|
||||
ALTER TABLE note_revisions ADD blobId TEXT DEFAULT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS IDX_notes_blobId on notes (blobId);
|
||||
CREATE INDEX IF NOT EXISTS IDX_note_revisions_blobId on note_revisions (blobId);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module.exports = () => {
|
||||
const sql = require("../../src/services/sql");
|
||||
const utils = require("../../src/services/utils");
|
||||
const sql = require('../../src/services/sql');
|
||||
const utils = require('../../src/services/utils');
|
||||
|
||||
const existingBlobIds = new Set();
|
||||
|
||||
|
||||
@@ -21,5 +21,6 @@ CREATE INDEX `IDX_revisions_utcDateCreated` ON `revisions` (`utcDateCreated`);
|
||||
CREATE INDEX `IDX_revisions_utcDateLastEdited` ON `revisions` (`utcDateLastEdited`);
|
||||
CREATE INDEX `IDX_revisions_dateCreated` ON `revisions` (`dateCreated`);
|
||||
CREATE INDEX `IDX_revisions_dateLastEdited` ON `revisions` (`dateLastEdited`);
|
||||
CREATE INDEX IF NOT EXISTS IDX_revisions_blobId on revisions (blobId);
|
||||
|
||||
UPDATE entity_changes SET entityName = 'revisions' WHERE entityName = 'note_revisions';
|
||||
|
||||
@@ -19,3 +19,5 @@ CREATE INDEX IDX_attachments_ownerId_role
|
||||
|
||||
CREATE INDEX IDX_attachments_utcDateScheduledForErasureSince
|
||||
on attachments (utcDateScheduledForErasureSince);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS IDX_attachments_blobId on attachments (blobId);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
module.exports = () => {
|
||||
const beccaLoader = require("../../src/becca/becca_loader");
|
||||
const becca = require("../../src/becca/becca");
|
||||
const cls = require("../../src/services/cls");
|
||||
const log = require("../../src/services/log");
|
||||
const sql = require("../../src/services/sql");
|
||||
const beccaLoader = require('../../src/becca/becca_loader');
|
||||
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}'.`);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
-- + is normally replaced by X and / by Y, but this can temporarily cause UNIQUE key exception
|
||||
-- this might create blob duplicates, but cleanup will eventually take care of it
|
||||
|
||||
UPDATE blobs SET blobId = REPLACE(blobId, '+', 'A');
|
||||
UPDATE blobs SET blobId = REPLACE(blobId, '/', 'B');
|
||||
|
||||
UPDATE notes SET blobId = REPLACE(blobId, '+', 'A');
|
||||
UPDATE notes SET blobId = REPLACE(blobId, '/', 'B');
|
||||
|
||||
UPDATE attachments SET blobId = REPLACE(blobId, '+', 'A');
|
||||
UPDATE attachments SET blobId = REPLACE(blobId, '/', 'B');
|
||||
|
||||
UPDATE revisions SET blobId = REPLACE(blobId, '+', 'A');
|
||||
UPDATE revisions SET blobId = REPLACE(blobId, '/', 'B');
|
||||
|
||||
UPDATE entity_changes SET entityId = REPLACE(entityId, '+', 'A') WHERE entityName = 'blobs';
|
||||
UPDATE entity_changes SET entityId = REPLACE(entityId, '/', 'B') WHERE entityName = 'blobs';
|
||||
@@ -1,7 +1,7 @@
|
||||
const http = require("http");
|
||||
const ini = require("ini");
|
||||
const fs = require("fs");
|
||||
const dataDir = require("./src/services/data_dir");
|
||||
const dataDir = require('./src/services/data_dir');
|
||||
const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, 'utf-8'));
|
||||
|
||||
if (config.Network.https) {
|
||||
|
||||
+23
-23
@@ -1588,7 +1588,7 @@ See addLabel, addRelation for more specific methods.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1351">line 1351</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1345">line 1345</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1835,7 +1835,7 @@ See addLabel, addRelation for more specific methods.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1372">line 1372</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1366">line 1366</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2081,7 +2081,7 @@ returned.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1385">line 1385</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1379">line 1379</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2316,7 +2316,7 @@ returned.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1470">line 1470</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1464">line 1464</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2432,7 +2432,7 @@ In the future, this functionality might get more generic and some of the require
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1522">line 1522</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1516">line 1516</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2653,7 +2653,7 @@ In the future, this functionality might get more generic and some of the require
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1560">line 1560</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1554">line 1554</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2848,7 +2848,7 @@ In the future, this functionality might get more generic and some of the require
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1192">line 1192</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1186">line 1186</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4207,7 +4207,7 @@ In the future, this functionality might get more generic and some of the require
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1245">line 1245</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1239">line 1239</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4386,7 +4386,7 @@ In the future, this functionality might get more generic and some of the require
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1255">line 1255</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1249">line 1249</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -9019,7 +9019,7 @@ This method can be significantly faster than the getAttribute()
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1214">line 1214</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1208">line 1208</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -11329,7 +11329,7 @@ This method can be significantly faster than the getAttribute()
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1286">line 1286</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1280">line 1280</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -11435,7 +11435,7 @@ This method can be significantly faster than the getAttribute()
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1264">line 1264</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1258">line 1258</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -12675,7 +12675,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1330">line 1330</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1324">line 1324</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -12855,7 +12855,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1446">line 1446</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1440">line 1440</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -13035,7 +13035,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1454">line 1454</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1448">line 1448</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -13288,7 +13288,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1660">line 1660</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1654">line 1654</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -13390,7 +13390,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1614">line 1614</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1608">line 1608</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -13622,7 +13622,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1299">line 1299</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1293">line 1293</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -14081,7 +14081,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1430">line 1430</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1424">line 1424</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -14241,7 +14241,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1438">line 1438</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1432">line 1432</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -14483,7 +14483,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1397">line 1397</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1391">line 1391</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -14694,7 +14694,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1413">line 1413</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1407">line 1407</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -14905,7 +14905,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1422">line 1422</a>
|
||||
<a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line1416">line 1416</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line43">line 43</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line44">line 44</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line671">line 671</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line679">line 679</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -314,7 +314,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line69">line 69</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line70">line 70</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -386,7 +386,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line53">line 53</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line54">line 54</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -458,7 +458,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line74">line 74</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line75">line 75</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -530,7 +530,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line58">line 58</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line59">line 59</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line515">line 515</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line516">line 516</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -674,7 +674,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line48">line 48</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line49">line 49</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -746,7 +746,7 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line79">line 79</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line80">line 80</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -774,6 +774,161 @@ available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="backupNow"><span class="type-signature"></span>backupNow<span class="signature">(backupName)</span><span class="type-signature"> → {Promise}</span></h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>backupName</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">string</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">If the backupName is e.g. "now", then the backup will be written to "backup-now.db" file</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line672">line 672</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Returns:</h5>
|
||||
|
||||
|
||||
<div class="param-desc">
|
||||
- resolves once the backup is finished
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
Type
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<span class="param-type">Promise</span>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="createDataNote"><span class="type-signature"></span>createDataNote<span class="signature">(parentNoteId, title, content)</span><span class="type-signature"> → {Object}</span></h4>
|
||||
|
||||
|
||||
@@ -922,7 +1077,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line275">line 275</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line276">line 276</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1441,7 +1596,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line298">line 298</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line299">line 299</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2075,7 +2230,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line318">line 318</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line319">line 319</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2602,7 +2757,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line542">line 542</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line543">line 543</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2803,7 +2958,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line258">line 258</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line259">line 259</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2985,7 +3140,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line235">line 235</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line236">line 236</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3186,7 +3341,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line225">line 225</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line226">line 226</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3337,7 +3492,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line502">line 502</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line503">line 503</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3538,7 +3693,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line608">line 608</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line609">line 609</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3640,7 +3795,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line521">line 521</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line522">line 522</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3798,7 +3953,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line115">line 115</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line116">line 116</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3952,7 +4107,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line108">line 108</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line109">line 109</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4106,7 +4261,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line155">line 155</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line156">line 156</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4260,7 +4415,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line101">line 101</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line102">line 102</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4461,7 +4616,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line401">line 401</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line402">line 402</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4615,7 +4770,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line129">line 129</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line130">line 130</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4720,7 +4875,7 @@ JSON MIME type. See also createNewNote() for more options.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line135">line 135</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line136">line 136</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4827,7 +4982,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line87">line 87</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line88">line 88</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5028,7 +5183,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line432">line 432</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line433">line 433</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5182,7 +5337,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line94">line 94</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line95">line 95</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5383,7 +5538,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line214">line 214</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line215">line 215</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5584,7 +5739,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line204">line 204</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line205">line 205</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5735,7 +5890,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line142">line 142</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line143">line 143</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5840,7 +5995,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line148">line 148</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line149">line 149</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5991,7 +6146,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line122">line 122</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line123">line 123</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6100,7 +6255,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line391">line 391</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line392">line 392</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6270,7 +6425,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line410">line 410</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line411">line 411</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6573,7 +6728,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line422">line 422</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line423">line 423</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6774,7 +6929,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line442">line 442</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line443">line 443</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6927,7 +7082,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line364">line 364</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line365">line 365</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7082,7 +7237,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line495">line 495</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line496">line 496</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7267,7 +7422,7 @@ instances execute the given function.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line621">line 621</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line622">line 622</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7431,7 +7586,7 @@ you need to make some DB changes, you need to surround your call with api.transa
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line664">line 664</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line665">line 665</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7634,7 +7789,7 @@ you need to make some DB changes, you need to surround your call with api.transa
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line190">line 190</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line191">line 191</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7836,7 +7991,7 @@ you need to make some DB changes, you need to surround your call with api.transa
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line166">line 166</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line167">line 167</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8045,7 +8200,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line476">line 476</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line477">line 477</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8391,7 +8546,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line456">line 456</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line457">line 457</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8615,7 +8770,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line247">line 247</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line248">line 248</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8771,7 +8926,7 @@ exists, then we'll use that transaction.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line486">line 486</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line487">line 487</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8926,7 +9081,7 @@ exists, then we'll use that transaction.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line509">line 509</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line510">line 510</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ class AbstractBeccaEntity {
|
||||
|
||||
sql.execute("DELETE FROM blobs WHERE blobId = ?", [oldBlobId]);
|
||||
// blobs are not marked as erased in entity_changes, they are just purged completely
|
||||
// this is because technically every keystroke can create a new blob and there would be just too many
|
||||
// this is because technically every keystroke can create a new blob, and there would be just too many
|
||||
sql.execute("DELETE FROM entity_changes WHERE entityName = 'blobs' AND entityId = ?", [oldBlobId]);
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ class AbstractBeccaEntity {
|
||||
isErased: false,
|
||||
utcDateChanged: pojo.utcDateModified,
|
||||
isSynced: true,
|
||||
// overriding componentId will cause frontend to think the change is coming from a different component
|
||||
// overriding componentId will cause the frontend to think the change is coming from a different component
|
||||
// and thus reload
|
||||
componentId: opts.forceFrontendReload ? utils.randomString(10) : null
|
||||
});
|
||||
|
||||
@@ -1202,14 +1202,8 @@ class BNote extends AbstractBeccaEntity {
|
||||
|
||||
/** @returns {BAttachment} */
|
||||
getAttachmentByTitle(title) {
|
||||
return sql.getRows(`
|
||||
SELECT attachments.*
|
||||
FROM attachments
|
||||
WHERE ownerId = ?
|
||||
AND title = ?
|
||||
AND isDeleted = 0
|
||||
ORDER BY position`, [this.noteId, title])
|
||||
.map(row => new BAttachment(row))[0];
|
||||
// cannot use SQL to filter by title since it can be encrypted
|
||||
return this.getAttachments().filter(attachment => attachment.title === title)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -185,14 +185,8 @@ class BRevision extends AbstractBeccaEntity {
|
||||
|
||||
/** @returns {BAttachment} */
|
||||
getAttachmentByTitle(title) {
|
||||
return sql.getRows(`
|
||||
SELECT attachments.*
|
||||
FROM attachments
|
||||
WHERE ownerId = ?
|
||||
AND title = ?
|
||||
AND isDeleted = 0
|
||||
ORDER BY position`, [this.revisionId, title])
|
||||
.map(row => new BAttachment(row))[0];
|
||||
// cannot use SQL to filter by title since it can be encrypted
|
||||
return this.getAttachments().filter(attachment => attachment.title === title)[0];
|
||||
}
|
||||
|
||||
beforeSaving() {
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line31">line 31</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line32">line 32</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -612,7 +612,7 @@ not for direct use.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line26">line 26</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line27">line 27</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ const SpacedUpdate = require("./spaced_update");
|
||||
const specialNotesService = require("./special_notes");
|
||||
const branchService = require("./branches");
|
||||
const exportService = require("./export/zip");
|
||||
const syncMutex = require("./sync_mutex.js");
|
||||
const syncMutex = require("./sync_mutex");
|
||||
const backupService = require("./backup");
|
||||
const optionsService = require("./options");
|
||||
|
||||
|
||||
@@ -691,6 +692,13 @@ function BackendScriptApi(currentNote, apiParams) {
|
||||
*/
|
||||
this.runOutsideOfSync = syncMutex.doExclusively;
|
||||
|
||||
/**
|
||||
* @method
|
||||
* @param {string} backupName - If the backupName is e.g. "now", then the backup will be written to "backup-now.db" file
|
||||
* @returns {Promise} - resolves once the backup is finished
|
||||
*/
|
||||
this.backupNow = backupService.backupNow;
|
||||
|
||||
/**
|
||||
* This object contains "at your risk" and "no BC guarantees" objects for advanced use cases.
|
||||
*
|
||||
|
||||
@@ -1172,7 +1172,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line378">line 378</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line381">line 381</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1278,7 +1278,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line265">line 265</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line268">line 268</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1380,7 +1380,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line250">line 250</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line253">line 253</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1482,7 +1482,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line259">line 259</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line262">line 262</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1656,7 +1656,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line641">line 641</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line644">line 644</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1834,7 +1834,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line663">line 663</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line666">line 666</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2034,7 +2034,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line312">line 312</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line315">line 315</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2213,7 +2213,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line434">line 434</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line437">line 437</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2392,7 +2392,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line444">line 444</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line447">line 447</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2498,7 +2498,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line888">line 888</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line891">line 891</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2602,7 +2602,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line171">line 171</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line174">line 174</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2706,7 +2706,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line188">line 188</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line191">line 191</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2808,7 +2808,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line198">line 198</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line201">line 201</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2910,7 +2910,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line240">line 240</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line243">line 243</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3012,7 +3012,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line245">line 245</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line248">line 248</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3163,7 +3163,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line717">line 717</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line720">line 720</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3318,7 +3318,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line741">line 741</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line744">line 744</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3485,7 +3485,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line527">line 527</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line530">line 530</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3595,7 +3595,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line1004">line 1004</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line1007">line 1007</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3699,7 +3699,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line883">line 883</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line886">line 886</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3801,7 +3801,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line783">line 783</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line786">line 786</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3975,7 +3975,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line630">line 630</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line633">line 633</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4153,7 +4153,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line652">line 652</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line655">line 655</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4353,7 +4353,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line299">line 299</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line302">line 302</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4508,7 +4508,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line711">line 711</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line714">line 714</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4663,7 +4663,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line735">line 735</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line738">line 738</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4830,7 +4830,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line519">line 519</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line522">line 522</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4985,7 +4985,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line723">line 723</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line726">line 726</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5140,7 +5140,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line747">line 747</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line750">line 750</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5307,7 +5307,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line593">line 593</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line596">line 596</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5413,7 +5413,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line163">line 163</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line166">line 166</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5515,7 +5515,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line178">line 178</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line181">line 181</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5617,7 +5617,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line206">line 206</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line209">line 209</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5719,7 +5719,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line211">line 211</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line214">line 214</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5870,7 +5870,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line729">line 729</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line732">line 732</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6025,7 +6025,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line759">line 759</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line762">line 762</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6195,7 +6195,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line769">line 769</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line772">line 772</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6346,7 +6346,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line753">line 753</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line756">line 756</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6513,7 +6513,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line601">line 601</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line604">line 604</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6619,7 +6619,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line932">line 932</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line935">line 935</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6797,7 +6797,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line400">line 400</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line403">line 403</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6903,7 +6903,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line873">line 873</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line876">line 876</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7009,7 +7009,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line863">line 863</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line866">line 866</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7183,7 +7183,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line610">line 610</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line613">line 613</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7289,7 +7289,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line193">line 193</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line196">line 196</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7440,7 +7440,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line679">line 679</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line682">line 682</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7618,7 +7618,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line621">line 621</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line624">line 624</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7773,7 +7773,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line673">line 673</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line676">line 676</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line699">line 699</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line702">line 702</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8083,7 +8083,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line705">line 705</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line708">line 708</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8191,7 +8191,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line856">line 856</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line859">line 859</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8275,7 +8275,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line453">line 453</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line456">line 456</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8369,7 +8369,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line927">line 927</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line930">line 930</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8475,7 +8475,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line919">line 919</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line922">line 922</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8581,7 +8581,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line137">line 137</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line140">line 140</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -8732,7 +8732,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line685">line 685</a>
|
||||
<a href="entities_fnote.js.html">entities/fnote.js</a>, <a href="entities_fnote.js.html#line688">line 688</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
@@ -121,6 +121,9 @@ class FNote {
|
||||
* @type {string}
|
||||
*/
|
||||
this.mime = row.mime;
|
||||
|
||||
// the main use case to keep this is to detect content change which should trigger refresh
|
||||
this.blobId = row.blobId;
|
||||
}
|
||||
|
||||
addParent(parentNoteId, branchId, sort = true) {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
const yargs = require('yargs/yargs')
|
||||
const { hideBin } = require('yargs/helpers')
|
||||
const dumpService = require("./inc/dump");
|
||||
const dumpService = require('./inc/dump.js');
|
||||
|
||||
yargs(hideBin(process.argv))
|
||||
.command('$0 <path_to_document> <target_directory>', 'dump the contents of document.db into the target directory', (yargs) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const crypto = require("crypto");
|
||||
const sql = require("./sql");
|
||||
const decryptService = require("./decrypt");
|
||||
const sql = require('./sql');
|
||||
const decryptService = require('./decrypt.js');
|
||||
|
||||
function getDataKey(password) {
|
||||
if (!password) {
|
||||
|
||||
+7
-7
@@ -1,9 +1,9 @@
|
||||
const fs = require("fs");
|
||||
const sanitize = require("sanitize-filename");
|
||||
const sql = require("./sql");
|
||||
const decryptService = require("./decrypt");
|
||||
const dataKeyService = require("./data_key");
|
||||
const extensionService = require("./extension");
|
||||
const sql = require('./sql.js');
|
||||
const decryptService = require('./decrypt.js');
|
||||
const dataKeyService = require('./data_key.js');
|
||||
const extensionService = require('./extension.js');
|
||||
|
||||
function dumpDocument(documentPath, targetPath, options) {
|
||||
const stats = {
|
||||
@@ -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.`);
|
||||
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const {app, globalShortcut, BrowserWindow} = require('electron');
|
||||
const sqlInit = require('./src/services/sql_init');
|
||||
const appIconService = require('./src/services/app_icon');
|
||||
const windowService = require('./src/services/window');
|
||||
const tray = require('./src/services/tray');
|
||||
|
||||
// Adds debug features like hotkeys for triggering dev tools and reload
|
||||
require('electron-debug')();
|
||||
|
||||
appIconService.installLocalAppIcon();
|
||||
|
||||
require('electron-dl')({ saveAs: true });
|
||||
|
||||
// needed for excalidraw export https://github.com/zadam/trilium/issues/4271
|
||||
app.commandLine.appendSwitch("enable-experimental-web-platform-features");
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
});
|
||||
|
||||
app.on('ready', async () => {
|
||||
// app.setAppUserModelId('com.github.zadam.trilium');
|
||||
|
||||
// if db is not initialized -> setup process
|
||||
// if db is initialized, then we need to wait until the migration process is finished
|
||||
if (sqlInit.isDbInitialized()) {
|
||||
await sqlInit.dbReady;
|
||||
|
||||
await windowService.createMainWindow(app);
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
app.on('activate', async () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
await windowService.createMainWindow(app);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
tray.createTray();
|
||||
}
|
||||
else {
|
||||
await windowService.createSetupWindow();
|
||||
}
|
||||
|
||||
await windowService.registerGlobalShortcuts();
|
||||
});
|
||||
|
||||
app.on('will-quit', () => {
|
||||
globalShortcut.unregisterAll();
|
||||
});
|
||||
|
||||
// this is to disable electron warning spam in the dev console (local development only)
|
||||
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
|
||||
|
||||
require('./src/www');
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
"use strict";
|
||||
|
||||
import electron = require("electron");
|
||||
import sqlInit = require("./src/services/sql_init");
|
||||
import appIconService = require("./src/services/app_icon");
|
||||
import windowService = require("./src/services/window");
|
||||
import tray = require("./src/services/tray");
|
||||
|
||||
// Adds debug features like hotkeys for triggering dev tools and reload
|
||||
require("electron-debug")();
|
||||
|
||||
appIconService.installLocalAppIcon();
|
||||
|
||||
require("electron-dl")({ saveAs: true });
|
||||
|
||||
// needed for excalidraw export https://github.com/zadam/trilium/issues/4271
|
||||
electron.app.commandLine.appendSwitch(
|
||||
"enable-experimental-web-platform-features"
|
||||
);
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
electron.app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin") {
|
||||
electron.app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
electron.app.on("ready", async () => {
|
||||
// electron.app.setAppUserModelId('com.github.zadam.trilium');
|
||||
|
||||
// if db is not initialized -> setup process
|
||||
// if db is initialized, then we need to wait until the migration process is finished
|
||||
if (sqlInit.isDbInitialized()) {
|
||||
await sqlInit.dbReady;
|
||||
|
||||
await windowService.createMainWindow(electron.app);
|
||||
|
||||
if (process.platform === "darwin") {
|
||||
electron.app.on("activate", async () => {
|
||||
if (electron.BrowserWindow.getAllWindows().length === 0) {
|
||||
await windowService.createMainWindow(electron.app);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
tray.createTray();
|
||||
} else {
|
||||
await windowService.createSetupWindow();
|
||||
}
|
||||
|
||||
await windowService.registerGlobalShortcuts();
|
||||
});
|
||||
|
||||
electron.app.on("will-quit", () => {
|
||||
electron.globalShortcut.unregisterAll();
|
||||
});
|
||||
|
||||
// this is to disable electron warning spam in the dev console (local development only)
|
||||
process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true";
|
||||
|
||||
require("./src/www.js");
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2021 Aniket Suvarna
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
File diff suppressed because it is too large
Load Diff
-1
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -5,8 +5,8 @@
|
||||
}
|
||||
|
||||
/*
|
||||
* CKEditor 5 (v40.0.0) content styles.
|
||||
* Generated on Thu, 19 Oct 2023 13:45:23 GMT.
|
||||
* CKEditor 5 (v41.0.0) content styles.
|
||||
* Generated on Fri, 26 Jan 2024 10:23:49 GMT.
|
||||
* For more information, check out https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/content-styles.html
|
||||
*/
|
||||
|
||||
@@ -42,18 +42,6 @@
|
||||
overflow-wrap: break-word;
|
||||
position: relative;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-table/theme/tablecaption.css */
|
||||
.ck-content .table > figcaption {
|
||||
display: table-caption;
|
||||
caption-side: top;
|
||||
word-break: break-word;
|
||||
text-align: center;
|
||||
color: var(--ck-color-selector-caption-text);
|
||||
background-color: var(--ck-color-selector-caption-background);
|
||||
padding: .6em;
|
||||
font-size: .75em;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-table/theme/table.css */
|
||||
.ck-content .table {
|
||||
margin: 0.9em auto;
|
||||
@@ -87,6 +75,18 @@
|
||||
.ck-content[dir="ltr"] .table th {
|
||||
text-align: left;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-table/theme/tablecaption.css */
|
||||
.ck-content .table > figcaption {
|
||||
display: table-caption;
|
||||
caption-side: top;
|
||||
word-break: break-word;
|
||||
text-align: center;
|
||||
color: var(--ck-color-selector-caption-text);
|
||||
background-color: var(--ck-color-selector-caption-background);
|
||||
padding: .6em;
|
||||
font-size: .75em;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-page-break/theme/pagebreak.css */
|
||||
.ck-content .page-break {
|
||||
position: relative;
|
||||
@@ -280,6 +280,42 @@
|
||||
.ck-editor__editable.ck-content .todo-list .todo-list__label.todo-list__label_without-description input[type=checkbox] {
|
||||
position: absolute;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol ol {
|
||||
list-style-type: lower-latin;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol ol ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol ol ol ol {
|
||||
list-style-type: upper-latin;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol ol ol ol ol {
|
||||
list-style-type: upper-roman;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ul ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ul ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ul ul ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-image/theme/image.css */
|
||||
.ck-content .image {
|
||||
display: table;
|
||||
@@ -318,17 +354,6 @@
|
||||
flex-shrink: 1;
|
||||
max-width: 100%;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-image/theme/imagecaption.css */
|
||||
.ck-content .image > figcaption {
|
||||
display: table-caption;
|
||||
caption-side: bottom;
|
||||
word-break: break-word;
|
||||
color: var(--ck-color-image-caption-text);
|
||||
background-color: var(--ck-color-image-caption-background);
|
||||
padding: .6em;
|
||||
font-size: .75em;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-image/theme/imageresize.css */
|
||||
.ck-content img.image_resized {
|
||||
height: auto;
|
||||
@@ -347,67 +372,16 @@
|
||||
.ck-content .image.image_resized > figcaption {
|
||||
display: block;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .marker-yellow {
|
||||
background-color: var(--ck-highlight-marker-yellow);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .marker-green {
|
||||
background-color: var(--ck-highlight-marker-green);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .marker-pink {
|
||||
background-color: var(--ck-highlight-marker-pink);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .marker-blue {
|
||||
background-color: var(--ck-highlight-marker-blue);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .pen-red {
|
||||
color: var(--ck-highlight-pen-red);
|
||||
background-color: transparent;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .pen-green {
|
||||
color: var(--ck-highlight-pen-green);
|
||||
background-color: transparent;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol ol {
|
||||
list-style-type: lower-latin;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol ol ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol ol ol ol {
|
||||
list-style-type: upper-latin;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ol ol ol ol ol {
|
||||
list-style-type: upper-roman;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ul ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ul ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-list/theme/list.css */
|
||||
.ck-content ul ul ul ul {
|
||||
list-style-type: square;
|
||||
/* @ckeditor/ckeditor5-image/theme/imagecaption.css */
|
||||
.ck-content .image > figcaption {
|
||||
display: table-caption;
|
||||
caption-side: bottom;
|
||||
word-break: break-word;
|
||||
color: var(--ck-color-image-caption-text);
|
||||
background-color: var(--ck-color-image-caption-background);
|
||||
padding: .6em;
|
||||
font-size: .75em;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-image/theme/imagestyle.css */
|
||||
.ck-content .image-style-block-align-left,
|
||||
@@ -470,6 +444,32 @@
|
||||
.ck-content .image-inline.image-style-align-right {
|
||||
margin-left: var(--ck-inline-image-style-spacing);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .marker-yellow {
|
||||
background-color: var(--ck-highlight-marker-yellow);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .marker-green {
|
||||
background-color: var(--ck-highlight-marker-green);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .marker-pink {
|
||||
background-color: var(--ck-highlight-marker-pink);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .marker-blue {
|
||||
background-color: var(--ck-highlight-marker-blue);
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .pen-red {
|
||||
color: var(--ck-highlight-pen-red);
|
||||
background-color: transparent;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
|
||||
.ck-content .pen-green {
|
||||
color: var(--ck-highlight-pen-green);
|
||||
background-color: transparent;
|
||||
}
|
||||
/* @ckeditor/ckeditor5-block-quote/theme/blockquote.css */
|
||||
.ck-content blockquote {
|
||||
overflow: hidden;
|
||||
|
||||
Vendored
+3
-3
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-5
File diff suppressed because one or more lines are too long
@@ -1,195 +0,0 @@
|
||||
/*jslint browser: true*/
|
||||
/*jslint jquery: true*/
|
||||
|
||||
/*
|
||||
* jQuery Hotkeys Plugin
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Based upon the plugin by Tzury Bar Yochay:
|
||||
* http://github.com/tzuryby/hotkeys
|
||||
*
|
||||
* Original idea by:
|
||||
* Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
|
||||
*/
|
||||
|
||||
/*
|
||||
* One small change is: now keys are passed by object { keys: '...' }
|
||||
* Might be useful, when you want to pass some other data to your handler
|
||||
*/
|
||||
|
||||
(function(jQuery) {
|
||||
|
||||
jQuery.hotkeys = {
|
||||
version: "0.8",
|
||||
|
||||
specialKeys: {
|
||||
8: "backspace",
|
||||
9: "tab",
|
||||
10: "return",
|
||||
13: "return",
|
||||
16: "shift",
|
||||
17: "ctrl",
|
||||
18: "alt",
|
||||
19: "pause",
|
||||
20: "capslock",
|
||||
27: "esc",
|
||||
32: "space",
|
||||
33: "pageup",
|
||||
34: "pagedown",
|
||||
35: "end",
|
||||
36: "home",
|
||||
37: "left",
|
||||
38: "up",
|
||||
39: "right",
|
||||
40: "down",
|
||||
45: "insert",
|
||||
46: "del",
|
||||
59: ";",
|
||||
61: "=",
|
||||
96: "0",
|
||||
97: "1",
|
||||
98: "2",
|
||||
99: "3",
|
||||
100: "4",
|
||||
101: "5",
|
||||
102: "6",
|
||||
103: "7",
|
||||
104: "8",
|
||||
105: "9",
|
||||
106: "*",
|
||||
107: "+",
|
||||
109: "-",
|
||||
110: ".",
|
||||
111: "/",
|
||||
112: "f1",
|
||||
113: "f2",
|
||||
114: "f3",
|
||||
115: "f4",
|
||||
116: "f5",
|
||||
117: "f6",
|
||||
118: "f7",
|
||||
119: "f8",
|
||||
120: "f9",
|
||||
121: "f10",
|
||||
122: "f11",
|
||||
123: "f12",
|
||||
144: "numlock",
|
||||
145: "scroll",
|
||||
173: "-",
|
||||
186: ";",
|
||||
187: "=",
|
||||
188: ",",
|
||||
189: "-",
|
||||
190: ".",
|
||||
191: "/",
|
||||
192: "`",
|
||||
219: "[",
|
||||
220: "\\",
|
||||
221: "]",
|
||||
222: "'"
|
||||
},
|
||||
|
||||
shiftNums: {
|
||||
"`": "~",
|
||||
"1": "!",
|
||||
"2": "@",
|
||||
"3": "#",
|
||||
"4": "$",
|
||||
"5": "%",
|
||||
"6": "^",
|
||||
"7": "&",
|
||||
"8": "*",
|
||||
"9": "(",
|
||||
"0": ")",
|
||||
"-": "_",
|
||||
"=": "+",
|
||||
";": ": ",
|
||||
"'": "\"",
|
||||
",": "<",
|
||||
".": ">",
|
||||
"/": "?",
|
||||
"\\": "|"
|
||||
},
|
||||
|
||||
// excludes: button, checkbox, file, hidden, image, password, radio, reset, search, submit, url
|
||||
textAcceptingInputTypes: [
|
||||
"text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime",
|
||||
"datetime-local", "search", "color", "tel"],
|
||||
|
||||
options: {
|
||||
filterTextInputs: true
|
||||
}
|
||||
};
|
||||
|
||||
function keyHandler(handleObj) {
|
||||
if (typeof handleObj.data === "string") {
|
||||
handleObj.data = {
|
||||
keys: handleObj.data
|
||||
};
|
||||
}
|
||||
|
||||
// Only care when a possible input has been specified
|
||||
if (!handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string") {
|
||||
return;
|
||||
}
|
||||
|
||||
var origHandler = handleObj.handler,
|
||||
keys = handleObj.data.keys.toLowerCase().split(" ");
|
||||
|
||||
handleObj.handler = function(event) {
|
||||
if (jQuery.hotkeys.options.filterTextInputs &&
|
||||
event.target.tagName != 'WEBVIEW' &&
|
||||
jQuery.inArray(event.target.type, jQuery.hotkeys.textAcceptingInputTypes) > -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[event.which],
|
||||
character = String.fromCharCode(event.which).toLowerCase(),
|
||||
modif = "",
|
||||
possible = {};
|
||||
|
||||
jQuery.each(["alt", "ctrl", "shift"], function(index, specialKey) {
|
||||
|
||||
if (event[specialKey + 'Key'] && special !== specialKey) {
|
||||
modif += specialKey + '+';
|
||||
}
|
||||
});
|
||||
|
||||
// metaKey is triggered off ctrlKey erronously
|
||||
if (event.metaKey && !event.ctrlKey && special !== "meta") {
|
||||
modif += "meta+";
|
||||
}
|
||||
|
||||
if (event.metaKey && special !== "meta" && modif.indexOf("alt+ctrl+shift+") > -1) {
|
||||
modif = modif.replace("alt+ctrl+shift+", "hyper+");
|
||||
}
|
||||
|
||||
if (special) {
|
||||
possible[modif + special] = true;
|
||||
}
|
||||
else {
|
||||
possible[modif + character] = true;
|
||||
possible[modif + jQuery.hotkeys.shiftNums[character]] = true;
|
||||
|
||||
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
|
||||
if (modif === "shift+") {
|
||||
possible[jQuery.hotkeys.shiftNums[character]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0, l = keys.length; i < l; i++) {
|
||||
if (possible[keys[i]]) {
|
||||
return origHandler.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
jQuery.each(["keydown", "keyup", "keypress"], function() {
|
||||
jQuery.event.special[this] = {
|
||||
add: keyHandler
|
||||
};
|
||||
});
|
||||
|
||||
})(jQuery || this.jQuery || window.jQuery);
|
||||
Vendored
-10704
File diff suppressed because it is too large
Load Diff
Vendored
-2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
-1641
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -1,335 +0,0 @@
|
||||
/*
|
||||
* printThis v1.15.0
|
||||
* @desc Printing plug-in for jQuery
|
||||
* @author Jason Day
|
||||
*
|
||||
* Resources (based on):
|
||||
* - jPrintArea: http://plugins.jquery.com/project/jPrintArea
|
||||
* - jqPrint: https://github.com/permanenttourist/jquery.jqprint
|
||||
* - Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm
|
||||
*
|
||||
* Licensed under the MIT licence:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* (c) Jason Day 2015-2018
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* $("#mySelector").printThis({
|
||||
* debug: false, // show the iframe for debugging
|
||||
* importCSS: true, // import parent page css
|
||||
* importStyle: false, // import style tags
|
||||
* printContainer: true, // grab outer container as well as the contents of the selector
|
||||
* loadCSS: "path/to/my.css", // path to additional css file - use an array [] for multiple
|
||||
* pageTitle: "", // add title to print page
|
||||
* removeInline: false, // remove all inline styles from print elements
|
||||
* removeInlineSelector: "body *", // custom selectors to filter inline styles. removeInline must be true
|
||||
* printDelay: 333, // variable print delay
|
||||
* header: null, // prefix to html
|
||||
* footer: null, // postfix to html
|
||||
* base: false, // preserve the BASE tag, or accept a string for the URL
|
||||
* formValues: true, // preserve input/form values
|
||||
* canvas: false, // copy canvas elements
|
||||
* doctypeString: '...', // enter a different doctype for older markup
|
||||
* removeScripts: false, // remove script tags from print content
|
||||
* copyTagClasses: false // copy classes from the html & body tag
|
||||
* beforePrintEvent: null, // callback function for printEvent in iframe
|
||||
* beforePrint: null, // function called before iframe is filled
|
||||
* afterPrint: null // function called before iframe is removed
|
||||
* });
|
||||
*
|
||||
* Notes:
|
||||
* - the loadCSS will load additional CSS (with or without @media print) into the iframe, adjusting layout
|
||||
*/
|
||||
;
|
||||
(function($) {
|
||||
|
||||
function appendContent($el, content) {
|
||||
if (!content) return;
|
||||
|
||||
// Simple test for a jQuery element
|
||||
$el.append(content.jquery ? content.clone() : content);
|
||||
}
|
||||
|
||||
function appendBody($body, $element, opt) {
|
||||
// Clone for safety and convenience
|
||||
// Calls clone(withDataAndEvents = true) to copy form values.
|
||||
var $content = $element.clone(opt.formValues);
|
||||
|
||||
if (opt.formValues) {
|
||||
// Copy original select and textarea values to their cloned counterpart
|
||||
// Makes up for inability to clone select and textarea values with clone(true)
|
||||
copyValues($element, $content, 'select, textarea');
|
||||
}
|
||||
|
||||
if (opt.removeScripts) {
|
||||
$content.find('script').remove();
|
||||
}
|
||||
|
||||
if (opt.printContainer) {
|
||||
// grab $.selector as container
|
||||
$content.appendTo($body);
|
||||
} else {
|
||||
// otherwise just print interior elements of container
|
||||
$content.each(function() {
|
||||
$(this).children().appendTo($body)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Copies values from origin to clone for passed in elementSelector
|
||||
function copyValues(origin, clone, elementSelector) {
|
||||
var $originalElements = origin.find(elementSelector);
|
||||
|
||||
clone.find(elementSelector).each(function(index, item) {
|
||||
$(item).val($originalElements.eq(index).val());
|
||||
});
|
||||
}
|
||||
|
||||
var opt;
|
||||
$.fn.printThis = function(options) {
|
||||
opt = $.extend({}, $.fn.printThis.defaults, options);
|
||||
var $element = this instanceof jQuery ? this : $(this);
|
||||
|
||||
var strFrameName = "printThis-" + (new Date()).getTime();
|
||||
|
||||
if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) {
|
||||
// Ugly IE hacks due to IE not inheriting document.domain from parent
|
||||
// checks if document.domain is set by comparing the host name against document.domain
|
||||
var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</s" + "cript></head><body></body>\")";
|
||||
var printI = document.createElement('iframe');
|
||||
printI.name = "printIframe";
|
||||
printI.id = strFrameName;
|
||||
printI.className = "MSIE";
|
||||
document.body.appendChild(printI);
|
||||
printI.src = iframeSrc;
|
||||
|
||||
} else {
|
||||
// other browsers inherit document.domain, and IE works if document.domain is not explicitly set
|
||||
var $frame = $("<iframe id='" + strFrameName + "' name='printIframe' />");
|
||||
$frame.appendTo("body");
|
||||
}
|
||||
|
||||
var $iframe = $("#" + strFrameName);
|
||||
|
||||
// show frame if in debug mode
|
||||
if (!opt.debug) $iframe.css({
|
||||
position: "absolute",
|
||||
width: "0px",
|
||||
height: "0px",
|
||||
left: "-600px",
|
||||
top: "-600px"
|
||||
});
|
||||
|
||||
// before print callback
|
||||
if (typeof opt.beforePrint === "function") {
|
||||
opt.beforePrint();
|
||||
}
|
||||
|
||||
// $iframe.ready() and $iframe.load were inconsistent between browsers
|
||||
setTimeout(function() {
|
||||
|
||||
// Add doctype to fix the style difference between printing and render
|
||||
function setDocType($iframe, doctype){
|
||||
var win, doc;
|
||||
win = $iframe.get(0);
|
||||
win = win.contentWindow || win.contentDocument || win;
|
||||
doc = win.document || win.contentDocument || win;
|
||||
doc.open();
|
||||
doc.write(doctype);
|
||||
doc.close();
|
||||
}
|
||||
|
||||
if (opt.doctypeString){
|
||||
setDocType($iframe, opt.doctypeString);
|
||||
}
|
||||
|
||||
var $doc = $iframe.contents(),
|
||||
$head = $doc.find("head"),
|
||||
$body = $doc.find("body"),
|
||||
$base = $('base'),
|
||||
baseURL;
|
||||
|
||||
// add base tag to ensure elements use the parent domain
|
||||
if (opt.base === true && $base.length > 0) {
|
||||
// take the base tag from the original page
|
||||
baseURL = $base.attr('href');
|
||||
} else if (typeof opt.base === 'string') {
|
||||
// An exact base string is provided
|
||||
baseURL = opt.base;
|
||||
} else {
|
||||
// Use the page URL as the base
|
||||
baseURL = document.location.protocol + '//' + document.location.host;
|
||||
}
|
||||
|
||||
$head.append('<base href="' + baseURL + '">');
|
||||
|
||||
// import page stylesheets
|
||||
if (opt.importCSS) $("link[rel=stylesheet]").each(function() {
|
||||
var href = $(this).attr("href");
|
||||
if (href) {
|
||||
var media = $(this).attr("media") || "all";
|
||||
$head.append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>");
|
||||
}
|
||||
});
|
||||
|
||||
// import style tags
|
||||
if (opt.importStyle) $("style").each(function() {
|
||||
$head.append(this.outerHTML);
|
||||
});
|
||||
|
||||
// add title of the page
|
||||
if (opt.pageTitle) $head.append("<title>" + opt.pageTitle + "</title>");
|
||||
|
||||
// import additional stylesheet(s)
|
||||
if (opt.loadCSS) {
|
||||
if ($.isArray(opt.loadCSS)) {
|
||||
jQuery.each(opt.loadCSS, function(index, value) {
|
||||
$head.append("<link type='text/css' rel='stylesheet' href='" + this + "'>");
|
||||
});
|
||||
} else {
|
||||
$head.append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>");
|
||||
}
|
||||
}
|
||||
|
||||
var pageHtml = $('html')[0];
|
||||
|
||||
// CSS VAR in html tag when dynamic apply e.g. document.documentElement.style.setProperty("--foo", bar);
|
||||
$doc.find('html').prop('style', pageHtml.style.cssText);
|
||||
|
||||
// copy 'root' tag classes
|
||||
var tag = opt.copyTagClasses;
|
||||
if (tag) {
|
||||
tag = tag === true ? 'bh' : tag;
|
||||
if (tag.indexOf('b') !== -1) {
|
||||
$body.addClass($('body')[0].className);
|
||||
}
|
||||
if (tag.indexOf('h') !== -1) {
|
||||
$doc.find('html').addClass(pageHtml.className);
|
||||
}
|
||||
}
|
||||
|
||||
// print header
|
||||
appendContent($body, opt.header);
|
||||
|
||||
if (opt.canvas) {
|
||||
// add canvas data-ids for easy access after cloning.
|
||||
var canvasId = 0;
|
||||
// .addBack('canvas') adds the top-level element if it is a canvas.
|
||||
$element.find('canvas').addBack('canvas').each(function(){
|
||||
$(this).attr('data-printthis', canvasId++);
|
||||
});
|
||||
}
|
||||
|
||||
appendBody($body, $element, opt);
|
||||
|
||||
if (opt.canvas) {
|
||||
// Re-draw new canvases by referencing the originals
|
||||
$body.find('canvas').each(function(){
|
||||
var cid = $(this).data('printthis'),
|
||||
$src = $('[data-printthis="' + cid + '"]');
|
||||
|
||||
this.getContext('2d').drawImage($src[0], 0, 0);
|
||||
|
||||
// Remove the markup from the original
|
||||
if ($.isFunction($.fn.removeAttr)) {
|
||||
$src.removeAttr('data-printthis');
|
||||
} else {
|
||||
$.each($src, function(i, el) {
|
||||
el.removeAttribute('data-printthis')
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// remove inline styles
|
||||
if (opt.removeInline) {
|
||||
// Ensure there is a selector, even if it's been mistakenly removed
|
||||
var selector = opt.removeInlineSelector || '*';
|
||||
// $.removeAttr available jQuery 1.7+
|
||||
if ($.isFunction($.removeAttr)) {
|
||||
$body.find(selector).removeAttr("style");
|
||||
} else {
|
||||
$body.find(selector).attr("style", "");
|
||||
}
|
||||
}
|
||||
|
||||
// print "footer"
|
||||
appendContent($body, opt.footer);
|
||||
|
||||
// attach event handler function to beforePrint event
|
||||
function attachOnBeforePrintEvent($iframe, beforePrintHandler) {
|
||||
var win = $iframe.get(0);
|
||||
win = win.contentWindow || win.contentDocument || win;
|
||||
|
||||
if (typeof beforePrintHandler === "function") {
|
||||
if ('matchMedia' in win) {
|
||||
win.matchMedia('print').addListener(function(mql) {
|
||||
if(mql.matches) beforePrintHandler();
|
||||
});
|
||||
} else {
|
||||
win.onbeforeprint = beforePrintHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
attachOnBeforePrintEvent($iframe, opt.beforePrint);
|
||||
|
||||
setTimeout(function() {
|
||||
if ($iframe.hasClass("MSIE")) {
|
||||
// check if the iframe was created with the ugly hack
|
||||
// and perform another ugly hack out of neccessity
|
||||
window.frames["printIframe"].focus();
|
||||
$head.append("<script> window.print(); </s" + "cript>");
|
||||
} else {
|
||||
// proper method
|
||||
if (document.queryCommandSupported("print")) {
|
||||
$iframe[0].contentWindow.document.execCommand("print", false, null);
|
||||
} else {
|
||||
$iframe[0].contentWindow.focus();
|
||||
$iframe[0].contentWindow.print();
|
||||
}
|
||||
}
|
||||
|
||||
// remove iframe after print
|
||||
if (!opt.debug) {
|
||||
setTimeout(function() {
|
||||
$iframe.remove();
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// after print callback
|
||||
if (typeof opt.afterPrint === "function") {
|
||||
opt.afterPrint();
|
||||
}
|
||||
|
||||
}, opt.printDelay);
|
||||
|
||||
}, 333);
|
||||
|
||||
};
|
||||
|
||||
// defaults
|
||||
$.fn.printThis.defaults = {
|
||||
debug: false, // show the iframe for debugging
|
||||
importCSS: true, // import parent page css
|
||||
importStyle: false, // import style tags
|
||||
printContainer: true, // print outer container/$.selector
|
||||
loadCSS: "", // path to additional css file - use an array [] for multiple
|
||||
pageTitle: "", // add title to print page
|
||||
removeInline: false, // remove inline styles from print elements
|
||||
removeInlineSelector: "*", // custom selectors to filter inline styles. removeInline must be true
|
||||
printDelay: 333, // variable print delay
|
||||
header: null, // prefix to html
|
||||
footer: null, // postfix to html
|
||||
base: false, // preserve the BASE tag or accept a string for the URL
|
||||
formValues: true, // preserve input/form values
|
||||
canvas: false, // copy canvas content
|
||||
doctypeString: '<!DOCTYPE html>', // enter a different doctype for older markup
|
||||
removeScripts: false, // remove script tags from print content
|
||||
copyTagClasses: false, // copy classes from the html & body tag
|
||||
beforePrintEvent: null, // callback function for printEvent in iframe
|
||||
beforePrint: null, // function called before iframe is filled
|
||||
afterPrint: null // function called before iframe is removed
|
||||
};
|
||||
})(jQuery);
|
||||
Vendored
-3
File diff suppressed because one or more lines are too long
+3
-4
@@ -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"
|
||||
}
|
||||
|
||||
Generated
+5884
-6167
File diff suppressed because it is too large
Load Diff
+73
-51
@@ -2,24 +2,24 @@
|
||||
"name": "trilium",
|
||||
"productName": "Trilium Notes",
|
||||
"description": "Trilium Notes",
|
||||
"version": "0.62.1-beta",
|
||||
"version": "0.90.0-beta",
|
||||
"license": "AGPL-3.0-only",
|
||||
"main": "electron.js",
|
||||
"bin": {
|
||||
"trilium": "./src/www"
|
||||
"trilium": "src/www.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zadam/trilium.git"
|
||||
},
|
||||
"scripts": {
|
||||
"start-server": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon ./src/www",
|
||||
"start-server-no-dir": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon ./src/www",
|
||||
"qstart-server": "npm run qswitch-server && TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon ./src/www",
|
||||
"start-electron": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron --inspect=5858 .",
|
||||
"start-server": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.ts",
|
||||
"start-server-no-dir": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.ts",
|
||||
"qstart-server": "npm run qswitch-server && TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.ts",
|
||||
"start-electron": "rimraf ./dist && tsc && ts-node ./bin/copy-dist.ts && cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron.js --inspect=5858 .",
|
||||
"start-electron-no-dir": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 electron --inspect=5858 .",
|
||||
"qstart-electron": "npm run qswitch-electron && TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron --inspect=5858 .",
|
||||
"start-test-server": "npm run qswitch-server; rm -rf ./data-test; cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 node ./src/www",
|
||||
"start-test-server": "npm run qswitch-server; rm -rf ./data-test; cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 ts-node src/www.ts",
|
||||
"switch-server": "rm -rf ./node_modules/better-sqlite3 && npm install",
|
||||
"switch-electron": "./node_modules/.bin/electron-rebuild",
|
||||
"qswitch-server": "rm -rf ./node_modules/better-sqlite3/bin ; mkdir -p ./node_modules/better-sqlite3/build ; cp ./bin/better-sqlite3/linux-server-better_sqlite3.node ./node_modules/better-sqlite3/build/better_sqlite3.node",
|
||||
@@ -27,23 +27,22 @@
|
||||
"build-backend-docs": "rm -rf ./docs/backend_api && ./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/backend_api src/becca/entities/*.js src/services/backend_script_api.js src/services/sql.js",
|
||||
"build-frontend-docs": "rm -rf ./docs/frontend_api && ./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
|
||||
"build-docs": "npm run build-backend-docs && npm run build-frontend-docs",
|
||||
"webpack": "webpack -c webpack.config.js",
|
||||
"webpack": "webpack -c webpack.config.ts",
|
||||
"test-jasmine": "TRILIUM_DATA_DIR=~/trilium/data-test jasmine",
|
||||
"test-es6": "node -r esm spec-es6/attribute_parser.spec.js ",
|
||||
"test": "npm run test-jasmine && npm run test-es6",
|
||||
"postinstall": "rimraf ./node_modules/canvas",
|
||||
"lint": "eslint . --cache",
|
||||
"prepare": "husky install || echo 'Husky install failed, expected on flatpak build'"
|
||||
"postinstall": "rimraf ./node_modules/canvas"
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "6.0.4",
|
||||
"@electron/remote": "2.0.12",
|
||||
"@excalidraw/excalidraw": "0.16.1",
|
||||
"archiver": "6.0.1",
|
||||
"async-mutex": "0.4.0",
|
||||
"axios": "1.6.1",
|
||||
"@electron/remote": "2.1.2",
|
||||
"@excalidraw/excalidraw": "0.17.3",
|
||||
"archiver": "7.0.0",
|
||||
"async-mutex": "0.4.1",
|
||||
"axios": "1.6.7",
|
||||
"better-sqlite3": "8.4.0",
|
||||
"chokidar": "3.5.3",
|
||||
"boxicons": "2.1.4",
|
||||
"chokidar": "3.6.0",
|
||||
"cls-hooked": "4.2.2",
|
||||
"compression": "1.7.4",
|
||||
"cookie-parser": "1.4.6",
|
||||
@@ -53,33 +52,39 @@
|
||||
"debounce": "1.2.1",
|
||||
"ejs": "3.1.9",
|
||||
"electron-debug": "3.2.0",
|
||||
"electron-dl": "3.5.1",
|
||||
"electron-dl": "3.5.2",
|
||||
"electron-window-state": "5.0.3",
|
||||
"escape-html": "1.0.3",
|
||||
"express": "4.18.2",
|
||||
"express": "4.18.3",
|
||||
"express-partial-content": "1.0.2",
|
||||
"express-rate-limit": "7.1.4",
|
||||
"express-session": "1.17.3",
|
||||
"fs-extra": "11.1.1",
|
||||
"express-rate-limit": "7.2.0",
|
||||
"express-session": "1.18.0",
|
||||
"force-graph": "1.43.5",
|
||||
"fs-extra": "11.2.0",
|
||||
"helmet": "7.1.0",
|
||||
"html": "1.0.0",
|
||||
"html2plaintext": "2.1.4",
|
||||
"http-proxy-agent": "7.0.0",
|
||||
"https-proxy-agent": "7.0.2",
|
||||
"http-proxy-agent": "7.0.2",
|
||||
"https-proxy-agent": "7.0.4",
|
||||
"image-type": "4.1.0",
|
||||
"ini": "3.0.1",
|
||||
"is-animated": "2.0.2",
|
||||
"is-svg": "4.3.2",
|
||||
"jimp": "0.22.10",
|
||||
"jimp": "0.22.12",
|
||||
"joplin-turndown-plugin-gfm": "1.0.12",
|
||||
"jsdom": "22.1.0",
|
||||
"jquery": "3.7.1",
|
||||
"jquery-hotkeys": "0.2.2",
|
||||
"jsdom": "24.0.0",
|
||||
"katex": "0.16.9",
|
||||
"marked": "9.1.6",
|
||||
"marked": "12.0.0",
|
||||
"mermaid": "10.9.0",
|
||||
"mime-types": "2.1.35",
|
||||
"multer": "1.4.5-lts.1",
|
||||
"node-abi": "3.51.0",
|
||||
"node-abi": "3.56.0",
|
||||
"normalize-strings": "1.1.1",
|
||||
"open": "8.4.1",
|
||||
"panzoom": "9.4.3",
|
||||
"print-this": "2.0.0",
|
||||
"rand-token": "1.0.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
@@ -87,50 +92,67 @@
|
||||
"rimraf": "5.0.5",
|
||||
"safe-compare": "1.1.4",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"sanitize-html": "2.11.0",
|
||||
"sanitize-html": "2.12.1",
|
||||
"sax": "1.3.0",
|
||||
"semver": "7.5.4",
|
||||
"semver": "7.6.0",
|
||||
"serve-favicon": "2.5.0",
|
||||
"session-file-store": "1.5.0",
|
||||
"split.js": "1.6.5",
|
||||
"stream-throttle": "0.1.3",
|
||||
"striptags": "3.2.0",
|
||||
"tmp": "0.2.1",
|
||||
"tree-kill": "^1.2.2",
|
||||
"tmp": "0.2.3",
|
||||
"tree-kill": "1.2.2",
|
||||
"turndown": "7.1.2",
|
||||
"unescape": "1.0.1",
|
||||
"ws": "8.14.2",
|
||||
"ws": "8.16.0",
|
||||
"xml2js": "0.6.2",
|
||||
"yauzl": "2.10.0"
|
||||
"yauzl": "3.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/archiver": "^6.0.2",
|
||||
"@types/better-sqlite3": "^7.6.9",
|
||||
"@types/cls-hooked": "^4.3.8",
|
||||
"@types/compression": "^1.7.5",
|
||||
"@types/cookie-parser": "^1.4.7",
|
||||
"@types/csurf": "^1.11.5",
|
||||
"@types/ejs": "^3.1.5",
|
||||
"@types/escape-html": "^1.0.4",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/express-session": "^1.18.0",
|
||||
"@types/html": "^1.0.4",
|
||||
"@types/ini": "^4.1.0",
|
||||
"@types/jsdom": "^21.1.6",
|
||||
"@types/mime-types": "^2.1.4",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/node": "^20.11.19",
|
||||
"@types/safe-compare": "^1.1.2",
|
||||
"@types/sanitize-html": "^2.11.0",
|
||||
"@types/sax": "^1.2.7",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/serve-favicon": "^2.5.7",
|
||||
"@types/stream-throttle": "^0.1.4",
|
||||
"@types/tmp": "^0.2.6",
|
||||
"@types/turndown": "^5.0.4",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@types/xml2js": "^0.4.14",
|
||||
"cross-env": "7.0.3",
|
||||
"electron": "25.9.4",
|
||||
"electron-builder": "24.6.4",
|
||||
"electron": "25.9.8",
|
||||
"electron-builder": "24.13.3",
|
||||
"electron-packager": "17.1.2",
|
||||
"electron-rebuild": "3.2.9",
|
||||
"eslint": "8.53.0",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-prettier": "9.0.0",
|
||||
"eslint-plugin-import": "2.29.0",
|
||||
"eslint-plugin-jsonc": "2.10.0",
|
||||
"eslint-plugin-prettier": "5.0.1",
|
||||
"esm": "3.2.25",
|
||||
"husky": "8.0.3",
|
||||
"jasmine": "5.1.0",
|
||||
"jsdoc": "4.0.2",
|
||||
"jsonc-eslint-parser": "2.4.0",
|
||||
"lint-staged": "15.1.0",
|
||||
"lorem-ipsum": "2.0.8",
|
||||
"nodemon": "3.0.1",
|
||||
"prettier": "3.1.0",
|
||||
"nodemon": "3.1.0",
|
||||
"rcedit": "4.0.1",
|
||||
"webpack": "5.89.0",
|
||||
"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"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": "eslint --cache --fix"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const {
|
||||
describeEtapi, postEtapi,
|
||||
putEtapiContent
|
||||
} = require("../support/etapi");
|
||||
} = require('../support/etapi.js');
|
||||
const {getEtapi} = require("../support/etapi.js");
|
||||
|
||||
describeEtapi("app_info", () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const {
|
||||
describeEtapi, postEtapi,
|
||||
getEtapi,
|
||||
} = require("../support/etapi");
|
||||
} = require('../support/etapi.js');
|
||||
const {putEtapiContent} = require("../support/etapi.js");
|
||||
|
||||
describeEtapi("backup", () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const {
|
||||
describeEtapi, postEtapi,
|
||||
postEtapiContent,
|
||||
} = require("../support/etapi");
|
||||
} = require('../support/etapi.js');
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const {getEtapiContent} = require("../support/etapi.js");
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ const {
|
||||
getEtapiContent,
|
||||
patchEtapi, putEtapi,
|
||||
putEtapiContent
|
||||
} = require("../support/etapi");
|
||||
} = require('../support/etapi.js');
|
||||
|
||||
describeEtapi("notes", () => {
|
||||
it("create", async () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const BNote = require('../../src/becca/entities/bnote');
|
||||
const BBranch = require('../../src/becca/entities/bbranch');
|
||||
const BAttribute = require('../../src/becca/entities/battribute');
|
||||
const becca = require('../../src/becca/becca');
|
||||
const BNote = require('../../src/becca/entities/bnote.js');
|
||||
const BBranch = require('../../src/becca/entities/bbranch.js');
|
||||
const BAttribute = require('../../src/becca/entities/battribute.js');
|
||||
const becca = require('../../src/becca/becca.js');
|
||||
const randtoken = require('rand-token').generator({source: 'crypto'});
|
||||
|
||||
/** @returns {BNote} */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const SearchContext = require("../../src/services/search/search_context");
|
||||
const SearchContext = require('../../src/services/search/search_context');
|
||||
const parse = require('../../src/services/search/services/parse');
|
||||
|
||||
function tokens(toks, cur = 0) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const searchService = require('../../src/services/search/services/search');
|
||||
const BNote = require('../../src/becca/entities/bnote');
|
||||
const BBranch = require('../../src/becca/entities/bbranch');
|
||||
const BNote = require('../../src/becca/entities/bnote.js');
|
||||
const BBranch = require('../../src/becca/entities/bbranch.js');
|
||||
const SearchContext = require('../../src/services/search/search_context');
|
||||
const dateUtils = require('../../src/services/date_utils');
|
||||
const becca = require('../../src/becca/becca');
|
||||
const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking');
|
||||
const becca = require('../../src/becca/becca.js');
|
||||
const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking.js');
|
||||
|
||||
describe("Search", () => {
|
||||
let rootNote;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const {note} = require('./becca_mocking');
|
||||
const {note} = require('./becca_mocking.js');
|
||||
const ValueExtractor = require('../../src/services/search/value_extractor');
|
||||
const becca = require('../../src/becca/becca');
|
||||
const SearchContext = require("../../src/services/search/search_context");
|
||||
const becca = require('../../src/becca/becca.js');
|
||||
const SearchContext = require('../../src/services/search/search_context');
|
||||
|
||||
const dsc = new SearchContext();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const anonymizationService = require('./services/anonymization');
|
||||
const sqlInit = require('./services/sql_init');
|
||||
import anonymizationService = require('./services/anonymization');
|
||||
import sqlInit = require('./services/sql_init');
|
||||
require('./becca/entity_constructor');
|
||||
|
||||
sqlInit.dbReady.then(async () => {
|
||||
@@ -16,7 +16,7 @@ sqlInit.dbReady.then(async () => {
|
||||
console.log("Anonymization failed.");
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
catch (e: any) {
|
||||
console.error(e.message, e.stack);
|
||||
}
|
||||
|
||||
+14
-14
@@ -1,11 +1,11 @@
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
const favicon = require('serve-favicon');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const helmet = require('helmet');
|
||||
const compression = require('compression');
|
||||
const sessionParser = require('./routes/session_parser');
|
||||
const utils = require('./services/utils');
|
||||
import express = require('express');
|
||||
import path = require('path');
|
||||
import favicon = require('serve-favicon');
|
||||
import cookieParser = require('cookie-parser');
|
||||
import helmet = require('helmet');
|
||||
import compression = require('compression');
|
||||
import sessionParser = require('./routes/session_parser');
|
||||
import utils = require('./services/utils');
|
||||
|
||||
require('./services/handlers');
|
||||
require('./becca/becca_loader');
|
||||
@@ -20,16 +20,16 @@ if (!utils.isElectron()) {
|
||||
app.use(compression()); // HTTP compression
|
||||
}
|
||||
|
||||
app.use(helmet({
|
||||
app.use(helmet.default({
|
||||
hidePoweredBy: false, // errors out in electron
|
||||
contentSecurityPolicy: false,
|
||||
crossOriginEmbedderPolicy: false
|
||||
}));
|
||||
|
||||
app.use(express.text({limit: '500mb'}));
|
||||
app.use(express.json({limit: '500mb'}));
|
||||
app.use(express.raw({limit: '500mb'}));
|
||||
app.use(express.urlencoded({extended: false}));
|
||||
app.use(express.text({ limit: '500mb' }));
|
||||
app.use(express.json({ limit: '500mb' }));
|
||||
app.use(express.raw({ limit: '500mb' }));
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
app.use(cookieParser());
|
||||
app.use(express.static(path.join(__dirname, 'public/root')));
|
||||
app.use(`/manifest.webmanifest`, express.static(path.join(__dirname, 'public/manifest.webmanifest')));
|
||||
@@ -57,4 +57,4 @@ if (utils.isElectron()) {
|
||||
require('@electron/remote/main').initialize();
|
||||
}
|
||||
|
||||
module.exports = app;
|
||||
export = app;
|
||||
@@ -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");
|
||||
const NoteSet = require("../services/search/note_set");
|
||||
const NotFoundError = require("../errors/not_found_error");
|
||||
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 {
|
||||
export default 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 {
|
||||
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,26 @@ 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"); // 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 = {}) {
|
||||
getRevisionOrThrow(revisionId: string): BRevision {
|
||||
const revision = this.getRevision(revisionId);
|
||||
if (!revision) {
|
||||
throw new NotFoundError(`Revision '${revisionId}' has not been found.`);
|
||||
}
|
||||
return revision;
|
||||
}
|
||||
|
||||
getAttachment(attachmentId: string, opts: AttachmentOpts = {}): BAttachment | null {
|
||||
opts.includeContentLength = !!opts.includeContentLength;
|
||||
|
||||
const query = opts.includeContentLength
|
||||
@@ -163,14 +179,13 @@ class Becca {
|
||||
WHERE attachmentId = ? AND isDeleted = 0`
|
||||
: `SELECT * FROM attachments WHERE attachmentId = ? AND isDeleted = 0`;
|
||||
|
||||
const BAttachment = require("./entities/battachment"); // 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 +193,36 @@ class Becca {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
/** @returns {BAttachment[]} */
|
||||
getAttachments(attachmentIds) {
|
||||
const BAttachment = require("./entities/battachment"); // 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"); // 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 +244,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: string[] = []): BRecentNote[] {
|
||||
const rows = sql.getRows(query, params);
|
||||
|
||||
const BRecentNote = require("./entities/brecent_note"); // 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: string[] = []): BRevision[] {
|
||||
const rows = sql.getRows<RevisionRow>(query, params);
|
||||
|
||||
const BRevision = require("./entities/brevision"); // avoiding circular dependency problems
|
||||
const BRevision = require('./entities/brevision'); // avoiding circular dependency problems
|
||||
return rows.map(row => new BRevision(row));
|
||||
}
|
||||
|
||||
@@ -260,8 +271,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 +288,26 @@ class Becca {
|
||||
}
|
||||
}
|
||||
|
||||
const becca = new Becca();
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
export interface ConstructorData<T extends AbstractBeccaEntity<T>> {
|
||||
primaryKeyName: string;
|
||||
entityName: string;
|
||||
hashedProperties: (keyof T)[];
|
||||
}
|
||||
|
||||
module.exports = becca;
|
||||
export interface NotePojo {
|
||||
noteId: string;
|
||||
title?: string;
|
||||
isProtected?: boolean;
|
||||
type: string;
|
||||
mime: string;
|
||||
blobId?: string;
|
||||
isDeleted: boolean;
|
||||
dateCreated?: string;
|
||||
dateModified?: string;
|
||||
utcDateCreated: string;
|
||||
utcDateModified?: string;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import Becca from "./becca-interface";
|
||||
|
||||
const becca = new Becca();
|
||||
|
||||
export = becca;
|
||||
@@ -1,19 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
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");
|
||||
import sql = require('../services/sql');
|
||||
import eventService = require('../services/events');
|
||||
import becca = require('./becca');
|
||||
import sqlInit = require('../services/sql_init');
|
||||
import log = require('../services/log');
|
||||
import BNote = require('./entities/bnote');
|
||||
import BBranch = require('./entities/bbranch');
|
||||
import BAttribute = require('./entities/battribute');
|
||||
import BOption = require('./entities/boption');
|
||||
import BEtapiToken = require('./entities/betapi_token');
|
||||
import cls = require('../services/cls');
|
||||
import entityConstructor = require('../becca/entity_constructor');
|
||||
import { AttributeRow, BranchRow, EtapiTokenRow, NoteRow, OptionRow } from './entities/rows';
|
||||
import AbstractBeccaEntity = require('./entities/abstract_becca_entity');
|
||||
|
||||
const beccaLoaded = new Promise((res, rej) => {
|
||||
const beccaLoaded = new Promise<void>((res, rej) => {
|
||||
sqlInit.dbReady.then(() => {
|
||||
cls.init(() => {
|
||||
load();
|
||||
@@ -38,23 +40,23 @@ function load() {
|
||||
new BNote().update(row).init();
|
||||
}
|
||||
|
||||
const branchRows = sql.getRawRows(`SELECT branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0`);
|
||||
const branchRows = sql.getRawRows<BranchRow>(`SELECT branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0`);
|
||||
// in-memory sort is faster than in the DB
|
||||
branchRows.sort((a, b) => a.notePosition - b.notePosition);
|
||||
branchRows.sort((a, b) => (a.notePosition || 0) - (b.notePosition || 0));
|
||||
|
||||
for (const row of branchRows) {
|
||||
new BBranch().update(row).init();
|
||||
}
|
||||
|
||||
for (const row of sql.getRawRows(`SELECT attributeId, noteId, type, name, value, isInheritable, position, utcDateModified FROM attributes WHERE isDeleted = 0`)) {
|
||||
for (const row of sql.getRawRows<AttributeRow>(`SELECT attributeId, noteId, type, name, value, isInheritable, position, utcDateModified FROM attributes WHERE isDeleted = 0`)) {
|
||||
new BAttribute().update(row).init();
|
||||
}
|
||||
|
||||
for (const row of sql.getRows(`SELECT name, value, isSynced, utcDateModified FROM options`)) {
|
||||
for (const row of sql.getRows<OptionRow>(`SELECT name, value, isSynced, utcDateModified FROM options`)) {
|
||||
new BOption(row);
|
||||
}
|
||||
|
||||
for (const row of sql.getRows(`SELECT etapiTokenId, name, tokenHash, utcDateCreated, utcDateModified FROM etapi_tokens WHERE isDeleted = 0`)) {
|
||||
for (const row of sql.getRows<EtapiTokenRow>(`SELECT etapiTokenId, name, tokenHash, utcDateCreated, utcDateModified FROM etapi_tokens WHERE isDeleted = 0`)) {
|
||||
new BEtapiToken(row);
|
||||
}
|
||||
});
|
||||
@@ -68,13 +70,13 @@ function load() {
|
||||
log.info(`Becca (note cache) load took ${Date.now() - start}ms`);
|
||||
}
|
||||
|
||||
function reload(reason) {
|
||||
function reload(reason: string) {
|
||||
load();
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -88,7 +90,7 @@ eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED], ({entity
|
||||
if (beccaEntity) {
|
||||
beccaEntity.updateFromRow(entityRow);
|
||||
} else {
|
||||
beccaEntity = new EntityClass();
|
||||
beccaEntity = new EntityClass() as AbstractBeccaEntity<AbstractBeccaEntity<any>>;
|
||||
beccaEntity.updateFromRow(entityRow);
|
||||
beccaEntity.init();
|
||||
}
|
||||
@@ -97,7 +99,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;
|
||||
}
|
||||
@@ -112,7 +114,7 @@ eventService.subscribeBeccaLoader(eventService.ENTITY_CHANGED, ({entityName, en
|
||||
* @param entityRow - can be a becca entity (change comes from this trilium instance) or just a row (from sync).
|
||||
* It should be therefore treated as a row.
|
||||
*/
|
||||
function postProcessEntityUpdate(entityName, entityRow) {
|
||||
function postProcessEntityUpdate(entityName: string, entityRow: any) {
|
||||
if (entityName === 'notes') {
|
||||
noteUpdated(entityRow);
|
||||
} else if (entityName === 'branches') {
|
||||
@@ -124,7 +126,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;
|
||||
}
|
||||
@@ -140,13 +142,13 @@ eventService.subscribeBeccaLoader([eventService.ENTITY_DELETED, eventService.ENT
|
||||
}
|
||||
});
|
||||
|
||||
function noteDeleted(noteId) {
|
||||
function noteDeleted(noteId: string) {
|
||||
delete becca.notes[noteId];
|
||||
|
||||
becca.dirtyNoteSetCache();
|
||||
}
|
||||
|
||||
function branchDeleted(branchId) {
|
||||
function branchDeleted(branchId: string) {
|
||||
const branch = becca.branches[branchId];
|
||||
|
||||
if (!branch) {
|
||||
@@ -173,23 +175,26 @@ function branchDeleted(branchId) {
|
||||
}
|
||||
|
||||
delete becca.childParentToBranch[`${branch.noteId}-${branch.parentNoteId}`];
|
||||
delete becca.branches[branch.branchId];
|
||||
}
|
||||
|
||||
function noteUpdated(entityRow) {
|
||||
const note = becca.notes[entityRow.noteId];
|
||||
|
||||
if (note) {
|
||||
// type / mime could have been changed, and they are present in flatTextCache
|
||||
note.flatTextCache = null;
|
||||
if (branch.branchId) {
|
||||
delete becca.branches[branch.branchId];
|
||||
}
|
||||
}
|
||||
|
||||
function branchUpdated(branchRow) {
|
||||
function noteUpdated(entityRow: NoteRow) {
|
||||
const note = becca.notes[entityRow.noteId];
|
||||
|
||||
if (note) {
|
||||
// TODO, this wouldn't have worked in the original implementation since the variable was named __flatTextCache.
|
||||
// type / mime could have been changed, and they are present in flatTextCache
|
||||
note.__flatTextCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
function branchUpdated(branchRow: BranchRow) {
|
||||
const childNote = becca.notes[branchRow.noteId];
|
||||
|
||||
if (childNote) {
|
||||
childNote.flatTextCache = null;
|
||||
childNote.__flatTextCache = null;
|
||||
childNote.sortParents();
|
||||
|
||||
// notes in the subtree can get new inherited attributes
|
||||
@@ -204,7 +209,7 @@ function branchUpdated(branchRow) {
|
||||
}
|
||||
}
|
||||
|
||||
function attributeDeleted(attributeId) {
|
||||
function attributeDeleted(attributeId: string) {
|
||||
const attribute = becca.attributes[attributeId];
|
||||
|
||||
if (!attribute) {
|
||||
@@ -239,8 +244,7 @@ function attributeDeleted(attributeId) {
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {BAttribute} attributeRow */
|
||||
function attributeUpdated(attributeRow) {
|
||||
function attributeUpdated(attributeRow: BAttribute) {
|
||||
const attribute = becca.attributes[attributeRow.attributeId];
|
||||
const note = becca.notes[attributeRow.noteId];
|
||||
|
||||
@@ -253,7 +257,7 @@ function attributeUpdated(attributeRow) {
|
||||
}
|
||||
}
|
||||
|
||||
function noteReorderingUpdated(branchIdList) {
|
||||
function noteReorderingUpdated(branchIdList: number[]) {
|
||||
const parentNoteIds = new Set();
|
||||
|
||||
for (const branchId in branchIdList) {
|
||||
@@ -267,7 +271,7 @@ function noteReorderingUpdated(branchIdList) {
|
||||
}
|
||||
}
|
||||
|
||||
function etapiTokenDeleted(etapiTokenId) {
|
||||
function etapiTokenDeleted(etapiTokenId: string) {
|
||||
delete becca.etapiTokens[etapiTokenId];
|
||||
}
|
||||
|
||||
@@ -275,14 +279,14 @@ eventService.subscribeBeccaLoader(eventService.ENTER_PROTECTED_SESSION, () => {
|
||||
try {
|
||||
becca.decryptProtectedNotes();
|
||||
}
|
||||
catch (e) {
|
||||
catch (e: any) {
|
||||
log.error(`Could not decrypt protected notes: ${e.message} ${e.stack}`);
|
||||
}
|
||||
});
|
||||
|
||||
eventService.subscribeBeccaLoader(eventService.LEAVE_PROTECTED_SESSION, load);
|
||||
|
||||
module.exports = {
|
||||
export = {
|
||||
load,
|
||||
reload,
|
||||
beccaLoaded
|
||||
@@ -1,10 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
const becca = require('./becca');
|
||||
const cls = require('../services/cls');
|
||||
const log = require('../services/log');
|
||||
import becca = require('./becca');
|
||||
import cls = require('../services/cls');
|
||||
import log = require('../services/log');
|
||||
|
||||
function isNotePathArchived(notePath) {
|
||||
function isNotePathArchived(notePath: string[]) {
|
||||
const noteId = notePath[notePath.length - 1];
|
||||
const note = becca.notes[noteId];
|
||||
|
||||
@@ -24,9 +24,9 @@ function isNotePathArchived(notePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getNoteTitle(childNoteId, parentNoteId) {
|
||||
function getNoteTitle(childNoteId: string, parentNoteId?: string) {
|
||||
const childNote = becca.notes[childNoteId];
|
||||
const parentNote = becca.notes[parentNoteId];
|
||||
const parentNote = parentNoteId ? becca.notes[parentNoteId] : null;
|
||||
|
||||
if (!childNote) {
|
||||
log.info(`Cannot find note '${childNoteId}'`);
|
||||
@@ -40,7 +40,7 @@ function getNoteTitle(childNoteId, parentNoteId) {
|
||||
return `${(branch && branch.prefix) ? `${branch.prefix} - ` : ''}${title}`;
|
||||
}
|
||||
|
||||
function getNoteTitleArrayForPath(notePathArray) {
|
||||
function getNoteTitleArrayForPath(notePathArray: string[]) {
|
||||
if (!notePathArray || !Array.isArray(notePathArray)) {
|
||||
throw new Error(`${notePathArray} is not an array.`);
|
||||
}
|
||||
@@ -76,13 +76,13 @@ function getNoteTitleArrayForPath(notePathArray) {
|
||||
return titles;
|
||||
}
|
||||
|
||||
function getNoteTitleForPath(notePathArray) {
|
||||
function getNoteTitleForPath(notePathArray: string[]) {
|
||||
const titles = getNoteTitleArrayForPath(notePathArray);
|
||||
|
||||
return titles.join(' / ');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export = {
|
||||
getNoteTitle,
|
||||
getNoteTitleForPath,
|
||||
isNotePathArchived
|
||||
+101
-80
@@ -1,66 +1,77 @@
|
||||
"use strict";
|
||||
|
||||
const utils = require('../../services/utils');
|
||||
const sql = require('../../services/sql');
|
||||
const entityChangesService = require('../../services/entity_changes');
|
||||
const eventService = require("../../services/events");
|
||||
const dateUtils = require("../../services/date_utils");
|
||||
const cls = require("../../services/cls");
|
||||
const log = require("../../services/log");
|
||||
const protectedSessionService = require("../../services/protected_session");
|
||||
const blobService = require("../../services/blob");
|
||||
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, { ConstructorData } from '../becca-interface';
|
||||
|
||||
let becca = null;
|
||||
let becca: Becca;
|
||||
|
||||
interface ContentOpts {
|
||||
forceSave?: boolean;
|
||||
forceFrontendReload?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>> {
|
||||
|
||||
utcDateModified?: string;
|
||||
dateCreated?: string;
|
||||
dateModified?: string;
|
||||
|
||||
utcDateCreated!: 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');
|
||||
}
|
||||
|
||||
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 +81,40 @@ 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(): {};
|
||||
|
||||
init() {
|
||||
// Do nothing by default, can be overriden in derived classes.
|
||||
}
|
||||
|
||||
abstract updateFromRow(row: unknown): void;
|
||||
|
||||
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;
|
||||
// TODO: opts not used but called a few times, maybe should be used by derived classes or passed to beforeSaving.
|
||||
save(opts?: {}): this {
|
||||
const constructorData = (this.constructor as unknown as ConstructorData<T>);
|
||||
const entityName = constructorData.entityName;
|
||||
const primaryKeyName = constructorData.primaryKeyName;
|
||||
|
||||
const isNewEntity = !this[primaryKeyName];
|
||||
|
||||
this.beforeSaving(opts);
|
||||
const isNewEntity = !(this as any)[primaryKeyName];
|
||||
|
||||
this.beforeSaving();
|
||||
|
||||
const pojo = this.getPojoToSave();
|
||||
|
||||
@@ -124,14 +144,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 +160,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 +208,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 +220,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 +267,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 +309,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 +327,4 @@ class AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AbstractBeccaEntity;
|
||||
export = AbstractBeccaEntity;
|
||||
@@ -1,30 +1,64 @@
|
||||
"use strict";
|
||||
|
||||
const utils = require('../../services/utils');
|
||||
const dateUtils = require('../../services/date_utils');
|
||||
const AbstractBeccaEntity = require("./abstract_becca_entity");
|
||||
const sql = require("../../services/sql");
|
||||
const protectedSessionService = require("../../services/protected_session");
|
||||
const log = require("../../services/log");
|
||||
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'
|
||||
'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 | null;
|
||||
/** optionally added to the entity */
|
||||
contentLength?: number;
|
||||
isDecrypted?: boolean;
|
||||
|
||||
constructor(row: AttachmentRow) {
|
||||
super();
|
||||
|
||||
this.updateFromRow(row);
|
||||
this.decrypt();
|
||||
}
|
||||
|
||||
updateFromRow(row: AttachmentRow): void {
|
||||
if (!row.ownerId?.trim()) {
|
||||
throw new Error("'ownerId' must be given to initialize a Attachment entity");
|
||||
} else if (!row.role?.trim()) {
|
||||
@@ -35,43 +69,21 @@ 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,
|
||||
@@ -82,14 +94,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() {
|
||||
@@ -110,33 +121,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() {
|
||||
return this._getContent();
|
||||
getContent(): Buffer {
|
||||
return this._getContent() as Buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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`);
|
||||
}
|
||||
|
||||
@@ -158,7 +162,7 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
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
|
||||
@@ -170,6 +174,11 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
|
||||
if (this.role === 'image' && parentNote.type === 'text') {
|
||||
const origContent = parentNote.getContent();
|
||||
|
||||
if (typeof origContent !== "string") {
|
||||
throw new Error(`Note with ID '${note.noteId} has a text type but non-string content.`);
|
||||
}
|
||||
|
||||
const oldAttachmentUrl = `api/attachments/${this.attachmentId}/image/`;
|
||||
const newNoteUrl = `api/images/${note.noteId}/`;
|
||||
|
||||
@@ -195,9 +204,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();
|
||||
@@ -210,7 +219,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,
|
||||
@@ -228,7 +237,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
|
||||
@@ -240,4 +249,4 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BAttachment;
|
||||
export = BAttachment;
|
||||
@@ -1,30 +1,34 @@
|
||||
"use strict";
|
||||
|
||||
const BNote = require('./bnote');
|
||||
const AbstractBeccaEntity = require("./abstract_becca_entity");
|
||||
const sql = require("../../services/sql");
|
||||
const dateUtils = require("../../services/date_utils");
|
||||
const promotedAttributeDefinitionParser = require("../../services/promoted_attribute_definition_parser");
|
||||
const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name");
|
||||
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;
|
||||
@@ -129,9 +125,6 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {BNote|null}
|
||||
*/
|
||||
getNote() {
|
||||
const note = this.becca.getNote(this.noteId);
|
||||
|
||||
@@ -142,9 +135,6 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
return note;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {BNote|null}
|
||||
*/
|
||||
getTargetNote() {
|
||||
if (this.type !== 'relation') {
|
||||
throw new Error(`Attribute '${this.attributeId}' is not a relation.`);
|
||||
@@ -157,9 +147,6 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
return this.becca.getNote(this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isDefinition() {
|
||||
return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
|
||||
}
|
||||
@@ -182,12 +169,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 +213,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 +226,4 @@ class BAttribute extends AbstractBeccaEntity {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BAttribute;
|
||||
export = BAttribute;
|
||||
@@ -1,25 +1,35 @@
|
||||
class BBlob {
|
||||
import AbstractBeccaEntity = require("./abstract_becca_entity");
|
||||
import { BlobRow } from "./rows";
|
||||
|
||||
// TODO: Why this does not extend the abstract becca?
|
||||
class BBlob extends AbstractBeccaEntity<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) {
|
||||
super();
|
||||
this.updateFromRow(row);
|
||||
}
|
||||
|
||||
updateFromRow(row: BlobRow): void {
|
||||
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 +37,4 @@ class BBlob {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BBlob;
|
||||
export = BBlob;
|
||||
@@ -1,12 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
const BNote = require('./bnote');
|
||||
const AbstractBeccaEntity = require("./abstract_becca_entity");
|
||||
const dateUtils = require("../../services/date_utils");
|
||||
const utils = require("../../services/utils");
|
||||
const TaskContext = require("../../services/task_context");
|
||||
const cls = require("../../services/cls");
|
||||
const log = require("../../services/log");
|
||||
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");
|
||||
*
|
||||
* 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));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,8 +127,6 @@ class BBranch extends AbstractBeccaEntity {
|
||||
* An example is shared or bookmarked clones - they are created automatically and exist for technical reasons,
|
||||
* not as user-intended actions. From user perspective, they don't count as real clones and for the purpose
|
||||
* of deletion should not act as a clone.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
get isWeak() {
|
||||
return ['_share', '_lbBookmarks'].includes(this.parentNoteId);
|
||||
@@ -138,12 +135,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 +157,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");
|
||||
const handlers = require('../../services/handlers');
|
||||
handlers.runAttachedRelations(note, 'runOnNoteDeletion', note);
|
||||
}
|
||||
}
|
||||
@@ -182,7 +178,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 +220,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,17 +265,19 @@ class BBranch extends AbstractBeccaEntity {
|
||||
};
|
||||
}
|
||||
|
||||
createClone(parentNoteId, notePosition) {
|
||||
createClone(parentNoteId: string, notePosition?: number) {
|
||||
const existingBranch = this.becca.getBranchFromChildAndParent(this.noteId, parentNoteId);
|
||||
|
||||
if (existingBranch) {
|
||||
existingBranch.notePosition = notePosition;
|
||||
if (notePosition) {
|
||||
existingBranch.notePosition = notePosition;
|
||||
}
|
||||
return existingBranch;
|
||||
} else {
|
||||
return new BBranch({
|
||||
noteId: this.noteId,
|
||||
parentNoteId: parentNoteId,
|
||||
notePosition: notePosition,
|
||||
notePosition: notePosition || null,
|
||||
prefix: this.prefix,
|
||||
isExpanded: this.isExpanded
|
||||
});
|
||||
@@ -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');
|
||||
const AbstractBeccaEntity = require("./abstract_becca_entity");
|
||||
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");
|
||||
*
|
||||
* 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;
|
||||
@@ -71,8 +74,10 @@ class BEtapiToken extends AbstractBeccaEntity {
|
||||
|
||||
super.beforeSaving();
|
||||
|
||||
this.becca.etapiTokens[this.etapiTokenId] = this;
|
||||
if (this.etapiTokenId) {
|
||||
this.becca.etapiTokens[this.etapiTokenId] = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BEtapiToken;
|
||||
export = BEtapiToken;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user