Compare commits

...

662 Commits

Author SHA1 Message Date
zadam
0948853539 release 0.63.3 2024-03-03 06:58:18 +01:00
zadam
0ad337c8e8 add API method to erase a revision #4662 2024-03-03 06:34:43 +01:00
zadam
9565b0b43d Merge pull request #4671 from AlexeiKharchev/master
Reduce warnings count caused by bin/copy-trilium.sh
2024-03-03 06:26:18 +01:00
zadam
a115b14136 fix highlighting search results with regexp characters in fulltext string, closes #4665 2024-03-02 07:35:52 +01:00
Alexei Kharchev
bb8bfc61ed Improved scriptes bin/copy-trilium.sh, bin/build-linux-x64.sh 2024-03-02 14:18:39 +08:00
zadam
2d19f073d9 fix searching fulltext with tags, closes #4661 2024-03-02 07:13:02 +01:00
Alexei Kharchev
ff5d5d20d9 Reduce warnings count caused by bin/copy-trilium.sh 2024-03-02 11:49:17 +08:00
zadam
1f95e88cfd release 0.63.2-beta 2024-02-17 22:47:50 +01:00
zadam
15677f7178 Update README.md 2024-02-16 12:16:58 +01:00
zadam
3a0bb91b77 fix 2024-02-16 11:25:23 +01:00
zadam
157f894c9b Merge pull request #4642 from henrikx/patch-1
Fix ribbon tooltips getting stuck on the screen by setting a small delay before saving attributes in attributeeditor
2024-02-16 11:02:13 +01:00
zadam
e6dec701c0 Merge remote-tracking branch 'origin/master' 2024-02-16 10:42:30 +01:00
zadam
450b52f6da JSDoc improvements 2024-02-16 10:42:25 +01:00
zadam
4ef31eaf3d Merge pull request #4635 from WantToLearnJapanese/WantToLearnJapanese-patch-unhoist-bookmark
Fix showing unhoist confirm dialogue for bookmarked notes.
2024-02-16 06:48:04 +01:00
zadam
2d865576cf Merge remote-tracking branch 'origin/master' 2024-02-16 06:46:38 +01:00
zadam
41e623b009 fix JSDoc, closes #4633 2024-02-16 06:46:32 +01:00
zadam
239786e7d1 Merge pull request #4632 from bavis-m/master
Add the -o option to the groupmod command used in start-docker.sh
2024-02-16 06:40:38 +01:00
zadam
89e1e47900 Merge remote-tracking branch 'origin/master' 2024-02-14 07:21:36 +01:00
zadam
67cb926233 PWA manifest fixes for extra auth, fixes #4611 2024-02-14 07:21:31 +01:00
henrikx
2f813dfc5d Update attribute_editor.js 2024-02-09 10:58:41 +01:00
WantToLearnJapanese
a939599223 Fix showing unhoist confirm dialogue for bookmarked notes. 2024-02-02 16:36:54 +09:00
Mark
fb10e0ad33 Add the -o option to the groupmod command used in start-docker.sh when USER_GID is set, otherwise we won't be added to existing groups (e.g. you want node to run in the users (100) group) 2024-02-01 11:56:37 -08:00
zadam
46bd5bc1ef Update README.md 2024-01-29 22:36:52 +01:00
zadam
5abfb5c08a revert unintended license changes 2024-01-28 23:09:57 +01:00
zadam
9357caeb5a activate parent note when deleting a note, #4601 2024-01-28 23:08:44 +01:00
zadam
6b58e59819 added keyboard shortcut for toggling the right pane, closes #4552 2024-01-28 08:58:40 +01:00
zadam
c6df25ece8 fix pin button shadow, closes #4595 2024-01-28 08:36:16 +01:00
zadam
ebd6276b5e CKEditor 41.0.0 2024-01-27 23:02:11 +01:00
zadam
92e8b155e4 Merge branch 'stable'
# Conflicts:
#	package.json
#	src/services/build.js
#	src/services/migration.js
2024-01-27 22:52:47 +01:00
zadam
e76093e75c release 0.62.6 2024-01-21 23:49:23 +01:00
zadam
4f8073daa7 Revert "don't tag beta images with latest #4590"
This reverts commit 47fb96faa8.
2024-01-21 23:48:56 +01:00
zadam
47fb96faa8 don't tag beta images with latest #4590 2024-01-21 23:42:57 +01:00
zadam
6e33553146 fix migration 2024-01-21 23:11:27 +01:00
zadam
807941e6a5 disable scanning for links while migration is running #4535 2024-01-21 20:50:38 +01:00
zadam
1e30c0702e add indexes sooner in the migration process to speed it up #4535 2024-01-21 11:13:45 +01:00
zadam
69b686ba3b basic emoji #4119 2024-01-21 10:44:23 +01:00
zadam
ace5660809 add special characters to CKEditor build #4119 2024-01-21 10:33:16 +01:00
zadam
8bc99fd799 downgrades to try to fix flatpak build 2024-01-12 00:17:04 +01:00
zadam
f0c3a090a2 release 0.63.1-beta 2024-01-12 00:02:50 +01:00
zadam
17e063f01d updates 2024-01-12 00:02:45 +01:00
zadam
76c9873705 fix erase sync 2024-01-10 23:51:53 +01:00
zadam
2c7b774356 Merge branch 'stable' 2024-01-10 22:57:05 +01:00
zadam
390ad6d813 fix rendering image title in share renderer, closes #4578 2024-01-09 23:38:44 +01:00
zadam
77800d073f fix URL unescaping in improper place, #4566 2024-01-09 23:22:45 +01:00
zadam
1953c7896f support SVG image upload, fixes #4573 2024-01-09 23:13:33 +01:00
zadam
dff4f73366 Merge pull request #4571 from Nriver/master
fix typo in keyboard shortcuts description
2024-01-09 22:53:41 +01:00
zadam
cd43752f61 remove conflicting shortcut, fixes #4570 2024-01-09 22:52:13 +01:00
Nriver
23a5cea338 fix typo in keyboard shortcuts description 2024-01-08 10:20:23 +08:00
zadam
e2cb3c0d14 Merge branch 'stable'
# Conflicts:
#	package.json
#	src/services/build.js
#	src/services/notes.js
2024-01-08 00:21:46 +01:00
zadam
d6046efa1b release 0.62.5 2024-01-08 00:05:13 +01:00
zadam
ee608fcf46 unescape HTML before downloading images, #4566 2024-01-08 00:03:11 +01:00
zadam
894b08a1b8 correctly save attachment URL, #4566 2024-01-07 23:51:38 +01:00
zadam
4e549baedc fix auto-download of images, closes #4566 2024-01-07 23:45:40 +01:00
zadam
6b6e42e9ba document attachment ETAPI APIs in OpenAPI spec, fixes #4559 2024-01-07 23:11:55 +01:00
zadam
0404b78fb8 fix loading katex in share #4558 2024-01-07 22:52:16 +01:00
zadam
d63d42d87c Merge branch 'stable' 2024-01-07 22:46:23 +01:00
zadam
37baa4cd74 Merge pull request #4550 from spasche/zip-export-sort-children
sort children during export to ensure a more stable format
2024-01-07 22:38:14 +01:00
zadam
68e03c434e release 0.63.0-beta 2024-01-04 00:49:06 +01:00
zadam
394530921e downgrade electron 2024-01-03 23:50:29 +01:00
zadam
57ccd5a954 stronger light anonymization 2024-01-03 22:10:29 +01:00
zadam
a28d8843ac fix migration 2024-01-03 22:08:26 +01:00
Sylvain Pasche
cb523faaad sort children during export to ensure a more stable format 2023-12-31 16:52:19 +01:00
zadam
f704cacdee bugfixes to sync 2023-12-30 00:34:46 +01:00
zadam
8dbc592563 add "copy image" context menu to also attachments, fixes #4514 2023-12-28 00:02:09 +01:00
zadam
439743d2b0 convert absolute image attachment URLs to relative without domain, fixes #4509 2023-12-27 23:22:40 +01:00
zadam
a3783131a2 Merge pull request #4522 from Nriver/master
fix decoding issue for request data chunks
2023-12-27 22:58:27 +01:00
zadam
33af9a3595 updates 2023-12-27 22:48:16 +01:00
Nriver
30c3c10524 fix decoding issue for request data chunks 2023-12-14 11:10:13 +08:00
zadam
df85a5eee4 Merge branch 'stable'
# Conflicts:
#	src/routes/api/revisions.js
#	src/services/bulk_actions.js
2023-12-11 23:07:15 +01:00
zadam
0ac397e7ff fix setNoteToParent API breakage, closes #4505 2023-12-11 23:05:05 +01:00
zadam
d243880099 release 0.62.4 2023-12-07 00:03:59 +01:00
zadam
2e23c521c3 electron upgrade 2023-12-06 23:54:17 +01:00
zadam
eb761b286f electron upgrade 2023-12-04 00:17:00 +01:00
zadam
d0f6ff5f98 fix erasing revisions 2023-12-04 00:11:24 +01:00
zadam
c35167f2f5 sometimes CPU info is not available #3957 2023-12-03 21:37:50 +01:00
zadam
84feaabc52 release 0.62.3 2023-11-27 23:37:24 +01:00
zadam
a6036859b8 normalize strings before calculation hashes, #4435 2023-11-27 23:23:55 +01:00
zadam
929f7f3114 add node version to app_info 2023-11-27 23:12:22 +01:00
zadam
9e914b9016 remove relation map from the demo document 2023-11-27 10:54:38 +01:00
zadam
947627d8a0 relation map deprecation - don't show it in menu to create new note 2023-11-27 10:50:17 +01:00
zadam
ed00797179 Merge branch 'stable'
# Conflicts:
#	package-lock.json
2023-11-27 10:41:07 +01:00
zadam
93dcce2217 dragging notes from note tree will automatically insert them as images where appropriate (image, canvas, mermaid) 2023-11-27 10:38:19 +01:00
zadam
686af0c6a1 when canvas and mermaid are inserted using "include note", we insert them as images 2023-11-27 10:22:54 +01:00
zadam
d07f02b95f contrary to what I believed encodeURIComponent() is available also in node.js, #4478 2023-11-27 10:15:29 +01:00
zadam
ad74952194 fix thumbnails with chinese titles, closes #4478 2023-11-27 10:10:27 +01:00
zadam
10f3df3ed4 make sure content is string for post-processing 2023-11-26 23:51:04 +01:00
zadam
18e2e6779b remove title to fix closing highlights list, fixes #4471 2023-11-24 23:51:12 +01:00
zadam
ed129c307b fix printing math, closes #4470 2023-11-24 00:17:20 +01:00
zadam
8742e4bfe9 make sure the promoted attributes don't take the whole screen in mobile, #4468 2023-11-24 00:04:49 +01:00
zadam
3b10bb742b pin versions 2023-11-22 20:46:20 +01:00
zadam
1f206a9c24 load panzoom from node_modules 2023-11-22 20:28:17 +01:00
zadam
f026646bb5 load split.js from node_modules 2023-11-22 20:26:20 +01:00
zadam
f9bfc8ad86 load printThis from node_modules 2023-11-22 20:22:16 +01:00
zadam
e70539ff48 load jquery-hotkeys from node_modules 2023-11-22 20:15:21 +01:00
zadam
a439be79b3 load jquery from node_modules 2023-11-22 20:11:41 +01:00
zadam
edf2dfe8f9 load mermaid from node_modules 2023-11-22 20:09:04 +01:00
zadam
0e4c49ea5b load box icons from node_modules 2023-11-22 20:06:44 +01:00
zadam
52cfd138d1 load force-graph from node_modules 2023-11-22 20:02:35 +01:00
zadam
258b97f833 Merge remote-tracking branch 'origin/master' 2023-11-22 19:58:59 +01:00
zadam
837b17d62a load day.js from node_modules 2023-11-22 19:58:54 +01:00
zadam
d82720f62f Merge pull request #4461 from Nriver/master
fix typo
2023-11-22 19:47:48 +01:00
zadam
cf99345962 use .js extension for require() as a preparation for future migration to ESM 2023-11-22 19:34:48 +01:00
Nriver
9e54496d00 fix more typo 2023-11-22 10:41:44 +08:00
Nriver
8ae6598b8a fix typo 2023-11-22 10:37:23 +08:00
zadam
722299dd26 release 0.62.2 2023-11-21 20:49:24 +01:00
zadam
e2b1421bf3 electron upgrade 2023-11-21 20:48:43 +01:00
zadam
1f41d39bc7 docs 2023-11-21 20:46:48 +01:00
zadam
ce39d3b4ce Merge branch 'stable'
# Conflicts:
#	docs/backend_api/BNote.html
#	docs/backend_api/BackendScriptApi.html
#	docs/backend_api/services_backend_script_api.js.html
#	docs/frontend_api/FAttribute.html
#	docs/frontend_api/FBranch.html
#	docs/frontend_api/FNote.html
#	docs/frontend_api/FrontendScriptApi.html
#	docs/frontend_api/entities_fattachment.js.html
#	docs/frontend_api/entities_fattribute.js.html
#	docs/frontend_api/entities_fblob.js.html
#	docs/frontend_api/entities_fbranch.js.html
#	docs/frontend_api/entities_fnote.js.html
#	docs/frontend_api/global.html
#	docs/frontend_api/index.html
#	docs/frontend_api/services_frontend_script_api.js.html
#	package.json
#	src/services/backend_script_api.js
#	src/services/build.js
2023-11-21 20:46:24 +01:00
zadam
ef2ade849b release 0.61.15 2023-11-20 23:23:12 +01:00
zadam
88067c071c add api.backupNow() to backend API, closes #4455 2023-11-20 23:14:53 +01:00
zadam
f5018e9820 fix buggy http proxy initialization, closes #4453 2023-11-20 23:03:19 +01:00
zadam
1561f402f0 ckeditor 40.1.0 2023-11-20 22:29:05 +01:00
zadam
0d7889d212 Merge branch 'stable'
# Conflicts:
#	package-lock.json
2023-11-20 22:22:05 +01:00
zadam
19a10e59e9 fix edit history crossing note activation in canvas, #4437 2023-11-20 22:13:52 +01:00
zadam
746abb02d3 Merge branch 'stable'
# Conflicts:
#	package-lock.json
#	package.json
#	src/services/build.js
2023-11-16 23:57:25 +01:00
zadam
23351298c8 fix incorrect syntax/typo, closes #4443 2023-11-16 23:35:50 +01:00
zadam
426a8f75aa fix creating tree cycle by moving clone into another clone, closes #4442 2023-11-16 23:31:33 +01:00
zadam
999cf0d9e3 release 0.61.14 2023-11-16 00:21:34 +01:00
zadam
0afc41060a template LABEL should not be inherited #4349 2023-11-16 00:11:14 +01:00
zadam
6e2d76c2b4 release 0.62.1-beta 2023-11-14 00:57:51 +01:00
zadam
3abf74a9f3 fix katex CSS loading 2023-11-14 00:57:19 +01:00
zadam
5d52498da1 Merge branch 'stable' 2023-11-14 00:19:15 +01:00
zadam
cf068211ff change the way frontend detects content change which works even if no new blob is created, fixes #4434 2023-11-13 23:53:14 +01:00
zadam
0507c46ae9 revert general HTML support 2023-11-13 00:58:55 +01:00
zadam
69ed3644f9 add a note about hideHighlightWidget to options 2023-11-13 00:39:28 +01:00
zadam
b0c5894691 added hideHighlightWidget to built in attributes 2023-11-13 00:36:08 +01:00
zadam
f10fc7bd7f Revert "Add attribute disableHighlightsList to disable Highlights List Widget"
This reverts commit e7d98206f9.
2023-11-13 00:34:09 +01:00
zadam
bdbaacaac9 Merge pull request #4421 from fang64/master
Add attribute disableHighlightsList to disable Highlights List Widget
2023-11-13 00:31:00 +01:00
zadam
2790f52e36 Merge pull request #4417 from ljgonzalez1/master
Migrate KaTeX@0.16.0 from `libraries` to KaTeX@0.16.9 in `node_modules`
2023-11-13 00:29:15 +01:00
zadam
6515dd7b23 fix assigning extension to attachment export filenames, closes #4415 2023-11-12 23:57:21 +01:00
zadam
5a38bf78e1 fix content renderer of protected canvas/mermaid notes, closes #4414 2023-11-12 23:43:04 +01:00
zadam
4bdb40904f fix loading reference link titles in read-only text notes, closes #4404 2023-11-12 22:57:04 +01:00
fang64
e7d98206f9 Add attribute disableHighlightsList to disable Highlights List Widget 2023-11-09 21:32:45 -05:00
Luis González
1939375161 Merge pull request #3 from ljgonzalez1/feat/migrate_katex_to_npm_v2
Feat/migrate katex to npm
2023-11-09 19:06:25 -03:00
Luis González
ec737d02b2 feat(src/routes/assets.js): Add KaTex support to assets route. 2023-11-09 18:33:36 -03:00
Luis González
927e5ede0c feat(src/routes/assets.js): Add KaTex support to assets route. 2023-11-09 18:21:53 -03:00
Luis González
3470347523 feat(package.json & package-lock.json): Add 'katex' package and update project version 2023-11-09 14:23:39 -03:00
Luis González
e25c86e947 Revert "🙈 gitignore" commits.
This reverts commits 30bd216500, 9a587e8c8c, 38e6008aa2, 5af1c7756c and c8d6f20c3b.

It reverts pr #2 from my branch
2023-11-09 13:16:50 -03:00
Luis González
fb1478f2dd Merge pull request #2
Add OS and IDE files to the gitignore + Add documentation
2023-11-09 12:07:12 -03:00
Luis González
c8d6f20c3b 🙈 gitignore(.gitignore): Include macOS and Linux system files 2023-11-09 11:59:04 -03:00
Luis González
5af1c7756c 🙈 gitignore(.idea/.gitignore): Ignore IntelliJ IDE specific files 2023-11-09 11:55:54 -03:00
Luis González
38e6008aa2 🙈 gitignore: Expand to ignore JetBrains IDEs, VisualStudioCode, and Kate templates. 2023-11-09 11:55:52 -03:00
Luis González
9a587e8c8c 🙈 gitignore: Add rules to maintain empty folders and all gitignore files. 2023-11-09 11:55:33 -03:00
Luis González
30bd216500 🙈 gitignore: Update documentation in gitignore and sort ignored folder/files by category. 2023-11-09 11:42:07 -03:00
Luis González
a3ce5b5d28 Merge pull request #1 from ljgonzalez1/feat/update_katex_0.16.9
Update Katex from 0.16.0 to 0.16.9
2023-11-08 17:16:59 -03:00
Luis González
b17848609b Update Katex from 0.16.0 to 0.16.9 2023-11-08 17:15:15 -03:00
zadam
e9ece21d20 release 0.62.0-beta 2023-11-06 23:13:25 +01:00
zadam
b700f069fe reduce flickering while hoisted 2023-11-06 23:11:57 +01:00
zadam
40fb6aa168 move the unhoist button to the right 2023-11-06 22:28:25 +01:00
zadam
341480e7cf scroll padding widget only on text and code notes 2023-11-06 22:26:17 +01:00
zadam
bde311fd76 upgrades 2023-11-06 22:23:18 +01:00
zadam
f8bc03feaf Merge branch 'stable' 2023-11-06 22:14:15 +01:00
zadam
7fc1eb5262 release 0.61.13 2023-11-06 00:21:41 +01:00
zadam
531e9d4aff graceful handling of sync error 2023-11-06 00:15:35 +01:00
zadam
e0d4766c2d fix recursion in the inline image processing 2023-11-05 21:50:08 +01:00
zadam
ab4e83771c fix throwing empty error 2023-11-04 22:53:09 +01:00
zadam
803b6df40c release 0.61.12 2023-11-04 00:16:19 +01:00
zadam
1ebdb0f5e1 emergency disabling of image compression since it appears to make problems in migration to 0.61 2023-11-04 00:10:54 +01:00
zadam
df5951ce46 improve sync debug info 2023-11-04 00:02:31 +01:00
zadam
809ffa0c6e small refactor of ordinal() func 2023-11-03 13:49:18 +01:00
zadam
6dd466ddaf updates 2023-11-03 12:23:14 +01:00
zadam
a45b801a84 reverted incomplete work on export per-directory metadata 2023-11-03 12:18:38 +01:00
zadam
f8ade4d0c5 Merge remote-tracking branch 'origin/master' 2023-11-03 12:15:46 +01:00
zadam
889cb1d7b1 Merge branch 'stable'
# Conflicts:
#	package.json
2023-11-03 12:15:39 +01:00
zadam
d3a477b8f2 release 0.61.11 2023-11-03 11:46:53 +01:00
zadam
4db042736c Merge pull request #4371 from rauenzi/pwa-manifest
Update webmanifest for wider compatibility
2023-11-03 11:25:17 +01:00
zadam
612e4406b5 refactored TOC and Highlights close buttons and added a button to quickly access options 2023-11-03 10:44:14 +01:00
zadam
76f874ef6d refactoring of the complex note tree entitiesReloadedEvent 2023-11-03 08:58:57 +01:00
zadam
f37f47ce5b fixes to stable sorting 2023-11-03 01:11:47 +01:00
zadam
45ed436426 added runOnBranchChange event #4108 2023-11-02 23:26:32 +01:00
Zack Rauen
9314cf87c5 Update manifest for wider compatibility
Partially fixes #920
2023-11-01 12:30:01 -04:00
zadam
0efc42081d more tests 2023-11-01 00:41:35 +01:00
zadam
7d80fe19e0 add backend API methods to access options, attachments, revisions, etapi tokens 2023-10-31 22:26:56 +01:00
zadam
de8c351e25 reduce indent of TOC when larger headings are not being used, fixes #4363 2023-10-31 00:18:03 +01:00
zadam
695c9d5cf3 more note etapi tests 2023-10-30 23:51:53 +01:00
zadam
8690228d98 etapi test infrastructure plus a basic note creation test 2023-10-29 23:24:11 +01:00
zadam
01093d05d7 qswitch-electron, qswitch-server npm scripts 2023-10-29 18:39:53 +01:00
zadam
690caf7da1 Merge branch 'beta'
# Conflicts:
#	package-lock.json
#	package.json
2023-10-29 16:43:31 +01:00
zadam
a9b63111ae qstart-electron, qstart-server npm scripts 2023-10-29 16:42:30 +01:00
zadam
eb0a68d0ab note list should show the prefix, #4362 2023-10-29 01:02:55 +02:00
zadam
48e98b2ac3 add api.runAsyncOnBackendWithManualTransactionHandling() variant and add toast warnings about improper usage. 2023-10-29 00:51:23 +02:00
zadam
ed1a731950 extra hint on "noproxy directly in the setting", #3934 2023-10-24 23:15:18 +02:00
zadam
4660c154e9 refactor 2023-10-24 23:10:52 +02:00
zadam
ef974ab1f5 add shell as enabled by default #4347 2023-10-24 23:00:46 +02:00
zadam
bacae67374 fix import 2023-10-24 00:14:15 +02:00
zadam
cc20d17bd2 npm upgrades && docs 2023-10-24 00:13:20 +02:00
zadam
494b240015 Merge branch 'beta'
# Conflicts:
#	src/public/app/layouts/desktop_layout.js
2023-10-24 00:09:37 +02:00
zadam
1cd391a132 mermaid 10.5.1 2023-10-22 23:57:28 +02:00
zadam
1c15527d95 added "greater than 0" and "less than 2" for ancestor depth, fixes #4343 2023-10-22 23:52:21 +02:00
zadam
7af79ec33b limit mermaid width, #4340 2023-10-21 23:24:43 +02:00
zadam
4294c043d8 enabled CKEditor HTML support 2023-10-21 23:19:14 +02:00
zadam
e5b925abf8 added extra elements to the html sanitizer 2023-10-21 18:03:06 +02:00
zadam
90c0a4a437 respect safeImport flag when sanitizing imported content 2023-10-21 17:54:07 +02:00
zadam
692f7868bc updated demo document so that canvas and mermaid have generated export attachments 2023-10-21 17:36:08 +02:00
zadam
5282af55f6 render attachment SVG when sharing mermaid 2023-10-21 17:32:07 +02:00
zadam
aefc4c6bd2 ckeditor 40 2023-10-21 17:24:47 +02:00
zadam
b39ba76505 add ability to insert mermaid diagram into text notes as image 2023-10-21 00:23:16 +02:00
zadam
9d918e7a54 fix image zooming 2023-10-20 23:44:30 +02:00
zadam
4773f9392b don't log known slow queries 2023-10-20 09:36:57 +02:00
zadam
5c10fc26be Merge branch 'beta'
# Conflicts:
#	package.json
#	src/public/app/layouts/desktop_layout.js
2023-10-20 09:15:48 +02:00
zadam
38db7f9db7 style tweaks #4338 2023-10-19 23:54:36 +02:00
zadam
5163e50e7d use mtime instead of ctime for backups #4321 2023-10-19 23:02:37 +02:00
zadam
5115b33446 release 0.61.10-beta 2023-10-19 09:33:51 +02:00
zadam
b01fe5ead9 add canvas properties with a button to copy reference to clipboard which allows inserting canvas as an image into text notes 2023-10-19 09:20:23 +02:00
zadam
b1d4a258a1 move FAB down in canvas 2023-10-19 09:03:49 +02:00
zadam
ca041bb658 fix expanded status when moving note trees 2023-10-19 08:58:04 +02:00
zadam
52244ddc99 Merge branch 'beta'
# Conflicts:
#	docs/backend_api/BAttachment.html
#	docs/backend_api/BNote.html
#	docs/backend_api/BackendScriptApi.html
#	package-lock.json
#	package.json
2023-10-19 01:13:45 +02:00
zadam
87a60e325f added ctime to backup list #4321 2023-10-19 00:51:38 +02:00
zadam
0a172d8bc1 add api.runOutsideOfSync() to backend script API, #4327 2023-10-19 00:29:03 +02:00
zadam
67a12d3c4d improve sync error logging 2023-10-19 00:13:11 +02:00
zadam
5b2ba3646d removed maxTouchPoints condition for detection of mobile browsers, #4316 2023-10-18 23:23:20 +02:00
zadam
148bff9f77 show existing backups and anonymized DBs, #4321 2023-10-18 23:16:47 +02:00
zadam
2132cf3bdc nodejs 18.18.2 2023-10-18 09:40:00 +02:00
zadam
d5271c17e3 fix sync bug 2023-10-18 09:37:36 +02:00
zadam
b764761e58 run local dev with TRILIUM_SAFE_MODE as a safety precaution 2023-10-18 09:36:49 +02:00
zadam
c666fc3b98 make sure exact noteId match comes on the top in search 2023-10-18 09:33:24 +02:00
zadam
ba34df2e15 typo 2023-10-18 09:24:13 +02:00
zadam
840ac2d63e updates 2023-10-14 21:15:06 +02:00
zadam
5dd4586ebe added webViewSrc to builtin attrs 2023-10-14 21:09:20 +02:00
zadam
bd7fa16e96 Merge remote-tracking branch 'origin/master' 2023-10-09 23:08:32 +03:00
zadam
846ac9305e don't anonymize option notes 2023-10-09 23:08:25 +03:00
zadam
db8014c0ef Merge pull request #4298 from rauenzi/share
Add ~shareTemplate and #shareExternalLink
2023-10-09 22:28:20 +03:00
Zack Rauen
a3540772dd Merge remote-tracking branch 'upstream/master' into share 2023-10-08 17:19:32 -04:00
zadam
137703ada4 add promoted attributes widget to the mobile version, closes #4314 2023-10-08 22:58:31 +03:00
Zack Rauen
ec6b8476f9 Adjust shared notes search api 2023-10-08 14:54:37 -04:00
zadam
d09d3f5a96 release 0.61.9-beta 2023-10-07 23:02:47 +03:00
zadam
3d15aeae58 def value 2023-10-07 23:02:33 +03:00
zadam
9765892d18 fix loading canvas notes created in 0.61.7-beta, closes #4313 2023-10-07 21:49:25 +03:00
zadam
00f5924251 jsdocs 2023-10-07 20:57:53 +03:00
zadam
99d0f22403 Merge branch 'beta'
# Conflicts:
#	package-lock.json
2023-10-07 20:51:26 +03:00
zadam
78f8a37587 added total result count to the note list widget 2023-10-06 22:02:09 +03:00
zadam
86d62866f2 catch JSON stringify error, #4310 2023-10-05 21:54:59 +02:00
zadam
1dc3fafcbf improve anonymization 2023-10-03 23:17:15 +02:00
zadam
7f06952d9e improve anonymization 2023-10-03 23:14:02 +02:00
zadam
78b6614eea fix docker-compose.yml #2239 2023-10-03 11:21:14 +02:00
zadam
9665e872c2 fix importing inline images within markdown within zip, closes #4301 2023-10-03 09:40:31 +02:00
zadam
9db0a062ed fix calculating revision attachment size 2023-10-03 09:05:30 +02:00
zadam
055bb39e4d Merge remote-tracking branch 'origin/beta' into beta 2023-10-02 22:02:31 +02:00
zadam
1261a06a30 order by note size + attachments + revisions, closes #4295 2023-10-02 22:02:25 +02:00
zadam
91eb3c45d5 added "save revision" to note actions menu 2023-10-02 15:29:45 +02:00
zadam
3944235592 -console.log 2023-10-02 15:25:12 +02:00
zadam
5be61e6142 saving / viewing canvas revisions 2023-10-02 15:24:40 +02:00
zadam
62ccf798ee allow deleting custom launchers, fixes #4291 2023-09-30 22:38:06 +02:00
Zack Rauen
d259931bd2 Add new attributes in appropriate locations 2023-09-30 00:48:34 -04:00
Zack Rauen
7729aad1e9 Allow external link notes in share tree 2023-09-30 00:44:10 -04:00
zadam
70d6bd0157 release 0.61.8-beta 2023-09-29 00:54:45 +02:00
zadam
e5555beea9 logging reason for frontend reload 2023-09-28 23:47:19 +02:00
zadam
9767b6269a upgrade code mirror to 5.65.15 and fix modes requiring multiplex or overlay, fixes #4279 2023-09-28 01:02:27 +02:00
zadam
7e486fda06 electron update 2023-09-28 00:27:00 +02:00
zadam
9f726304aa sync fix, #4288 2023-09-28 00:24:53 +02:00
Zack Rauen
614cc4dd82 Allow users to use their own share template 2023-09-27 14:34:07 -04:00
zadam
3e8f09d306 allow shrinking note title text in the tree to make space for the "add note" button https://github.com/zadam/trilium/discussions/4287 2023-09-26 00:14:28 +02:00
zadam
613b83e638 Merge pull request #4281 from rauenzi/jump-to-toc
Fix jump to ToC for nested headers
2023-09-25 23:33:00 +02:00
zadam
4ac609ff57 Merge pull request #4280 from rauenzi/promoted-alias
Add option for promoted aliases
2023-09-25 23:30:39 +02:00
zadam
c14ce2c428 Merge pull request #4278 from Nriver/master
sort mime types alphabetically
2023-09-25 23:28:22 +02:00
zadam
984bd726e9 add support for "bottom" sort, closes #4277 2023-09-25 23:25:00 +02:00
zadam
964abf390b API docs 2023-09-25 23:11:24 +02:00
zadam
af24758ad4 Merge branch 'beta'
# Conflicts:
#	docs/backend_api/BAttachment.html
#	docs/backend_api/BNote.html
#	docs/backend_api/becca_entities_bnote.js.html
#	docs/frontend_api/FAttribute.html
#	docs/frontend_api/FBranch.html
#	docs/frontend_api/FNote.html
#	docs/frontend_api/FrontendScriptApi.html
#	docs/frontend_api/entities_fattachment.js.html
#	docs/frontend_api/entities_fattribute.js.html
#	docs/frontend_api/entities_fblob.js.html
#	docs/frontend_api/entities_fbranch.js.html
#	docs/frontend_api/entities_fnote.js.html
#	docs/frontend_api/global.html
#	docs/frontend_api/index.html
#	docs/frontend_api/services_frontend_script_api.js.html
#	package-lock.json
2023-09-25 23:11:07 +02:00
zadam
528d94a8fb accept custom widgets as classes instead of instances, #4274 2023-09-25 23:05:54 +02:00
zadam
be918628c3 global API docs 2023-09-25 23:04:03 +02:00
zadam
602b9ae64a API docs 2023-09-23 00:04:32 +02:00
zadam
602a166e36 added info, confirm, prompt dialogs 2023-09-23 00:04:16 +02:00
zadam
2e69cc8331 Merge pull request #4267 from rauenzi/tray
Add hotkey option to toggle hide to tray
2023-09-22 23:52:47 +02:00
zadam
aaad858395 save scroll and zoom in canvas 2023-09-22 23:44:03 +02:00
Zack Rauen
b266c327e4 Fix jump to ToC for nested headers 2023-09-22 05:52:06 -04:00
Zack Rauen
149462e3ab Add option for promoted alias 2023-09-22 04:58:06 -04:00
Nriver
237d309406 sort mime types alphabetically 2023-09-22 09:58:37 +08:00
zadam
48248224f8 release 0.61.7-beta 2023-09-21 23:38:18 +02:00
zadam
79e5e3b65f more logging for sync 2023-09-21 18:13:14 +02:00
zadam
d0383f3044 remove debian packaging hack 2023-09-21 12:44:20 +02:00
zadam
62ecd1ad76 node 18.18.0 2023-09-21 12:29:11 +02:00
zadam
75b7706c2c mermaid 10.4.0 2023-09-21 12:24:44 +02:00
zadam
584b176643 hiding useless/misleading buttons from excalidraw 2023-09-21 12:03:40 +02:00
zadam
a16555bbff don't save appState in canvas - app state should be reset after each load 2023-09-21 11:54:54 +02:00
zadam
a749e24147 fix creating revisions for non-text notes #4176 2023-09-21 11:38:38 +02:00
zadam
bb81f110dd improved error handling 2023-09-21 11:16:03 +02:00
zadam
5dd6f49104 chart js 0.16.0 2023-09-19 23:59:05 +02:00
zadam
bc6be44b19 better error condition checks 2023-09-19 23:48:55 +02:00
zadam
8075265753 fix migration, closes #4262 2023-09-18 23:45:00 +02:00
Zack Rauen
9d69024758 Add hotkey option to toggle hide to tray
Fixes #3043
2023-09-18 04:38:23 -04:00
zadam
40ca949890 fixes for tooltip auto-disappearing handling 2023-09-14 00:40:49 +02:00
zadam
035113db4d Merge branch 'beta'
# Conflicts:
#	package-lock.json
2023-09-14 00:19:19 +02:00
zadam
4a67f63abd better error message in image attachment + upgrades 2023-09-14 00:18:56 +02:00
zadam
d9666210f1 make sure that the hidden note is never selected when hoisted to root to avoid e.g. erroneous deletion 2023-09-13 16:57:24 +02:00
zadam
925bba134e formatting 2023-09-13 09:10:56 +02:00
zadam
d46801ff1f refactoring, tab switching handling shouldn't be on the widget level 2023-09-13 09:01:55 +02:00
zadam
7848c7e319 Merge pull request #4251 from rauenzi/tab-navigation
Add keyboard shortcuts for tabs
2023-09-13 00:22:01 +02:00
zadam
65e53741e7 Merge pull request #4255 from Compositr/master
Add new datePattern and monthPattern replacers
2023-09-13 00:19:04 +02:00
Zack Rauen
a83e8ff91a Switch back to window scope 2023-09-11 18:03:49 -04:00
Compositr
542e2579df feat: add new datePattern replacers for shortmonth
* `{shortMonth3}` 3-letter months, e.g. Sep, Oct, Nov, Dec
* `{shortMonth4}` 4-letter months, e.g. Sept, Octo, Nove, Dece
2023-09-12 07:35:46 +10:00
Compositr
81d64e020e feat: add new datePattern replacer {ordinal}
* {ordinal} is replaced with the ordinal date (e.g. 1st, 2nd, 3rd) etc.
2023-09-12 07:30:30 +10:00
zadam
9413cd2296 comment explaining scope in keyboard actions 2023-09-11 22:54:36 +02:00
zadam
5b85713bf3 saving export meta file per directory 2023-09-11 00:12:12 +02:00
Zack Rauen
15254e2dfc Add keyboard shortcuts for tabs 2023-09-08 22:53:21 -04:00
zadam
5f6d562bf8 add ability to excalidraw to follow links 2023-09-08 23:00:43 +02:00
zadam
f37dc66074 add support for storing canvas libraries in note attachments plus storing exported SVG in attachment 2023-09-08 21:53:57 +02:00
zadam
c881b39860 Merge branch 'beta'
# Conflicts:
#	package-lock.json
2023-09-08 01:10:12 +02:00
zadam
0b84524807 fix refreshing note actions on note/tab switch, closes #4247 2023-09-08 00:43:18 +02:00
zadam
5218f7b7a6 Merge pull request #4246 from SiriusXT/open-note-custom
Add openAttachmentCustom
2023-09-08 00:31:20 +02:00
zadam
8062bb7e2a fix reloading unprotected note title to the document.title after entering protected session, fixes #4244 2023-09-08 00:28:00 +02:00
zadam
806062c8d1 fix undelete attachments 2023-09-08 00:22:48 +02:00
zadam
83f19c0537 fix protecting attachments 2023-09-08 00:19:30 +02:00
siriusXT
0424728012 Add openAttachmentCustom 2023-09-07 06:33:51 +00:00
zadam
3a83d58b25 release 0.61.6-beta 2023-09-06 23:57:29 +02:00
zadam
6fa9d996e8 ckeditor 39.0.2 2023-09-06 23:23:42 +02:00
siriusXT
1ea3d238e0 Fix right click bookmark bug
(cherry picked from commit 92e43bc051)
2023-09-06 23:11:51 +02:00
zadam
eb273b7dbb lib upgrades 2023-09-06 23:11:02 +02:00
zadam
55374ac4d9 Merge pull request #4240 from SiriusXT/LauncherWidget
Fix right click bookmark bug
2023-09-06 23:10:54 +02:00
zadam
8070c00b5f API docs 2023-09-06 23:05:03 +02:00
zadam
da8025f1e4 Merge branch 'beta' 2023-09-06 23:00:45 +02:00
zadam
d2263c68f8 provide note dates in the frontend API, fixes #4232 2023-09-06 22:54:31 +02:00
siriusXT
92e43bc051 Fix right click bookmark bug 2023-09-06 14:49:01 +00:00
zadam
40971afe4f API docs build 2023-09-06 09:25:00 +02:00
zadam
90fc4b8293 Merge branch 'beta'
# Conflicts:
#	docs/backend_api/BAttachment.html
#	docs/backend_api/BRevision.html
#	docs/backend_api/BackendScriptApi.html
#	docs/backend_api/becca_entities_battachment.js.html
#	docs/backend_api/becca_entities_bblob.js.html
#	docs/backend_api/becca_entities_brevision.js.html
#	docs/frontend_api/FNote.html
#	docs/frontend_api/FrontendScriptApi.html
#	docs/frontend_api/entities_fattachment.js.html
#	docs/frontend_api/entities_fblob.js.html
#	docs/frontend_api/services_frontend_script_api.js.html
#	package-lock.json
#	src/public/app/services/frontend_script_api.js
2023-09-06 09:24:41 +02:00
zadam
97d8b19868 add missing API docs 2023-09-06 09:23:13 +02:00
zadam
2bc7da91a6 add createLink() returns jsDoc, #4235 2023-09-06 09:20:32 +02:00
zadam
2b4cbb5f6b fix clipperInbox handling for new note creation, closes #4219 2023-09-05 23:24:01 +02:00
zadam
72b2a6ecb6 Merge pull request #4225 from SiriusXT/master
Click the button to reset the zoom level
2023-09-05 23:01:50 +02:00
zadam
7b662b04ff fix orderby with multiple labels, closes #4220 2023-09-05 23:00:08 +02:00
zadam
f8e4a665bd fixed search parser tests 2023-09-05 22:48:20 +02:00
zadam
f9a27dd90c add imageStyle alignBlockLeft, alignBlockRight, fixes #4215 2023-09-05 22:16:45 +02:00
zadam
641985737f fix FNote.getContent() #4210 2023-09-05 22:02:26 +02:00
zadam
121e4ba2ea fix displaying 1 / 0 in find widget 2023-09-05 21:00:24 +02:00
zadam
01474ecd2d sync fixes 2023-09-05 00:30:09 +02:00
zadam
82e4e28e7b fix 2023-09-04 23:57:42 +02:00
SnnBcd xt
06eb522a8c Click the button to reset the zoom level 2023-09-01 06:40:36 +00:00
SnnBcd xt
21098be307 Click the button to reset the zoom level 2023-09-01 03:30:39 +00:00
zadam
886ee0dbcb fix sync exception 2023-08-31 00:14:35 +02:00
zadam
6f7fbacca1 add "api.runOnFrontend()" to the backend script API 2023-08-30 23:18:16 +02:00
zadam
f5ddabc042 Merge pull request #4202 from eliandoran/feature/jump_to_note_list
Use a list instead of dropdown for jump-to-note
2023-08-30 22:17:04 +02:00
vaifix
8da5b90aea Fix bug: Calendar display incorrect tooltips.
(cherry picked from commit 58fe3a62af)
2023-08-30 00:20:42 +02:00
zadam
23848526c0 Merge pull request #4197 from dvai/master
fix some bugs
2023-08-30 00:19:53 +02:00
zadam
e7d57bc08f Merge remote-tracking branch 'origin/beta' into beta
# Conflicts:
#	package-lock.json
2023-08-30 00:11:52 +02:00
zadam
041758766a allow specifying date created in the ETAPI, #4199 2023-08-30 00:11:32 +02:00
Elian Doran
69980c798b note autocomplete: Use backspace icon for delete text 2023-08-28 23:07:08 +03:00
Elian Doran
4de6a803e9 jump to note list: Remove scroll when not needed 2023-08-28 22:30:42 +03:00
Elian Doran
748c5064b5 jump to note list: Improve scroll bar position 2023-08-28 22:21:54 +03:00
Elian Doran
c6e8966ecd jump to note: Improve position of close button 2023-08-28 22:15:36 +03:00
Elian Doran
8c247ba7c6 jump to note list: Improve layout 2023-08-28 22:12:14 +03:00
Elian Doran
52b5711ecd jump to note: Add "Create and link child note" 2023-08-28 21:51:40 +03:00
vaifix
58fe3a62af Fix bug: Calendar display incorrect tooltips. 2023-08-28 20:43:03 +08:00
Elian Doran
af4d0c3ba6 jump to note list: Improve layout slightly 2023-08-26 17:52:01 +03:00
Elian Doran
4bba0aa842 jump to note list: Re-enable styling 2023-08-26 17:52:01 +03:00
Elian Doran
ae9af8ea23 jump to note list: Use a proper height to the container 2023-08-26 17:52:01 +03:00
Elian Doran
eea29aba0e jump to note list: Don't close jump to note results on lost focus 2023-08-26 17:51:58 +03:00
Elian Doran
abbd0b50eb jump to note list: Use a fixed container instead of dropdown 2023-08-26 17:51:47 +03:00
vaifix
739ab28763 Resolve autocomplete error 2023-08-25 13:01:53 +08:00
zadam
c551eae651 Merge pull request #4188 from rauenzi/master
Update JSDoc & API Docs
2023-08-21 23:46:40 +02:00
Zack Rauen
d5aea26960 Update API Docs 2023-08-21 04:18:14 -04:00
Zack Rauen
d3730ac1a9 Fix and improve JSDoc for APIs 2023-08-21 04:15:53 -04:00
zadam
f2a510e4c5 cleanup of old migrations, since upgrading to 0.61 is possible only from 0.60. 2023-08-18 15:56:38 +02:00
zadam
4717242dc7 force migration to 0.60 first before 0.61 #4132 2023-08-18 15:55:59 +02:00
zadam
b5ef09e779 hide canvas buttons which don't work, #4182 2023-08-18 15:33:20 +02:00
zadam
d706b3a447 fix saving revisions for non-text types, closes #4176 2023-08-17 16:39:57 +02:00
zadam
6c96cca3a5 add 200ms timeout to api.getTextEditor() and similar #4174 2023-08-17 16:31:04 +02:00
zadam
c1865f8564 small refactor 2023-08-17 09:09:06 +02:00
zadam
515c5411a6 release 0.61.5-beta 2023-08-16 23:02:15 +02:00
zadam
3f7a5504c7 prettier config 2023-08-16 20:31:14 +02:00
zadam
8c7c37cf98 updates 2023-08-16 20:12:22 +02:00
zadam
d93e00adce Merge pull request #4168 from soulsands/button-style
fix: launcher-button style
2023-08-16 00:02:26 +02:00
zadam
0e16e48db6 scroll beyond last line in text/code editor, fixes #2728 2023-08-15 22:50:13 +02:00
zadam
c0f48c0e99 mermaid 10.3.1 2023-08-15 10:30:30 +02:00
zadam
abedf2bba4 fix pasting into ckeditor, upgrade to v39.0.1 2023-08-15 10:25:23 +02:00
zadam
bb0137b2fd fix displaying options / book on firefox, closes #4165 2023-08-15 10:25:23 +02:00
zadam
6c54c7d17d save enex images as attachment, fixes #4163 2023-08-15 10:25:23 +02:00
“soulsands”
cd95adcecb fix: launcher-button style 2023-08-15 16:11:13 +08:00
zadam
90255ac55b release 0.61.4-beta 2023-08-10 23:49:37 +02:00
zadam
e741c2826c release 0.61.4-beta 2023-08-10 23:48:27 +02:00
zadam
026992db78 release 0.61.4-beta 2023-08-10 23:46:42 +02:00
zadam
33780c1e17 fix note tooltip code rendering 2023-08-10 13:50:25 +02:00
zadam
ede9c43f67 API docs 2023-08-10 13:40:26 +02:00
zadam
5c12ac4eee fix CKEditor crashing 2023-08-10 13:40:15 +02:00
zadam
522518cf0d disambiguous query 2023-08-09 23:12:31 +02:00
zadam
1d869d25c2 fix #clipperInbox, closes #4153 2023-08-09 23:00:42 +02:00
zadam
a9cdd93cb4 added options to disable auto-opening of promoted attributes and edited notes ribbon tabs, closes #4151 2023-08-09 22:50:41 +02:00
zadam
4240da349d add shared info to mobile layout, closes #4147 2023-08-09 00:02:45 +02:00
zadam
c257bc07a8 clipper now creates notes with image attachments instead of image notes 2023-08-09 00:01:31 +02:00
zadam
00eaa16985 clipper now creates notes with image attachments instead of image notes 2023-08-08 23:42:47 +02:00
zadam
fefb059564 clipper now creates notes with image attachments instead of image notes 2023-08-08 23:07:59 +02:00
zadam
9166765ced fix include note sizing when in readonly mode, closes #4135 2023-08-08 22:56:45 +02:00
zadam
6ae7661603 note path validation 2023-08-02 23:23:31 +02:00
zadam
30e75056bd release 0.61.3-beta 2023-07-31 23:03:45 +02:00
zadam
530e56dcb5 fixed comment 2023-07-31 22:59:47 +02:00
zadam
63675bfbae make migration 223 NOOP 2023-07-30 21:54:01 +02:00
zadam
696ce38083 ckeditor 38.1.1 2023-07-30 00:32:16 +02:00
zadam
12014b9f4d sync fixes and refactorings 2023-07-29 23:35:08 +02:00
zadam
e8b52f9e6c sync fixes and refactorings 2023-07-29 23:25:02 +02:00
zadam
04b125afc0 sync fixes and refactorings 2023-07-29 21:59:20 +02:00
zadam
2a7fe85020 VACUUM database after migration 2023-07-28 16:22:10 +02:00
zadam
119050e355 fix migration 2023-07-28 16:13:31 +02:00
zadam
72122d0f95 fix blobIds - they shouldn't contain + and / characters 2023-07-28 15:55:26 +02:00
zadam
bd22863bb7 release 0.61.2-beta 2023-07-28 00:06:23 +02:00
zadam
ce3834eb9e blob erasure is not synced, need to clean them up before each content hash check 2023-07-27 23:57:12 +02:00
zadam
8edb5428e5 small sync fixes and refactorings 2023-07-27 23:22:08 +02:00
zadam
527718eff7 add indices on blobId 2023-07-27 21:40:47 +02:00
zadam
5b0f487f3f handle ERR_* errors gracefully 2023-07-27 14:50:18 +02:00
zadam
a3fa8341ba handle ERR_CONNECTION_RESET gracefully 2023-07-27 10:55:34 +02:00
zadam
04813743e2 fix zooming speed, closes #4121 2023-07-25 22:33:35 +02:00
zadam
ddf75cd5e5 note tooltip displays the whole note with scrollbar, other behavior changes. closes #4120 2023-07-25 22:27:15 +02:00
zadam
d0e5ad5b7e release 0.61.1-beta 2023-07-24 23:47:57 +02:00
zadam
b4631e927c Merge remote-tracking branch 'origin/master' 2023-07-24 23:47:27 +02:00
zadam
b7bc843a37 fix demo document statistics, closes #4117 2023-07-24 23:46:02 +02:00
zadam
98d65f8767 Merge pull request #4114 from SiriusXT/master
Fix bugs in highlights,v0.61.0-beta
2023-07-24 22:58:20 +02:00
zadam
0599891ec0 Merge pull request #4001 from dymani/reopen-in-place
Reopen recently closed tab/split in place
2023-07-24 22:52:14 +02:00
zadam
cc06701565 swiftshader deletion is no longer needed 2023-07-24 22:33:36 +02:00
SnnBcd xt
40683985cd Fix bugs in highlights 2023-07-22 19:13:03 +00:00
zadam
074e13a889 release 0.61.0-beta 2023-07-22 17:51:08 +02:00
zadam
98b0baefe2 Merge remote-tracking branch 'origin/master' into next61
# Conflicts:
#	src/public/app/widgets/buttons/note_actions.js
2023-07-22 17:49:29 +02:00
zadam
3aad0ebc95 Merge remote-tracking branch 'origin/next61' into next61 2023-07-22 17:48:17 +02:00
zadam
479d720a6e upgrades 2023-07-22 17:48:09 +02:00
zadam
e4892c9888 fixed order of multi-valued promoted attributes, closes #4105 2023-07-20 23:22:31 +02:00
zadam
f8c9178c5d fix migration 2023-07-18 23:23:52 +02:00
zadam
83049c95c3 defensive copies of owned attrs 2023-07-17 22:56:36 +02:00
zadam
bc8f531b33 fix a bug which caused immedate deletion of created attributes 2023-07-17 22:53:54 +02:00
zadam
23278f54cb force refresh before activating the attribute detail dialog, fixes #4077 2023-07-17 22:41:37 +02:00
zadam
18801fb3e1 more filtering of note actions based on note type 2023-07-17 22:32:07 +02:00
zadam
dc0a0dcf09 Merge pull request #4098 from AndrewPluzhnikov/fix-search-in-text
Disable Search in note button in global search context.
2023-07-17 22:30:49 +02:00
zadam
04c306b360 support combination of shared and cloned in the note tree, fixes #4097 2023-07-17 22:26:41 +02:00
zadam
d6a4f1db13 share tree should include branch prefixes, fixes #4096 2023-07-17 22:19:03 +02:00
zadam
84c4b368c8 updated better-sqlite binaries for node 18/electron 25 2023-07-17 21:39:25 +02:00
Andrew Pluzhnikov
4307f25205 Disable Search in note button in global search context.
This button doesn't actually do anything in the global search window, so
it should be greyed out/disabled.
2023-07-16 10:40:34 -07:00
zadam
48f03f7a1b API docs 2023-07-15 12:07:45 +02:00
zadam
9d24499fef upgrade excalidraw to 0.15.2 2023-07-15 12:01:09 +02:00
zadam
df97b269a7 autocomplete upgrade to 0.38.1 2023-07-15 11:45:18 +02:00
zadam
ee6fb98a0d jquery 3.7.0 2023-07-15 11:41:36 +02:00
zadam
13e30e5855 dayjs frontend update 2023-07-15 11:38:01 +02:00
zadam
5ab2ec0f13 little fixes for the datetime promoted attr 2023-07-15 11:29:29 +02:00
zadam
8465d7fa68 Merge remote-tracking branch 'origin/master' into next61 2023-07-15 11:27:42 +02:00
zadam
d153fc7ba5 Merge pull request #4090 from harishkumarc/datetime-attribute
added date and time attribute capability
2023-07-15 11:26:53 +02:00
zadam
1a7c2d4c32 fix hiding toc with multiple splits, closes #4093 2023-07-15 11:19:05 +02:00
zadam
b3381a3b53 reimplemented triggering search from URL, fixes #385 2023-07-15 10:59:30 +02:00
zadam
ac0d61e9b4 add mindmap mermaid example to demo document 2023-07-15 10:44:38 +02:00
zadam
b13a6ced19 cleanup 2023-07-15 10:33:29 +02:00
zadam
b61aab06b5 nodejs upgrade 2023-07-15 10:32:26 +02:00
zadam
64b86b2666 use marked instead of commonmark to convert MD to HTML, which supports e.g. tables, closes #2026 2023-07-15 10:31:50 +02:00
zadam
27e6fa9526 Merge branch 'stable' into next61 2023-07-15 10:10:29 +02:00
zadam
3d31742285 fix FNote.isHiddenCompletely() which returned false for _hidden 2023-07-15 09:50:07 +02:00
zadam
2b2f4fbc07 comment 2023-07-15 09:48:30 +02:00
zadam
513bf252cd don't display export for backend log note, fixes #4076 2023-07-15 09:35:03 +02:00
zadam
f591e954f3 capitalization of options titles 2023-07-15 09:26:18 +02:00
zadam
59de1925a9 decreased padding 2023-07-14 22:14:07 +02:00
zadam
6c1011341c add help button to attachment detail as well 2023-07-14 22:02:30 +02:00
zadam
906082a6b2 add help button to attachment list 2023-07-14 21:59:43 +02:00
zadam
30bcd1764a check the attachment after upload 2023-07-14 21:28:32 +02:00
zadam
cea54aecad check the attachment after conversion 2023-07-14 21:18:56 +02:00
zadam
ff6f2a4d44 zoom for the attachment images 2023-07-14 21:08:00 +02:00
zadam
5f6fded833 zoom for the attachment images 2023-07-14 21:06:15 +02:00
zadam
fed5f1a7d2 fix content renderer for mermaid 2023-07-14 20:03:28 +02:00
zadam
a06ee1ced1 added new mermaid diagram examples to the demo document 2023-07-14 20:00:53 +02:00
zadam
332b92791e upgrade mermaid to 10.2.4 2023-07-14 19:56:37 +02:00
zadam
d4a9461460 force graph upgrade 2023-07-14 19:45:10 +02:00
zadam
2dac6ab281 DB migration should convert only "perfect candidates" to attachments 2023-07-14 18:24:15 +02:00
zadam
4d00404f55 more actions triggering new tab should respect current hoisting 2023-07-14 18:15:31 +02:00
zadam
3adab07ddb common style for options number inputs 2023-07-14 18:05:19 +02:00
zadam
3d0c3652ce file note should reload after uploading new revision 2023-07-14 17:55:28 +02:00
zadam
c3f5bb5518 image note should reload after uploading new revision 2023-07-14 17:52:35 +02:00
zadam
b2d460d5c1 update demo document with images converted to attachments 2023-07-14 17:06:38 +02:00
zadam
d475346a09 renamed attachment's parentId to more fitting ownerId 2023-07-14 17:01:56 +02:00
zadam
ca41806bc2 import and export fixes 2023-07-13 23:54:47 +02:00
zadam
a748710b01 make file attachments accessible in revisions dialog 2023-07-10 20:30:04 +02:00
zadam
ac9a4b3afc fixes in etapi tests 2023-07-10 19:10:07 +02:00
zadam
b7f0fd2db3 Merge branch 'master' into next61
# Conflicts:
#	package-lock.json
#	src/public/app/services/note_content_renderer.js
#	src/public/app/widgets/note_tree.js
#	src/routes/routes.js
#	src/services/consistency_checks.js
#	src/services/notes.js
#	src/services/task_context.js
2023-07-10 18:20:36 +02:00
harishkumarchellappa
7d6c847d47 added date and time attribute capability 2023-07-10 17:24:34 +05:30
zadam
6ec6d66f17 Merge pull request #4084 from AndrewPluzhnikov/fix-868
Implement saving of global search string.
2023-07-09 23:52:36 +02:00
zadam
977089cc28 Merge pull request #4083 from viperdc/patch-1
Update docker_healthcheck.js
2023-07-09 23:47:55 +02:00
zadam
c3f8975166 small refactorings of clipper code 2023-07-09 22:58:34 +02:00
zadam
639f80b603 Merge pull request #4075 from manto89/feature/add-clippings-existing
Feature/add clippings existing url
2023-07-09 22:43:34 +02:00
Andrew Pluzhnikov
927da84d3b Implement saving of global search string.
This implements point 1 of issue 868.

After performing a search, when returning to the global search tab the
previous search term is now retained and preselected, making it easier
to repeat the same search or modify it.
2023-07-06 20:26:55 -07:00
viperdc
b8c9943deb Update docker_healthcheck.js
Correcting ini location for HTTPS health-check bypass.
2023-07-06 19:02:51 -04:00
manto89
bb6ab0fe45 Fix clipping html with parser when using web-clipper 2023-07-02 12:52:16 +02:00
manto89
0c86dece5f Fix clipType searching for web-clipper 2023-07-02 12:51:23 +02:00
zadam
b7b0bd80ed padding of right pane 2023-06-30 23:01:57 +02:00
zadam
f06207207b fix styling for videos 2023-06-30 16:36:03 +02:00
zadam
068684101f remove the option to show CKEditor banner 2023-06-30 15:58:42 +02:00
zadam
f78d96a3d4 refactoring of server and suppressing error during conversion of attachment into note 2023-06-30 15:44:30 +02:00
zadam
a0d958bf12 refactor uploading files 2023-06-30 15:25:45 +02:00
zadam
0802b81807 improved error logging in frontend 2023-06-30 12:14:58 +02:00
zadam
192e399cb5 typos 2023-06-30 11:18:34 +02:00
zadam
fc564f6aed fix eslint validation 2023-06-30 00:02:25 +02:00
zadam
eb34f9c64f small refactorings and fixes 2023-06-29 23:32:19 +02:00
zadam
48029cea7c small refactorings 2023-06-29 22:10:13 +02:00
zadam
f4ec4e58c7 fixed image styles 2023-06-29 21:30:26 +02:00
zadam
faa402fcda API docs 2023-06-29 20:54:58 +02:00
zadam
788841d256 fix mentions 2023-06-29 12:19:01 +02:00
zadam
b7c37fdf58 cleanup 2023-06-29 11:44:28 +02:00
zadam
a46c5a2243 use isLabelTruthy() for most binary labels 2023-06-29 00:14:12 +02:00
zadam
430f2975f8 make "excludeFromNoteMap" overridable with note.isLabelTruthy(), #4058 2023-06-29 00:04:30 +02:00
zadam
dd8226ff4c comment 2023-06-28 21:33:09 +02:00
zadam
807b442c7a fix froca update of erased blob 2023-06-28 21:28:41 +02:00
zadam
a452e4add5 sync fixes 2023-06-28 21:05:31 +02:00
zadam
48b30b985e attachment upload 2023-06-28 20:53:55 +02:00
zadam
05d2f4fe96 Merge branch 'stable' 2023-06-27 23:15:20 +02:00
zadam
85a75fc186 getOwnedAttributes() should not make a copy, consistent with similar methods 2023-06-27 23:03:17 +02:00
zadam
ddda4d9867 fix constructing result note path in the jump to note dialog, closes #4054 2023-06-27 22:57:13 +02:00
zadam
42c8059ae1 Merge pull request #4057 from dymani/master
Fix closing parenthesis
2023-06-27 21:38:36 +02:00
dymani
0f4eb8ff4c fix closing parenthesis 2023-06-28 02:31:17 +08:00
zadam
8ee537e2eb API comments 2023-06-27 00:14:13 +02:00
zadam
8eb091445b Merge pull request #4032 from mechanarchy/patch-1
Ignore SQL comments in query console
2023-06-26 23:05:42 +02:00
mechanarchy
1fc23c948e Fix SQL comment handling 2023-06-23 09:06:14 +10:00
zadam
cb2b97635a centering icons in note book vertically 2023-06-22 23:34:05 +02:00
zadam
8fb42e4517 Merge pull request #4049 from SiriusXT/master
Fix bugs in toc and improve related codes
2023-06-22 22:34:47 +02:00
zadam
edae1a5d1c Merge pull request #4050 from kianmeng/fix-typos
Fix typos
2023-06-22 22:33:09 +02:00
zadam
08398a1417 fix search scripts, closes #4048 2023-06-22 22:30:26 +02:00
Kian-Meng Ang
712304bbc6 Fix typos
Found via `codespell -S ./libraries,./package-lock.json -L tabel,tabels,uptodate,isnt,edn,falsy`
2023-06-23 00:27:04 +08:00
SiriusXT
afb893c157 Fix bugs in toc and improve related codes 2023-06-22 15:38:36 +08:00
manto89
ebccd48013 Don't search note by url if url begins with 'about:' 2023-06-21 18:06:28 +02:00
manto89
54065672aa Normalize behaviour with the other create method for web-clipper 2023-06-21 16:10:06 +02:00
manto89
8394ce8002 Change method when adding a new note.
Add reference to new backend method
2023-06-21 13:09:49 +02:00
zadam
176784834f simple formatter for source view of text HTML notes 2023-06-20 23:59:36 +02:00
zadam
a47004bb4e shift migrations after upmerge 2023-06-20 23:32:31 +02:00
zadam
995f1c9fc4 Merge branch 'stable' into next61
# Conflicts:
#	src/etapi/etapi.openapi.yaml
#	src/etapi/notes.js
#	src/public/app/widgets/type_widgets/editable_text.js
#	src/services/app_info.js
2023-06-20 23:30:45 +02:00
zadam
1f3b6feaff Merge branch 'master' into next61
# Conflicts:
#	src/public/app/widgets/note_tree.js
2023-06-20 23:28:41 +02:00
zadam
8095c77b91 cache icon count to make filtering more responsive on slower connections, #4044 2023-06-20 21:31:25 +02:00
zadam
6cfd18b29b read filter values in icon selector only after async events, #4044 2023-06-20 21:19:56 +02:00
zadam
defd997424 release 0.60.4 2023-06-19 23:26:50 +02:00
zadam
5905950c17 fix notePosition assignment for new children of root 2023-06-19 00:29:36 +02:00
zadam
691fccb769 fix keyboard navigation in the note tree, fixes #4036 2023-06-18 23:45:48 +02:00
zadam
bbe3f436d3 avoid scrolling to active node without a reason, fixes #4031 2023-06-18 21:50:22 +02:00
mechanarchy
af053b61fc Ignore SQL comments in query console 2023-06-17 17:06:17 +10:00
zadam
a2cd6f92d7 compatibility with online excalidraw tool 2023-06-15 21:34:02 +02:00
zadam
3ff5fe61b2 unified file and image upload WIP 2023-06-15 01:26:38 +02:00
zadam
75c6afd1c3 fix loading of string content saved as binary 2023-06-14 22:21:22 +02:00
zadam
8d2958738f add option to hide the "Powered by CKEditor" banner 2023-06-14 00:51:05 +02:00
zadam
0496412f4a cleanup of unused options 2023-06-14 00:38:48 +02:00
zadam
f80a20d18c don't use non-existing btn-xs 2023-06-14 00:31:15 +02:00
zadam
34c642a49a rename attachment 2023-06-14 00:28:59 +02:00
zadam
2ebbc33081 fix revision rename DB migration 2023-06-13 23:39:42 +02:00
zadam
ac56056f65 Merge branch 'master' into next61
# Conflicts:
#	package-lock.json
#	src/routes/api/recent_changes.js
2023-06-13 23:25:35 +02:00
zadam
6f16b4caec Merge branch 'beta' 2023-06-13 23:24:09 +02:00
zadam
fbc805a221 Merge pull request #4019 from mechanarchy/patch-2
Fix attempted ETAPI token rename after cancel
2023-06-12 23:21:13 +02:00
zadam
41844cf817 Merge pull request #4017 from mechanarchy/patch-1
Fix SQL Console error messages
2023-06-12 23:12:35 +02:00
mechanarchy
b97ebe9f03 Update etapi.js 2023-06-10 17:36:23 +10:00
mechanarchy
08ec866dd2 Update entrypoints.js 2023-06-10 07:44:23 +10:00
zadam
38839532d5 file upload WIP 2023-06-06 12:31:38 +02:00
zadam
0234ff5fca share support for attachment file download 2023-06-06 00:16:32 +02:00
zadam
44bcfd47c0 share support for attachment images 2023-06-05 23:05:05 +02:00
zadam
69c7eb14aa fixes 2023-06-05 21:14:33 +02:00
zadam
00453fc151 attachment ETAPI tests WIP 2023-06-05 17:00:58 +02:00
zadam
5c393f959d got rid of .isDeleted on froca entities (the property is not available there) 2023-06-05 16:26:05 +02:00
zadam
e6bf6424e8 rename loadresults methods/properties for clarity that they don't contain entities, only rows 2023-06-05 16:12:02 +02:00
zadam
57702a07a2 attachment ETAPI support WIP 2023-06-05 09:44:36 +02:00
zadam
3b3f6082a7 attachment ETAPI support WIP 2023-06-05 09:23:42 +02:00
zadam
49241ab318 merge 2023-06-05 00:12:08 +02:00
zadam
93addac8bb Merge branch 'master' into next61
# Conflicts:
#	src/becca/entities/bnote.js
#	src/public/app/components/note_context.js
#	src/public/app/layouts/desktop_layout.js
#	src/public/app/services/note_content_renderer.js
#	src/public/app/services/utils.js
#	src/public/app/widgets/ribbon_widgets/file_properties.js
#	src/public/app/widgets/ribbon_widgets/note_info_widget.js
#	src/services/notes.js
2023-06-05 00:09:55 +02:00
zadam
fe908759d1 rename "note revision" to just "revision" 2023-06-04 23:02:49 +02:00
zadam
779751a234 rename "note revision" to just "revision" 2023-06-04 23:01:40 +02:00
zadam
cb9feab7b2 got rid of the hot/cold blob, all blobs are "cold" now 2023-06-04 22:50:07 +02:00
zadam
b79631a35d setContent refactoring 2023-06-04 20:51:08 +02:00
zadam
c177aaa901 refactoring of highlight list 2023-06-04 17:46:37 +02:00
zadam
eff3e1df85 Merge pull request #3988 from SiriusXT/Highlighted-Text
Show highlighted text in the right pane
2023-06-04 12:37:19 +02:00
zadam
b46d5f4a71 add blobId to the ETAPI #4005 2023-06-04 12:00:04 +02:00
SiriusXT
5b421d51b5 Merge branch 'Highlighted-Text' of https://github.com/SiriusXT/trilium into Highlighted-Text 2023-06-04 16:02:32 +08:00
SiriusXT
8852e8e531 Show highlighted text in right panel 2023-06-04 16:02:30 +08:00
SnnBcd
cde13dc580 Merge branch 'zadam:master' into Highlighted-Text 2023-06-04 00:24:08 +08:00
SiriusXT
3e3d7aa4d7 Show highlighted text in right panel 2023-06-03 17:12:06 +08:00
SiriusXT
446c41d020 Show highlighted text in right panel 2023-06-03 17:00:15 +08:00
SiriusXT
33fdad5159 Show highlighted text in right panel 2023-06-03 14:43:20 +08:00
SiriusXT
463d145cb7 Merge branch 'Highlighted-Text' of https://github.com/SiriusXT/trilium into Highlighted-Text 2023-06-03 11:55:59 +08:00
SiriusXT
1413756d00 Show highlighted text in right panel 2023-06-03 11:55:50 +08:00
dymani
50ec17433d Fix move pane button after reopen split 2023-06-03 05:59:53 +08:00
dymani
2c8eb82d42 Reopen recently closed tab/split in place 2023-06-03 05:54:33 +08:00
SnnBcd
045ee18237 Merge branch 'zadam:master' into Highlighted-Text 2023-06-02 21:02:31 +08:00
SiriusXT
0a66809bf0 Not show when nothing is checked in the options 2023-06-01 20:38:55 +08:00
SiriusXT
ecfdde2f2a Show highlighted text in the right pane 2023-06-01 20:17:00 +08:00
SiriusXT
92d5aeae41 Show highlighted text in the right panel 2023-05-31 22:34:24 +08:00
SiriusXT
d2d286a4ff Show highlighted text in the left pane 2023-05-31 21:47:43 +08:00
SiriusXT
86861f6ec3 Show highlighted text in the left pane 2023-05-31 18:32:33 +08:00
zadam
f4b5d43899 inline file attachments when exporting single HTML file 2023-05-29 23:42:08 +02:00
zadam
235b779dec detect existing attachment in target note 2023-05-29 22:37:19 +02:00
zadam
df17840dbc fixes attachments 2023-05-29 13:02:25 +02:00
zadam
9d52f80c2f linking attachments finished 2023-05-29 10:21:34 +02:00
zadam
0aa119af2c attachments WIP 2023-05-29 00:19:54 +02:00
zadam
c2f70031d0 Merge branch 'master' into next61
# Conflicts:
#	package-lock.json
#	package.json
#	src/public/app/entities/fnote.js
#	src/public/app/services/link.js
2023-05-28 16:57:48 +02:00
zadam
8e913cb453 wip 2023-05-26 10:36:05 +02:00
zadam
579ed7e194 attachment content rendering 2023-05-21 18:14:17 +02:00
zadam
e20fac19ba attachment WIP 2023-05-20 23:46:45 +02:00
zadam
9e9fb2979f Merge branch 'master' into next61
# Conflicts:
#	package-lock.json
#	package.json
#	src/public/app/components/note_context.js
#	src/public/app/services/open.js
#	src/public/app/widgets/buttons/note_actions.js
#	src/public/app/widgets/find_in_code.js
#	src/public/app/widgets/type_widgets/canvas.js
#	src/services/options.js
2023-05-20 20:55:57 +02:00
zadam
1f8798d7ac upgrades 2023-05-17 23:47:30 +02:00
zadam
af95d387b9 Merge remote-tracking branch 'origin/master' into next60
# Conflicts:
#	src/public/app/services/open.js
#	src/public/app/widgets/buttons/note_actions.js
2023-05-17 23:10:02 +02:00
zadam
76196ed42c Merge remote-tracking branch 'origin/master' into next60 2023-05-14 17:32:59 +02:00
zadam
8a6002c6be fix search in "view source", closes #3929 2023-05-13 15:58:32 +02:00
zadam
38781d33ac Merge remote-tracking branch 'origin/master' into next60
# Conflicts:
#	src/public/app/widgets/type_widgets/editable_text.js
2023-05-13 15:43:35 +02:00
zadam
ff5d3a5f0c import WIP 2023-05-09 00:05:27 +02:00
zadam
626af84f42 refactoring + uploading attachments WIP 2023-05-08 00:02:08 +02:00
zadam
b05ce12e7b adding links to owning note and list to attachments 2023-05-07 23:32:30 +02:00
zadam
274505188b fix "go to note" from note autocomplete 2023-05-07 21:29:09 +02:00
zadam
f85209a72f getting rid of attributes like data-note-path in favor of the whole nav state in URLs 2023-05-07 21:18:21 +02:00
zadam
291f0e79d9 make a special backup before migrating to 0.60 2023-05-07 15:46:17 +02:00
zadam
64db5e2542 cleanup of app.js, wwww 2023-05-07 15:23:46 +02:00
zadam
9f5f0aeddd fix hamburger icon in canvas 2023-05-07 11:54:04 +02:00
zadam
4d5612e845 fix updating non-text notes 2023-05-07 11:20:51 +02:00
zadam
371f174756 run hiddenSubtreeService.checkHiddenSubtree() also periodically, useful for server deployments, #3907 2023-05-07 10:54:06 +02:00
zadam
8284c673f9 can't allow opening externally on attachment list 2023-05-07 10:43:51 +02:00
zadam
cc02546ed3 Merge remote-tracking branch 'origin/master' into next60
# Conflicts:
#	src/routes/api/options.js
#	src/services/import/zip.js
#	src/services/options_init.js
2023-05-07 09:41:33 +02:00
zadam
2aa987c072 fixes for zip export/import in regard to attachments 2023-05-06 22:50:28 +02:00
zadam
a06ddc439d improving import WIP 2023-05-06 15:07:38 +02:00
zadam
f6944b8219 introducing meta types for import/export, fixes for attachments export 2023-05-06 14:38:45 +02:00
zadam
fa3cbb4645 grammar 2023-05-05 23:41:11 +02:00
zadam
6dfc72c065 many small fixes from Intellij analysis 2023-05-05 23:17:23 +02:00
zadam
0af6f91d21 exposing blobs in APIs 2023-05-05 22:21:51 +02:00
zadam
5e1f81e53e getting rid of note complement WIP 2023-05-05 16:37:39 +02:00
zadam
9cdcbb3125 fix runOnNoteContentChange event 2023-05-05 15:42:53 +02:00
zadam
35338e9ec6 fix runOnNoteContentChange event 2023-05-05 15:40:44 +02:00
zadam
78d83b8826 fix note size calculation with blobs 2023-05-05 15:18:55 +02:00
zadam
8edf06d28d small refactorings 2023-05-04 22:16:18 +02:00
zadam
ecd2a5cbac Merge remote-tracking branch 'origin/master' into next60 2023-05-04 21:01:53 +02:00
zadam
c0cf319521 upgrade electron to 25 and node to 18 2023-05-04 21:01:25 +02:00
zadam
9b32d86f78 take branch prefix into account while sorting, fixes #3896 2023-05-03 23:42:44 +02:00
zadam
fbffc6b2b5 inline attachment images into single HTML export 2023-05-03 23:17:07 +02:00
zadam
cd01886eb2 attachment revision upload 2023-05-03 22:49:24 +02:00
zadam
d8bc9c2982 attachment actions 2023-05-03 10:23:20 +02:00
zadam
d232694dec tree context menu to convert notes into attachments 2023-05-02 23:04:41 +02:00
zadam
735ac55bb8 fixes, allowing conversion of note into an attachment 2023-05-02 22:46:39 +02:00
zadam
330e7ac08e copying attachments WIP 2023-04-25 00:01:58 +02:00
zadam
49fb913eab erasing unused attachments 2023-04-24 21:22:34 +02:00
zadam
4b074365e7 Merge branch 'master' into next60 2023-04-24 20:21:45 +02:00
zadam
5e2efca933 scheduled erasure of attachments WIP 2023-04-21 00:19:17 +02:00
zadam
e71b0d82a1 scheduled attachment deletion WIP 2023-04-20 00:11:09 +02:00
zadam
c6c162cdda restore revision with attachments 2023-04-19 22:47:33 +02:00
zadam
8b46d6c718 Merge branch 'stable' into next60 2023-04-19 22:03:44 +02:00
zadam
e28fbf4617 fixes 2023-04-17 23:21:28 +02:00
zadam
0e4a040ed8 fixes of new attachment URLs 2023-04-17 22:40:53 +02:00
zadam
b84670d503 Merge branch 'master' into next60 2023-04-17 22:27:21 +02:00
zadam
f01657e1dd refactorings 2023-04-14 16:49:06 +02:00
zadam
34ecd77bd4 note revision save also saves attachments 2023-04-11 23:24:39 +02:00
zadam
6cf0fe0b73 attachments have a position 2023-04-11 22:55:50 +02:00
zadam
3f8bf7cacc renamed openTabs to openNoteContexts 2023-04-11 22:00:04 +02:00
zadam
17128c5874 navigation state is more nicely and completely serialized into URL 2023-04-11 21:41:55 +02:00
zadam
9e71c44c76 open attachment by double click 2023-04-11 18:05:57 +02:00
zadam
54c0268593 attachment improvements 2023-04-11 17:45:51 +02:00
zadam
a5f0b2a81e Merge remote-tracking branch 'origin/next60' into next60 2023-04-11 17:02:53 +02:00
zadam
a154bea016 Merge branch 'master' into next60 2023-04-11 17:02:24 +02:00
zadam
15a11daf38 Merge branch 'master' into next60
# Conflicts:
#	package-lock.json
#	package.json
2023-04-10 18:52:30 +02:00
zadam
5d6d9ab6d6 wip attachment support 2023-04-03 23:47:24 +02:00
zadam
2bc78ccafb wip attachment widget 2023-04-01 23:55:04 +02:00
zadam
53aebf1448 wip attachment widget 2023-04-01 13:58:53 +02:00
zadam
fa406d3ded wip attachment widget 2023-03-30 23:48:26 +02:00
zadam
9be524ef89 attachment improvements 2023-03-24 10:57:32 +01:00
zadam
fd8a2d4d92 hide global menu after changing note/context 2023-03-24 09:32:06 +01:00
zadam
0b270ee87a remove "hide included images" feature since with attachments it's no longer necessary 2023-03-24 09:17:17 +01:00
zadam
5cc5859211 migrate images to attachments 2023-03-24 09:13:35 +01:00
zadam
bd489d5780 node upgrades 2023-03-24 07:45:18 +01:00
zadam
a24c56a9d5 fixes 2023-03-20 23:11:32 +01:00
zadam
95e38a037b scrollbar tweak color 2023-03-20 20:50:18 +01:00
zadam
256b800d0e scrollbar tweak color 2023-03-20 20:48:52 +01:00
zadam
b3c4c850db Merge branch 'master' into next60 2023-03-20 20:21:30 +01:00
zadam
e698aa5822 uploading image to attachment 2023-03-16 20:13:34 +01:00
zadam
1fdb23746a uploading image to attachment 2023-03-16 18:34:39 +01:00
zadam
9cd5bdeb53 fix note revision 2023-03-16 17:49:35 +01:00
zadam
e6183b9a1d improved saving 2023-03-16 17:43:37 +01:00
zadam
d83005fe4d improved saving attachment 2023-03-16 16:37:31 +01:00
zadam
2b84f1be00 unify .setContent() .getContent() handling across notes, revisions, attachments 2023-03-16 15:19:26 +01:00
zadam
bb45c67e60 Merge branch 'stable' into next60 2023-03-16 13:39:28 +01:00
zadam
515fb4e5db blob WIP 2023-03-16 13:29:11 +01:00
zadam
b6efc954bd blob WIP 2023-03-16 12:17:55 +01:00
zadam
eee05a4d01 blob WIP 2023-03-16 12:11:00 +01:00
zadam
dc97400dbf ancillary => attachment 2023-03-16 11:03:28 +01:00
zadam
e16bedfab4 WIP blobs 2023-03-16 11:02:07 +01:00
zadam
5a8e216dec WIP blob 2023-03-15 22:44:08 +01:00
zadam
1faf8225c7 Merge branch 'master' into next60 2023-03-15 20:19:47 +01:00
zadam
5225a99995 wip 2023-03-09 09:38:02 +01:00
zadam
929f8ef720 note ancillary/attachment backported from dev branch 2023-03-08 09:01:23 +01:00
670 changed files with 40944 additions and 82020 deletions

View File

@@ -75,8 +75,6 @@ module.exports = {
glob: true,
log: true,
EditorWatchdog: true,
baseApiUrl: true,
// \src\share\canvas_share.js
React: true,
appState: true,
ExcalidrawLib: true,
@@ -93,17 +91,16 @@ module.exports = {
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\note_content_renderer.js
// \src\public\app\services\content_renderer.js
mermaid: true,
// src\public\app\services\frontend_script_api.js
dayjs: true,
// \src\public\app\widgets\dialogs\markdown_import.js
commonmark: true,
// \src\public\app\widgets\note_map.js
ForceGraph: true,
// \src\public\app\setup.js
@@ -112,7 +109,9 @@ module.exports = {
// src\public\app\services\utils.js
logInfo: true,
__non_webpack_require__: true,
//
describe: true,
it: true,
expect: true
},
parserOptions: {
ecmaVersion: 'latest',

3
.gitignore vendored
View File

@@ -11,5 +11,6 @@ cert.crt
server-package.json
.idea/httpRequests/
data/
data-test/
tmp/
.eslintcache
.eslintcache

View File

@@ -2,7 +2,7 @@ image:
file: .gitpod.dockerfile
tasks:
- before: nvm install 16.19.1 && nvm use 16.19.1
- before: nvm install 18.18.2 && nvm use 18.18.2
init: npm install
command: npm run start-server

4
.idea/dataSources.xml generated
View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="SQLite - document.db" uuid="30cef30d-e704-484d-a4ca-5d3bfc2ece63">
<data-source source="LOCAL" name="document.db" uuid="2a4ac1e6-b828-4a2a-8e4a-3f59f10aff26">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/../trilium-data/document.db</jdbc-url>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/data/document.db</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>

1
.idea/misc.xml generated
View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />

View File

@@ -1,11 +1,13 @@
//https://prettier.io/docs/en/options.html
//https://prettier.io/docs/en/options.html
module.exports = {
semi: true,
trailingComma: 'es5',
trailingComma: 'none',
singleQuote: true,
printWidth: 120,
printWidth: 100,
tabWidth: 4,
// useTabs: false,
// bracketSpacing: true,
useTabs: false,
quoteProps: "as-needed",
bracketSpacing: true,
arrowParens: "avoid"
// htmlWhitespaceSensitivity: 'ignore',
};

View File

@@ -1,5 +1,5 @@
# !!! Don't try to build this Dockerfile directly, run it through bin/build-docker.sh script !!!
FROM node:16.19.1-alpine
FROM node:18.18.2-alpine
# Create app directory
WORKDIR /usr/src/app

View File

@@ -1,8 +1,14 @@
# Trilium Notes
## Trilium is in maintenance mode - see details in https://github.com/zadam/trilium/issues/4620
Preliminary disccusions on the successor organization are taking place in [Trilium Next discussions](https://github.com/orgs/TriliumNext/discussions).
[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](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)
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:
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:
<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>

View File

@@ -5,18 +5,3 @@ echo "Packaging debian x64 distribution..."
VERSION=`jq -r ".version" package.json`
./node_modules/.bin/electron-installer-debian --config bin/deb-options.json --options.version=${VERSION} --arch amd64
# hacky stop-gag measure to produce debian compatible XZ compressed debs until this is fixed: https://github.com/electron-userland/electron-installer-debian/issues/272
cd dist
ar x trilium_${VERSION}_amd64.deb
rm trilium_${VERSION}_amd64.deb
# recompress
< control.tar.zst zstd -d | xz > control.tar.xz
< data.tar.zst zstd -d | xz > data.tar.xz
# create deb archive (I really do not know, what argument "sdsd" is for but something is required for ar to create the archive as desired)
ar -m -c -a sdsd trilium_${VERSION}_amd64.deb debian-binary control.tar.xz data.tar.xz
rm control* data* debian-binary
echo "Converted to XZ deb"

View File

@@ -2,52 +2,37 @@
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"/
# removing software WebGL binaries because they are pretty huge and not necessary
rm -r $BUILD_DIR/swiftshader
cp -r dump-db "$BUILD_DIR"/
rm -rf "$BUILD_DIR"/dump-db/node_modules
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
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

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
PKG_DIR=dist/trilium-linux-x64-server
NODE_VERSION=16.19.1
NODE_VERSION=18.18.2
if [ "$1" != "DONTCOPY" ]
then

View File

@@ -22,9 +22,6 @@ rm -rf $BUILD_DIR
mv "./dist/Trilium Notes-win32-x64" $BUILD_DIR
# removing software WebGL binaries because they are pretty huge and not necessary
rm -r $BUILD_DIR/swiftshader
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
cp -r dump-db $BUILD_DIR/

View File

@@ -4,47 +4,49 @@ 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 16.19.1 npm run webpack
n exec 18.18.2 npm run webpack || npm run webpack
DIR=$1
DIR="$1"
rm -rf $DIR
mkdir $DIR
rm -rf "$DIR"
mkdir -pv "$DIR"
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' 'electron.js'; do
cp "$f" "$DIR"/
done
cp webpack-* "$DIR"/ # here warning because there is no 'webpack-*', but webpack.config.js only
# run in subshell (so we return to original dir)
(cd $DIR && n exec 16.19.1 npm install --only=prod)
(cd $DIR && n exec 18.18.2 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

2
bin/create-anonymization-script.js Normal file → Executable file
View File

@@ -1,6 +1,6 @@
#!/usr/bin/env node
const anonymizationService = require('../src/services/anonymization');
const anonymizationService = require('../src/services/anonymization.js');
const fs = require('fs');
const path = require('path');

View File

@@ -1,6 +1,7 @@
{
"src": "dist/trilium-linux-x64",
"dest": "dist/",
"compression": "xz",
"name": "trilium",
"productName": "Trilium Notes",
"genericName": "Note taker",
@@ -11,4 +12,4 @@
"bin": "trilium",
"icon": "dist/trilium-linux-x64/icon.png",
"categories": [ "Office" ]
}
}

View File

@@ -1,166 +1,50 @@
UPDATE etapi_tokens SET tokenHash = 'API token hash value';
UPDATE notes SET title = 'title' WHERE noteId != 'root' AND noteId NOT LIKE '\_%' ESCAPE '\';
UPDATE note_contents SET content = 'text' WHERE content IS NOT NULL;
UPDATE note_revisions SET title = 'title';
UPDATE note_revision_contents SET content = 'text' WHERE content IS NOT NULL;
UPDATE attributes SET name = 'name', value = 'value'
WHERE type = 'label'
AND name NOT IN ('inbox',
'disableVersioning',
'calendarRoot',
'archived',
'excludeFromExport',
'disableInclusion',
'appCss',
'appTheme',
'hidePromotedAttributes',
'readOnly',
'autoReadOnlyDisabled',
'cssClass',
'iconClass',
'keyboardShortcut',
'run',
'runOnInstance',
'runAtHour',
'customRequestHandler',
'customResourceProvider',
'widget',
'noteInfoWidgetDisabled',
'linkMapWidgetDisabled',
'noteRevisionsWidgetDisabled',
'whatLinksHereWidgetDisabled',
'similarNotesWidgetDisabled',
'workspace',
'workspaceIconClass',
'workspaceTabBackgroundColor',
'searchHome',
'workspaceInbox',
'workspaceSearchHome',
'sqlConsoleHome',
'datePattern',
'pageSize',
'viewType',
'mapRootNoteId',
'bookmarkFolder',
'sorted',
'top',
'fullContentWidth',
'shareHiddenFromTree',
'shareAlias',
'shareOmitDefaultCss',
'shareRoot',
'internalLink',
'imageLink',
'relationMapLink',
'includeMapLink',
'runOnNoteCreation',
'runOnNoteTitleChange',
'runOnNoteContentChange',
'runOnNoteChange',
'runOnChildNoteCreation',
'runOnAttributeCreation',
'runOnAttributeChange',
'template',
'inherit',
'widget',
'renderNote',
'shareCss',
'shareJs',
'shareFavicon',
'executeButton',
'keepCurrentHoisting',
'color',
'toc',
'excludeFromNoteMap',
'docName',
'launcherType',
'builtinWidget',
'baseSize',
'growthFactor'
);
UPDATE attributes SET name = 'name'
AND name NOT IN ('inbox',
'disableVersioning',
'calendarRoot',
'archived',
'excludeFromExport',
'disableInclusion',
'appCss',
'appTheme',
'hidePromotedAttributes',
'readOnly',
'autoReadOnlyDisabled',
'cssClass',
'iconClass',
'keyboardShortcut',
'run',
'runOnInstance',
'runAtHour',
'customRequestHandler',
'customResourceProvider',
'widget',
'noteInfoWidgetDisabled',
'linkMapWidgetDisabled',
'noteRevisionsWidgetDisabled',
'whatLinksHereWidgetDisabled',
'similarNotesWidgetDisabled',
'workspace',
'workspaceIconClass',
'workspaceTabBackgroundColor',
'searchHome',
'workspaceInbox',
'workspaceSearchHome',
'sqlConsoleHome',
'datePattern',
'pageSize',
'viewType',
'mapRootNoteId',
'bookmarkFolder',
'sorted',
'top',
'fullContentWidth',
'shareHiddenFromTree',
'shareAlias',
'shareOmitDefaultCss',
'shareRoot',
'internalLink',
'imageLink',
'relationMapLink',
'includeMapLink',
'runOnNoteCreation',
'runOnNoteTitleChange',
'runOnNoteContentChange',
'runOnNoteChange',
'runOnChildNoteCreation',
'runOnAttributeCreation',
'runOnAttributeChange',
'template',
'inherit',
'widget',
'renderNote',
'shareCss',
'shareJs',
'shareFavicon',
'executeButton',
'keepCurrentHoisting',
'color',
'toc',
'excludeFromNoteMap',
'docName',
'launcherType',
'builtinWidget',
'baseSize',
'growthFactor'
);
UPDATE notes SET title = 'title'
WHERE noteId NOT IN ('root', '_hidden', '_share')
AND SUBSTR(noteId, 1, 8) != '_options'
AND SUBSTR(noteId, 1, 3) != '_lb';
UPDATE blobs SET content = 'text' WHERE content IS NOT NULL;
UPDATE revisions SET title = 'title';
UPDATE attributes SET name = 'name', value = 'value' WHERE type = 'label'
AND name NOT IN
('inbox', 'disableVersioning', 'calendarRoot', 'archived', 'excludeFromExport', 'disableInclusion', 'appCss',
'appTheme', 'hidePromotedAttributes', 'readOnly', 'autoReadOnlyDisabled', 'cssClass', 'iconClass',
'keyboardShortcut', 'run', 'runOnInstance', 'runAtHour', 'customRequestHandler', 'customResourceProvider',
'widget', 'noteInfoWidgetDisabled', 'linkMapWidgetDisabled', 'revisionsWidgetDisabled',
'whatLinksHereWidgetDisabled', 'similarNotesWidgetDisabled', 'workspace', 'workspaceIconClass',
'workspaceTabBackgroundColor', 'workspaceCalendarRoot', 'workspaceTemplate', 'searchHome', 'workspaceInbox',
'workspaceSearchHome', 'sqlConsoleHome', 'datePattern', 'pageSize', 'viewType', 'mapRootNoteId',
'bookmarkFolder', 'sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural', 'sortLocale', 'top',
'fullContentWidth', 'shareHiddenFromTree', 'shareExternalLink', 'shareOmitDefaultCss', 'shareRoot', 'shareDescription',
'shareRaw', 'shareDisallowRobotIndexing', 'shareIndex', 'displayRelations', 'hideRelations', 'titleTemplate',
'template', 'toc', 'color', 'keepCurrentHoisting', 'executeButton', 'executeDescription', 'newNotesOnTop',
'clipperInbox', 'internalLink', 'imageLink', 'relationMapLink', 'includeMapLink', 'runOnNoteCreation',
'runOnNoteTitleChange', 'runOnNoteChange', 'runOnNoteContentChange', 'runOnNoteDeletion', 'runOnBranchCreation', 'runOnBranchChange',
'runOnBranchDeletion', 'runOnChildNoteCreation', 'runOnAttributeCreation', 'runOnAttributeChange', 'template',
'inherit', 'widget', 'renderNote', 'shareCss', 'shareJs', 'shareTemplate', 'shareFavicon');
UPDATE attributes SET name = 'name' WHERE type = 'relation'
AND name NOT IN
('inbox', 'disableVersioning', 'calendarRoot', 'archived', 'excludeFromExport', 'disableInclusion', 'appCss',
'appTheme', 'hidePromotedAttributes', 'readOnly', 'autoReadOnlyDisabled', 'cssClass', 'iconClass',
'keyboardShortcut', 'run', 'runOnInstance', 'runAtHour', 'customRequestHandler', 'customResourceProvider',
'widget', 'noteInfoWidgetDisabled', 'linkMapWidgetDisabled', 'revisionsWidgetDisabled',
'whatLinksHereWidgetDisabled', 'similarNotesWidgetDisabled', 'workspace', 'workspaceIconClass',
'workspaceTabBackgroundColor', 'workspaceCalendarRoot', 'workspaceTemplate', 'searchHome', 'workspaceInbox',
'workspaceSearchHome', 'sqlConsoleHome', 'datePattern', 'pageSize', 'viewType', 'mapRootNoteId',
'bookmarkFolder', 'sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural', 'sortLocale', 'top',
'fullContentWidth', 'shareHiddenFromTree', 'shareExternalLink', 'shareOmitDefaultCss', 'shareRoot', 'shareDescription',
'shareRaw', 'shareDisallowRobotIndexing', 'shareIndex', 'displayRelations', 'hideRelations', 'titleTemplate',
'template', 'toc', 'color', 'keepCurrentHoisting', 'executeButton', 'executeDescription', 'newNotesOnTop',
'clipperInbox', 'internalLink', 'imageLink', 'relationMapLink', 'includeMapLink', 'runOnNoteCreation',
'runOnNoteTitleChange', 'runOnNoteChange', 'runOnNoteContentChange', 'runOnNoteDeletion', 'runOnBranchCreation', 'runOnBranchChange',
'runOnBranchDeletion', 'runOnChildNoteCreation', 'runOnAttributeCreation', 'runOnAttributeChange', 'template',
'inherit', 'widget', 'renderNote', 'shareCss', 'shareJs', 'shareTemplate', 'shareFavicon');
UPDATE branches SET prefix = 'prefix' WHERE prefix IS NOT NULL AND prefix != 'recovered';
UPDATE options SET value = 'anonymized' WHERE name IN
('documentId', 'documentSecret', 'encryptedDataKey',
'passwordVerificationHash', 'passwordVerificationSalt',
'passwordDerivedKeySalt', 'username', 'syncServerHost', 'syncProxy')
AND value != '';
('documentId', 'documentSecret', 'encryptedDataKey',
'passwordVerificationHash', 'passwordVerificationSalt',
'passwordDerivedKeySalt', 'username', 'syncServerHost', 'syncProxy')
AND value != '';
VACUUM;

View File

@@ -16,7 +16,7 @@ noBackup=false
# host=0.0.0.0
# port setting is relevant only for web deployments, desktop builds run on a fixed port (changeable with TRILIUM_PORT environment variable)
port=8080
# true for TLS/SSL/HTTPS (secure), false for HTTP (unsecure).
# true for TLS/SSL/HTTPS (secure), false for HTTP (insecure).
https=false
# path to certificate (run "bash bin/generate-cert.sh" to generate self-signed certificate). Relevant only if https=true
certPath=

View File

@@ -1,5 +1,4 @@
- isDeleted = 0 by default
- rename openTabs to openNoteContexts
- unify readOnly handling to a single attribute:
* readOnly - like now
* readOnly=auto - like without readOnly (used to override inherited readOnly)

Binary file not shown.

View File

@@ -1 +0,0 @@
module.exports = () => console.log("NOOP, moved to migration 0189");

View File

@@ -1,4 +0,0 @@
-- black theme has been removed, dark is closest replacement
UPDATE options SET value = 'dark' WHERE name = 'theme' AND value = 'black';
UPDATE options SET value = 'light' WHERE name = 'theme' AND value = 'white';

View File

@@ -1,2 +0,0 @@
ALTER TABLE branches DROP COLUMN utcDateCreated;
ALTER TABLE options DROP COLUMN utcDateCreated;

View File

@@ -1,33 +0,0 @@
CREATE TABLE IF NOT EXISTS "mig_entity_changes" (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`entityName` TEXT NOT NULL,
`entityId` TEXT NOT NULL,
`hash` TEXT NOT NULL,
`isErased` INT NOT NULL,
`changeId` TEXT NOT NULL,
`sourceId` TEXT NOT NULL,
`isSynced` INTEGER NOT NULL,
`utcDateChanged` TEXT NOT NULL
);
INSERT INTO mig_entity_changes (id, entityName, entityId, hash, isErased, changeId, sourceId, isSynced, utcDateChanged)
SELECT id, entityName, entityId, hash, isErased, '', sourceId, isSynced, utcDateChanged FROM entity_changes;
-- delete duplicates https://github.com/zadam/trilium/issues/2534
DELETE FROM mig_entity_changes WHERE isErased = 0 AND id IN (
SELECT id FROM mig_entity_changes ec
WHERE (
SELECT COUNT(*) FROM mig_entity_changes
WHERE ec.entityName = mig_entity_changes.entityName
AND ec.entityId = mig_entity_changes.entityId
) > 1
);
DROP TABLE entity_changes;
ALTER TABLE mig_entity_changes RENAME TO entity_changes;
CREATE UNIQUE INDEX `IDX_entityChanges_entityName_entityId` ON "entity_changes" (
`entityName`,
`entityId`
);

View File

@@ -1,8 +0,0 @@
UPDATE branches SET branchId = 'hidden' where branchId = (
SELECT branchId FROM branches
WHERE parentNoteId = 'root'
AND noteId = 'hidden'
AND isDeleted = 0
ORDER BY utcDateModified
LIMIT 1
);

View File

@@ -1 +0,0 @@
DELETE FROM options WHERE name = 'username';

View File

@@ -1,15 +0,0 @@
CREATE TABLE IF NOT EXISTS "etapi_tokens"
(
etapiTokenId TEXT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
tokenHash TEXT NOT NULL,
utcDateCreated TEXT NOT NULL,
utcDateModified TEXT NOT NULL,
isDeleted INT NOT NULL DEFAULT 0);
INSERT INTO etapi_tokens (etapiTokenId, name, tokenHash, utcDateCreated, utcDateModified, isDeleted)
SELECT apiTokenId, 'Trilium Sender', token, utcDateCreated, utcDateCreated, isDeleted FROM api_tokens;
DROP TABLE api_tokens;
UPDATE entity_changes SET entityName = 'etapi_tokens' WHERE entityName = 'api_tokens';

View File

@@ -1,10 +0,0 @@
module.exports = () => {
const sql = require('../../src/services/sql');
const crypto = require('crypto');
for (const {etapiTokenId, token} of sql.getRows("SELECT etapiTokenId, tokenHash AS token FROM etapi_tokens")) {
const tokenHash = crypto.createHash('sha256').update(token).digest('base64');
sql.execute(`UPDATE etapi_tokens SET tokenHash = ? WHERE etapiTokenId = ?`, [tokenHash, etapiTokenId]);
}
};

View File

@@ -1,20 +0,0 @@
DROP TABLE entity_changes;
-- not preserving the data because of https://github.com/zadam/trilium/issues/3447
CREATE TABLE IF NOT EXISTS "entity_changes" (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`entityName` TEXT NOT NULL,
`entityId` TEXT NOT NULL,
`hash` TEXT NOT NULL,
`isErased` INT NOT NULL,
`changeId` TEXT NOT NULL,
`componentId` TEXT NOT NULL,
`instanceId` TEXT NOT NULL,
`isSynced` INTEGER NOT NULL,
`utcDateChanged` TEXT NOT NULL
);
CREATE UNIQUE INDEX `IDX_entityChanges_entityName_entityId` ON "entity_changes" (
`entityName`,
`entityId`
);

View File

@@ -1 +0,0 @@
CREATE INDEX `IDX_entity_changes_changeId` ON `entity_changes` (`changeId`);

View File

@@ -1,15 +0,0 @@
const becca = require('../../src/becca/becca');
const beccaLoader = require('../../src/becca/becca_loader');
const cls = require('../../src/services/cls');
module.exports = () => {
cls.init(() => {
beccaLoader.load();
for (const note of Object.values(becca.notes)) {
if (note.hasLabel('calendarRoot')) {
note.addLabel('excludeFromNoteMap', "", true);
}
}
});
};

View File

@@ -1,2 +0,0 @@
-- removing potential remnants of recent notes in entity changes, see https://github.com/zadam/trilium/issues/2842
DELETE FROM entity_changes WHERE entityName = 'recent_notes';

View File

@@ -1,2 +0,0 @@
UPDATE attributes SET value = replace(value, 'setLabelValue', 'updateLabelValue') WHERE name = 'action' AND type = 'label';
UPDATE attributes SET value = replace(value, 'setRelationTarget', 'updateRelationTarget') WHERE name = 'action' AND type = 'label';

View File

@@ -1 +0,0 @@
module.exports = () => console.log("NOOP, increased because of protected notes IV change");

View File

@@ -1,6 +0,0 @@
UPDATE branches SET branchId = '_hidden__search' WHERE parentNoteId = 'hidden' AND noteId = 'search' AND isDeleted = 0;
UPDATE branches SET branchId = 'root__globalNoteMap' WHERE parentNoteId = 'singles' AND noteId = 'globalnotemap' AND isDeleted = 0;
UPDATE branches SET branchId = '_hidden__sqlConsole' WHERE parentNoteId = 'hidden' AND noteId = 'sqlconsole' AND isDeleted = 0;
UPDATE branches SET branchId = 'root__hidden' WHERE parentNoteId = 'root' AND noteId = 'hidden' AND isDeleted = 0;
UPDATE branches SET branchId = '_hidden__bulkAction' WHERE parentNoteId = 'hidden' AND noteId = 'bulkaction' AND isDeleted = 0;
UPDATE branches SET branchId = '_hidden__share' WHERE parentNoteId = 'root' AND noteId = 'share' AND isDeleted = 0;

View File

@@ -1,53 +0,0 @@
UPDATE notes SET noteId = '_globalNoteMap', title = 'Note Map' WHERE noteId = 'globalnotemap';
UPDATE note_contents SET noteId = '_globalNoteMap' WHERE noteId = 'globalnotemap';
UPDATE note_revisions SET noteId = '_globalNoteMap' WHERE noteId = 'globalnotemap';
UPDATE branches SET noteId = '_globalNoteMap' WHERE noteId = 'globalnotemap';
UPDATE branches SET parentNoteId = '_globalNoteMap' WHERE parentNoteId = 'globalnotemap';
UPDATE attributes SET noteId = '_globalNoteMap' WHERE noteId = 'globalnotemap';
UPDATE attributes SET value = '_globalNoteMap' WHERE type = 'relation' AND value = 'globalnotemap';
UPDATE entity_changes SET entityId = '_globalNoteMap' WHERE entityId = 'globalnotemap';
UPDATE notes SET noteId = '_bulkAction', title = 'Bulk Action' WHERE noteId = 'bulkaction';
UPDATE note_contents SET noteId = '_bulkAction' WHERE noteId = 'bulkaction';
UPDATE note_revisions SET noteId = '_bulkAction' WHERE noteId = 'bulkaction';
UPDATE branches SET parentNoteId = '_bulkAction' WHERE parentNoteId = 'bulkaction';
UPDATE branches SET noteId = '_bulkAction' WHERE noteId = 'bulkaction';
UPDATE attributes SET noteId = '_bulkAction' WHERE noteId = 'bulkaction';
UPDATE attributes SET value = '_bulkAction' WHERE type = 'relation' AND value = 'bulkaction';
UPDATE entity_changes SET entityId = '_bulkAction' WHERE entityId = 'bulkaction';
UPDATE notes SET noteId = '_sqlConsole', title = 'SQL Console History' WHERE noteId = 'sqlconsole';
UPDATE note_contents SET noteId = '_sqlConsole' WHERE noteId = 'sqlconsole';
UPDATE note_revisions SET noteId = '_sqlConsole' WHERE noteId = 'sqlconsole';
UPDATE branches SET noteId = '_sqlConsole' WHERE noteId = 'sqlconsole';
UPDATE branches SET parentNoteId = '_sqlConsole' WHERE parentNoteId = 'sqlconsole';
UPDATE attributes SET noteId = '_sqlConsole' WHERE noteId = 'sqlconsole';
UPDATE attributes SET value = '_sqlConsole' WHERE type = 'relation' AND value = 'sqlconsole';
UPDATE entity_changes SET entityId = '_sqlConsole' WHERE entityId = 'sqlconsole';
UPDATE notes SET noteId = '_hidden', title = 'Hidden Notes' WHERE noteId = 'hidden';
UPDATE note_contents SET noteId = '_hidden' WHERE noteId = 'hidden';
UPDATE note_revisions SET noteId = '_hidden' WHERE noteId = 'hidden';
UPDATE branches SET noteId = '_hidden', prefix = NULL WHERE noteId = 'hidden';
UPDATE branches SET parentNoteId = '_hidden' WHERE parentNoteId = 'hidden';
UPDATE attributes SET noteId = '_hidden' WHERE noteId = 'hidden';
UPDATE attributes SET value = '_hidden' WHERE type = 'relation' AND value = 'hidden';
UPDATE entity_changes SET entityId = '_hidden' WHERE entityId = 'hidden';
UPDATE notes SET noteId = '_search', title = 'Search History' WHERE noteId = 'search';
UPDATE note_contents SET noteId = '_search' WHERE noteId = 'search';
UPDATE note_revisions SET noteId = '_search' WHERE noteId = 'search';
UPDATE branches SET noteId = '_search' WHERE noteId = 'search';
UPDATE branches SET parentNoteId = '_search' WHERE parentNoteId = 'search';
UPDATE attributes SET noteId = '_search' WHERE noteId = 'search';
UPDATE attributes SET value = '_search' WHERE type = 'relation' AND value = 'search';
UPDATE entity_changes SET entityId = '_search' WHERE entityId = 'search';
UPDATE notes SET noteId = '_share', title = 'Shared Notes' WHERE noteId = 'share';
UPDATE note_contents SET noteId = '_share' WHERE noteId = 'share';
UPDATE note_revisions SET noteId = '_share' WHERE noteId = 'share';
UPDATE branches SET noteId = '_share' WHERE noteId = 'share';
UPDATE branches SET parentNoteId = '_share' WHERE parentNoteId = 'share';
UPDATE attributes SET noteId = '_share' WHERE noteId = 'share';
UPDATE attributes SET value = '_share' WHERE type = 'relation' AND value = 'share';
UPDATE entity_changes SET entityId = '_share' WHERE entityId = 'share';

View File

@@ -1,12 +0,0 @@
module.exports = () => {
const hiddenSubtreeService = require('../../src/services/hidden_subtree');
const cls = require("../../src/services/cls");
const beccaLoader = require("../../src/becca/becca_loader");
cls.init(() => {
beccaLoader.load();
// make sure the hidden subtree exists since the subsequent migrations we will move some existing notes into it (share...)
// in previous releases hidden subtree was created lazily
hiddenSubtreeService.checkHiddenSubtree(true);
});
};

View File

@@ -1,2 +0,0 @@
DELETE FROM branches WHERE noteId = '_share' AND parentNoteId != 'root' AND parentNoteId != '_hidden'; -- delete all other branches of _share if any
UPDATE branches SET parentNoteId = '_hidden' WHERE noteId = '_share';

View File

@@ -1,2 +0,0 @@
DELETE FROM branches WHERE noteId = '_globalNoteMap' AND parentNoteId != 'singles' AND parentNoteId != '_hidden'; -- make sure there are no clones which would fail at the next line
UPDATE branches SET parentNoteId = '_hidden' WHERE noteId = '_globalNoteMap';

View File

@@ -1,6 +0,0 @@
DELETE FROM branches WHERE noteId = 'singles';
DELETE FROM notes WHERE noteId = 'singles';
DELETE FROM note_contents WHERE noteId = 'singles';
DELETE FROM note_revisions WHERE noteId = 'singles';
DELETE FROM attributes WHERE noteId = 'singles';
DELETE FROM entity_changes WHERE entityId = 'singles';

View File

@@ -1,21 +0,0 @@
module.exports = () => {
const cls = require("../../src/services/cls");
const cloningService = require("../../src/services/cloning");
const beccaLoader = require("../../src/becca/becca_loader");
const becca = require("../../src/becca/becca");
cls.init(() => {
beccaLoader.load();
for (const attr of becca.findAttributes('label','bookmarked')) {
cloningService.toggleNoteInParent(true, attr.noteId, '_lbBookmarks');
attr.markAsDeleted("0204__migrate_bookmarks_to_clones");
}
// bookmarkFolder used to work in 0.57 without the bookmarked label
for (const attr of becca.findAttributes('label','bookmarkFolder')) {
cloningService.toggleNoteInParent(true, attr.noteId, '_lbBookmarks');
}
});
};

View File

@@ -1,3 +0,0 @@
UPDATE notes SET type = 'relationMap' WHERE type = 'relation-map';
UPDATE notes SET type = 'noteMap' WHERE type = 'note-map';
UPDATE notes SET type = 'webView' WHERE type = 'web-view';

View File

@@ -1,33 +0,0 @@
// the history was previously not exposed and the fact they were not cleaned up is rather a side-effect than an intention
module.exports = () => {
const cls = require("../../src/services/cls");
const beccaLoader = require("../../src/becca/becca_loader");
const becca = require("../../src/becca/becca");
cls.init(() => {
beccaLoader.load();
// deleting just branches because they might be cloned (and therefore saved) also outside of the hidden subtree
const searchRoot = becca.getNote('_search');
for (const searchBranch of searchRoot.getChildBranches()) {
const searchNote = searchBranch.getNote();
if (searchNote.type === 'search') {
searchBranch.deleteBranch('0206__delete_search_and_sql_console_history');
}
}
const sqlConsoleRoot = becca.getNote('_sqlConsole');
for (const sqlConsoleBranch of sqlConsoleRoot.getChildBranches()) {
const sqlConsoleNote = sqlConsoleBranch.getNote();
if (sqlConsoleNote.type === 'code' && sqlConsoleNote.mime === 'text/x-sqlite;schema=trilium') {
sqlConsoleBranch.deleteBranch('0206__delete_search_and_sql_console_history');
}
}
});
};

View File

@@ -1,2 +0,0 @@
UPDATE notes SET title = 'SQL Console History' WHERE noteId = '_sqlConsole';
UPDATE notes SET title = 'Search History' WHERE noteId = '_search';

View File

@@ -1,13 +0,0 @@
module.exports = () => {
const cls = require("../../src/services/cls");
const beccaLoader = require("../../src/becca/becca_loader");
const becca = require("../../src/becca/becca");
cls.init(() => {
beccaLoader.load();
for (const label of becca.getNote('_hidden').getLabels('archived')) {
label.markAsDeleted('0208__remove_archived_from_hidden');
}
});
};

View File

@@ -1,5 +0,0 @@
UPDATE attributes SET name = 'workspaceInbox' WHERE type = 'label' AND name = 'hoistedInbox';
UPDATE entity_changes SET entityId = 'workspaceInbox' WHERE entityName = 'attributes' AND entityId = 'hoistedInbox';
UPDATE attributes SET name = 'workspaceSearchHome' WHERE type = 'label' AND name = 'hoistedSearchHome';
UPDATE entity_changes SET entityId = 'workspaceSearchHome' WHERE entityName = 'attributes' AND entityId = 'hoistedSearchHome';

View File

@@ -1,24 +0,0 @@
module.exports = async () => {
const cls = require("../../src/services/cls");
const beccaLoader = require("../../src/becca/becca_loader");
const log = require("../../src/services/log");
const consistencyChecks = require("../../src/services/consistency_checks");
const noteService = require("../../src/services/notes");
await cls.init(async () => {
// precaution for the 0211 migration
noteService.eraseDeletedNotesNow();
beccaLoader.load();
try {
// precaution before running 211 which might produce unique constraint problems if the DB was not consistent
consistencyChecks.runOnDemandChecksWithoutExclusiveLock(true);
}
catch (e) {
// consistency checks might start failing in the future if there's some incompatible migration down the road
// we can optimistically assume the DB is consistent and still continue
log.error(`Consistency checks failed in migration 0210: ${e.message} ${e.stack}`);
}
});
};

View File

@@ -1,12 +0,0 @@
-- case based on isDeleted is needed, otherwise 2 branches (1 deleted, 1 not) might get the same ID
UPDATE entity_changes SET entityId = COALESCE((
SELECT
CASE isDeleted
WHEN 0 THEN parentNoteId || '_' || noteId
WHEN 1 THEN branchId
END
FROM branches WHERE branchId = entityId
), entityId)
WHERE entityName = 'branches' AND isErased = 0;
UPDATE branches SET branchId = parentNoteId || '_' || noteId WHERE isDeleted = 0;

View File

@@ -1,27 +0,0 @@
module.exports = () => {
const cls = require("../../src/services/cls");
const beccaLoader = require("../../src/becca/becca_loader");
const becca = require("../../src/becca/becca");
const log = require("../../src/services/log");
cls.init(() => {
beccaLoader.load();
const hidden = becca.getNote("_hidden");
if (!hidden) {
log.info("MIGRATION 212: no _hidden note, skipping.");
return;
}
for (const noteId of hidden.getSubtreeNoteIds({includeHidden: true})) {
if (noteId.startsWith("_")) { // is "named" note
const note = becca.getNote(noteId);
for (const attr of note.getOwnedAttributes()) {
attr.markAsDeleted("0212__delete_all_attributes_of_named_notes");
}
}
}
});
};

View File

@@ -1,48 +0,0 @@
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");
cls.init(() => {
beccaLoader.load();
for (const note of Object.values(becca.notes)) {
try {
if (!note.isJavaScript()) {
continue;
}
if (!note.mime?.endsWith('env=frontend') && !note.mime?.endsWith('env=backend')) {
continue;
}
const origContent = note.getContent().toString();
const fixedContent = origContent
.replaceAll("runOnServer", "runOnBackend")
.replaceAll("api.refreshTree()", "")
.replaceAll("addTextToActiveTabEditor", "addTextToActiveContextEditor")
.replaceAll("getActiveTabNote", "getActiveContextNote")
.replaceAll("getActiveTabTextEditor", "getActiveContextTextEditor")
.replaceAll("getActiveTabNotePath", "getActiveContextNotePath")
.replaceAll("getDateNote", "getDayNote")
.replaceAll("utils.unescapeHtml", "unescapeHtml")
.replaceAll("sortNotesByTitle", "sortNotes")
.replaceAll("CollapsibleWidget", "RightPanelWidget")
.replaceAll("TabAwareWidget", "NoteContextAwareWidget")
.replaceAll("TabCachingWidget", "NoteContextAwareWidget")
.replaceAll("NoteContextCachingWidget", "NoteContextAwareWidget");
if (origContent !== fixedContent) {
log.info(`Replacing legacy API calls for note '${note.noteId}'`);
note.saveNoteRevision();
note.setContent(fixedContent);
}
}
catch (e) {
log.error(`Error during migration to 213 for note '${note.noteId}': ${e.message} ${e.stack}`);
}
}
});
};

View File

@@ -0,0 +1,13 @@
CREATE TABLE IF NOT EXISTS "blobs" (
`blobId` TEXT NOT NULL,
`content` TEXT NULL DEFAULT NULL,
`dateModified` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`blobId`)
);
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);

View File

@@ -0,0 +1,62 @@
module.exports = () => {
const sql = require('../../src/services/sql.js');
const utils = require('../../src/services/utils.js');
const existingBlobIds = new Set();
for (const noteId of sql.getColumn(`SELECT noteId FROM note_contents`)) {
const row = sql.getRow(`SELECT noteId, content, dateModified, utcDateModified FROM note_contents WHERE noteId = ?`, [noteId]);
const blobId = utils.hashedBlobId(row.content);
if (!existingBlobIds.has(blobId)) {
existingBlobIds.add(blobId);
sql.insert('blobs', {
blobId,
content: row.content,
dateModified: row.dateModified,
utcDateModified: row.utcDateModified
});
sql.execute("UPDATE entity_changes SET entityName = 'blobs', entityId = ? WHERE entityName = 'note_contents' AND entityId = ?", [blobId, row.noteId]);
} else {
// duplicates
sql.execute("DELETE FROM entity_changes WHERE entityName = 'note_contents' AND entityId = ?", [row.noteId]);
}
sql.execute('UPDATE notes SET blobId = ? WHERE noteId = ?', [blobId, row.noteId]);
}
for (const noteRevisionId of sql.getColumn(`SELECT noteRevisionId FROM note_revision_contents`)) {
const row = sql.getRow(`SELECT noteRevisionId, content, utcDateModified FROM note_revision_contents WHERE noteRevisionId = ?`, [noteRevisionId]);
const blobId = utils.hashedBlobId(row.content);
if (!existingBlobIds.has(blobId)) {
existingBlobIds.add(blobId);
sql.insert('blobs', {
blobId,
content: row.content,
dateModified: row.utcDateModified,
utcDateModified: row.utcDateModified
});
sql.execute("UPDATE entity_changes SET entityName = 'blobs', entityId = ? WHERE entityName = 'note_revision_contents' AND entityId = ?", [blobId, row.noteRevisionId]);
} else {
// duplicates
sql.execute("DELETE FROM entity_changes WHERE entityName = 'note_revision_contents' AND entityId = ?", [row.noteId]);
}
sql.execute('UPDATE note_revisions SET blobId = ? WHERE noteRevisionId = ?', [blobId, row.noteRevisionId]);
}
const notesWithoutBlobIds = sql.getColumn("SELECT noteId FROM notes WHERE blobId IS NULL");
if (notesWithoutBlobIds.length > 0) {
throw new Error("BlobIds were not filled correctly in notes: " + JSON.stringify(notesWithoutBlobIds));
}
const noteRevisionsWithoutBlobIds = sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE blobId IS NULL");
if (noteRevisionsWithoutBlobIds.length > 0) {
throw new Error("BlobIds were not filled correctly in note revisions: " + JSON.stringify(noteRevisionsWithoutBlobIds));
}
};

View File

@@ -0,0 +1,4 @@
DROP TABLE note_contents;
DROP TABLE note_revision_contents;
DELETE FROM entity_changes WHERE entityName IN ('note_contents', 'note_revision_contents');

View File

@@ -0,0 +1,26 @@
CREATE TABLE IF NOT EXISTS "revisions" (`revisionId` TEXT NOT NULL PRIMARY KEY,
`noteId` TEXT NOT NULL,
type TEXT DEFAULT '' NOT NULL,
mime TEXT DEFAULT '' NOT NULL,
`title` TEXT NOT NULL,
`isProtected` INT NOT NULL DEFAULT 0,
blobId TEXT DEFAULT NULL,
`utcDateLastEdited` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
`dateLastEdited` TEXT NOT NULL,
`dateCreated` TEXT NOT NULL);
INSERT INTO revisions (revisionId, noteId, type, mime, title, isProtected, utcDateLastEdited, utcDateCreated, utcDateModified, dateLastEdited, dateCreated, blobId)
SELECT noteRevisionId, noteId, type, mime, title, isProtected, utcDateLastEdited, utcDateCreated, utcDateModified, dateLastEdited, dateCreated, blobId FROM note_revisions;
DROP TABLE note_revisions;
CREATE INDEX `IDX_revisions_noteId` ON `revisions` (`noteId`);
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';

View File

@@ -0,0 +1,23 @@
CREATE TABLE IF NOT EXISTS "attachments"
(
attachmentId TEXT not null primary key,
ownerId TEXT not null,
role TEXT not null,
mime TEXT not null,
title TEXT not null,
isProtected INT not null DEFAULT 0,
position INT default 0 not null,
blobId TEXT DEFAULT null,
dateModified TEXT NOT NULL,
utcDateModified TEXT not null,
utcDateScheduledForErasureSince TEXT DEFAULT NULL,
isDeleted INT not null,
deleteId TEXT DEFAULT NULL);
CREATE INDEX IDX_attachments_ownerId_role
on attachments (ownerId, role);
CREATE INDEX IDX_attachments_utcDateScheduledForErasureSince
on attachments (utcDateScheduledForErasureSince);
CREATE INDEX IF NOT EXISTS IDX_attachments_blobId on attachments (blobId);

View File

@@ -0,0 +1,27 @@
module.exports = () => {
const beccaLoader = require('../../src/becca/becca_loader.js');
const becca = require('../../src/becca/becca.js');
const cls = require('../../src/services/cls.js');
const log = require('../../src/services/log.js');
const sql = require('../../src/services/sql.js');
cls.init(() => {
// emergency disabling of image compression since it appears to make problems in migration to 0.61
sql.execute(`UPDATE options SET value = 'false' WHERE name = 'compressImages'`);
beccaLoader.load();
for (const note of Object.values(becca.notes)) {
try {
const attachment = note.convertToParentAttachment({autoConversion: true});
if (attachment) {
log.info(`Auto-converted note '${note.noteId}' into attachment '${attachment.attachmentId}'.`);
}
}
catch (e) {
log.error(`Cannot convert note '${note.noteId}' to attachment: ${e.message} ${e.stack}`);
}
}
});
};

View File

@@ -0,0 +1,2 @@
DELETE FROM options WHERE name = 'hideIncludedImages_main';
DELETE FROM entity_changes WHERE entityName = 'options' AND entityId = 'hideIncludedImages_main';

View File

@@ -0,0 +1,2 @@
UPDATE options SET name = 'openNoteContexts' WHERE name = 'openTabs';
UPDATE entity_changes SET entityId = 'openNoteContexts' WHERE entityName = 'options' AND entityId = 'openTabs';

View File

@@ -0,0 +1 @@
SELECT 1;

View File

@@ -0,0 +1,14 @@
UPDATE blobs SET blobId = REPLACE(blobId, '+', 'X');
UPDATE blobs SET blobId = REPLACE(blobId, '/', 'Y');
UPDATE notes SET blobId = REPLACE(blobId, '+', 'X');
UPDATE notes SET blobId = REPLACE(blobId, '/', 'Y');
UPDATE attachments SET blobId = REPLACE(blobId, '+', 'X');
UPDATE attachments SET blobId = REPLACE(blobId, '/', 'Y');
UPDATE revisions SET blobId = REPLACE(blobId, '+', 'X');
UPDATE revisions SET blobId = REPLACE(blobId, '/', 'Y');
UPDATE entity_changes SET entityId = REPLACE(entityId, '+', 'X') WHERE entityName = 'blobs';
UPDATE entity_changes SET entityId = REPLACE(entityId, '/', 'Y') WHERE entityName = 'blobs';

View File

@@ -0,0 +1,3 @@
CREATE INDEX IF NOT EXISTS IDX_notes_blobId on notes (blobId);
CREATE INDEX IF NOT EXISTS IDX_revisions_blobId on revisions (blobId);
CREATE INDEX IF NOT EXISTS IDX_attachments_blobId on attachments (blobId);

View File

@@ -0,0 +1 @@
UPDATE attributes SET value = 'contentAndAttachmentsAndRevisionsSize' WHERE name = 'orderBy' AND value = 'noteSize';

View File

@@ -0,0 +1,2 @@
-- emergency disabling of image compression since it appears to make problems in migration to 0.61
UPDATE options SET value = 'false' WHERE name = 'compressImages';

View File

@@ -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';

View File

@@ -35,6 +35,7 @@ CREATE TABLE IF NOT EXISTS "notes" (
`isProtected` INT NOT NULL DEFAULT 0,
`type` TEXT NOT NULL DEFAULT 'text',
`mime` TEXT NOT NULL DEFAULT 'text/html',
blobId TEXT DEFAULT NULL,
`isDeleted` INT NOT NULL DEFAULT 0,
`deleteId` TEXT DEFAULT NULL,
`dateCreated` TEXT NOT NULL,
@@ -42,27 +43,18 @@ CREATE TABLE IF NOT EXISTS "notes" (
`utcDateCreated` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`noteId`));
CREATE TABLE IF NOT EXISTS "note_contents" (
`noteId` TEXT NOT NULL,
`content` TEXT NULL DEFAULT NULL,
`dateModified` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`noteId`)
);
CREATE TABLE IF NOT EXISTS "note_revisions" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY,
CREATE TABLE IF NOT EXISTS "revisions" (`revisionId` TEXT NOT NULL PRIMARY KEY,
`noteId` TEXT NOT NULL,
type TEXT DEFAULT '' NOT NULL,
mime TEXT DEFAULT '' NOT NULL,
`title` TEXT NOT NULL,
`isProtected` INT NOT NULL DEFAULT 0,
blobId TEXT DEFAULT NULL,
`utcDateLastEdited` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
`dateLastEdited` TEXT NOT NULL,
`dateCreated` TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS "note_revision_contents" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY,
`content` TEXT,
`utcDateModified` TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS "options"
(
name TEXT not null PRIMARY KEY,
@@ -94,11 +86,11 @@ CREATE INDEX `IDX_notes_dateCreated` ON `notes` (`dateCreated`);
CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`);
CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`);
CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`);
CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (`noteId`);
CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCreated`);
CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`);
CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`);
CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`);
CREATE INDEX `IDX_revisions_noteId` ON `revisions` (`noteId`);
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 `IDX_entity_changes_changeId` ON `entity_changes` (`changeId`);
CREATE INDEX IDX_attributes_name_value
on attributes (name, value);
@@ -112,3 +104,31 @@ CREATE TABLE IF NOT EXISTS "recent_notes"
notePath TEXT not null,
utcDateCreated TEXT not null
);
CREATE TABLE IF NOT EXISTS "blobs" (
`blobId` TEXT NOT NULL,
`content` TEXT NULL DEFAULT NULL,
`dateModified` TEXT NOT NULL,
`utcDateModified` TEXT NOT NULL,
PRIMARY KEY(`blobId`)
);
CREATE TABLE IF NOT EXISTS "attachments"
(
attachmentId TEXT not null primary key,
ownerId TEXT not null,
role TEXT not null,
mime TEXT not null,
title TEXT not null,
isProtected INT not null DEFAULT 0,
position INT default 0 not null,
blobId TEXT DEFAULT null,
dateModified TEXT NOT NULL,
utcDateModified TEXT not null,
utcDateScheduledForErasureSince TEXT DEFAULT NULL,
isDeleted INT not null,
deleteId TEXT DEFAULT NULL);
CREATE INDEX IDX_attachments_ownerId_role
on attachments (ownerId, role);
CREATE INDEX IDX_notes_blobId on notes (blobId);
CREATE INDEX IDX_revisions_blobId on revisions (blobId);
CREATE INDEX IDX_attachments_blobId on attachments (blobId);

View File

@@ -1,3 +1,5 @@
# Running `docker-compose up` will create/use the "trilium-data" directory in the user home
# Run `TRILIUM_DATA_DIR=/path/of/your/choice docker-compose up` to set a different directory
version: '2.1'
services:
trilium:
@@ -8,7 +10,7 @@ services:
ports:
- "8080:8080"
volumes:
- trilium:/home/node/trilium-data
- ${TRILIUM_DATA_DIR:-~/trilium-data}:/home/node/trilium-data
volumes:
trilium:

View File

@@ -1,17 +1,17 @@
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.js');
const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, 'utf-8'));
if (config.https) {
if (config.Network.https) {
// built-in TLS (terminated by trilium) is not supported yet, PRs are welcome
// for reverse proxy terminated TLS this will works since config.https will be false
process.exit(0);
}
const port = require('./src/services/port');
const host = require('./src/services/host');
const port = require('./src/services/port.js');
const host = require('./src/services/host.js');
const options = { timeout: 2000 };

View File

@@ -93,7 +93,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line16">line 16</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line18">line 18</a>
</li></ul></dd>
@@ -183,7 +183,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line53">line 53</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line35">line 35</a>
</li></ul></dd>
@@ -211,7 +211,7 @@
<h4 class="name" id="addEntityChange"><span class="type-signature">(protected) </span>addEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="_getContent"><span class="type-signature">(protected) </span>_getContent<span class="signature">()</span><span class="type-signature"> &rarr; {string|Buffer}</span></h4>
@@ -259,7 +259,112 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line62">line 62</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line250">line 250</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
|
<span class="param-type">Buffer</span>
</dd>
</dl>
<h4 class="name" id="_setContent"><span class="type-signature">(protected) </span>_setContent<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
</li></ul></dd>
@@ -343,7 +448,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line18">line 18</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line20">line 20</a>
</li></ul></dd>
@@ -379,7 +484,7 @@
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"> &rarr; {string}</span></h4>
@@ -427,7 +532,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line30">line 30</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line59">line 59</a>
</li></ul></dd>
@@ -452,6 +557,24 @@
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
</dd>
</dl>
@@ -463,7 +586,7 @@
<h4 class="name" id="generateIdIfNecessary"><span class="type-signature">(protected) </span>generateIdIfNecessary<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="getPojo"><span class="type-signature">(abstract, protected) </span>getPojo<span class="signature">()</span><span class="type-signature"></span></h4>
@@ -511,7 +634,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line23">line 23</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line82">line 82</a>
</li></ul></dd>
@@ -679,7 +802,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line45">line 45</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line27">line 27</a>
</li></ul></dd>
@@ -725,7 +848,7 @@
<div class="description">
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.
This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
</div>
@@ -833,7 +956,91 @@ 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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line267">line 267</a>
</li></ul></dd>
</dl>
<h4 class="name" id="putEntityChange"><span class="type-signature">(protected) </span>putEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line44">line 44</a>
</li></ul></dd>
@@ -921,7 +1128,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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line83">line 83</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line91">line 91</a>
</li></ul></dd>
@@ -985,7 +1192,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -94,7 +94,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line16">line 16</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line22">line 22</a>
</li></ul></dd>
@@ -205,7 +205,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line47">line 47</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line53">line 53</a>
</li></ul></dd>
@@ -268,7 +268,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line53">line 53</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line35">line 35</a>
</li></ul></dd>
@@ -336,7 +336,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line59">line 59</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line65">line 65</a>
</li></ul></dd>
@@ -404,7 +404,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line53">line 53</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line59">line 59</a>
</li></ul></dd>
@@ -464,74 +464,6 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line49">line 49</a>
</li></ul></dd>
</dl>
<h4 class="name" id="position"><span class="type-signature"></span>position<span class="type-signature"> :int</span></h4>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type">int</span>
</li>
</ul>
<dl class="details">
@@ -558,7 +490,7 @@ and relation (representing named relationship between source and target note)</d
<h4 class="name" id="type"><span class="type-signature"></span>type<span class="type-signature"> :string</span></h4>
<h4 class="name" id="position"><span class="type-signature"></span>position<span class="type-signature"> :<a href="global.html#int">int</a></span></h4>
@@ -569,7 +501,7 @@ and relation (representing named relationship between source and target note)</d
<ul>
<li>
<span class="param-type">string</span>
<span class="param-type"><a href="global.html#int">int</a></span>
</li>
@@ -608,7 +540,75 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line51">line 51</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line61">line 61</a>
</li></ul></dd>
</dl>
<h4 class="name" id="type"><span class="type-signature"></span>type<span class="type-signature"> :<a href="global.html#AttributeType">AttributeType</a></span></h4>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type"><a href="global.html#AttributeType">AttributeType</a></span>
</li>
</ul>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line57">line 57</a>
</li></ul></dd>
@@ -676,7 +676,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line61">line 61</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line67">line 67</a>
</li></ul></dd>
@@ -744,7 +744,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line57">line 57</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line63">line 63</a>
</li></ul></dd>
@@ -772,7 +772,7 @@ and relation (representing named relationship between source and target note)</d
<h4 class="name" id="addEntityChange"><span class="type-signature">(protected) </span>addEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="_getContent"><span class="type-signature">(protected) </span>_getContent<span class="signature">()</span><span class="type-signature"> &rarr; {string|Buffer}</span></h4>
@@ -802,7 +802,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#addEntityChange">AbstractBeccaEntity#addEntityChange</a>
<a href="AbstractBeccaEntity.html#_getContent">AbstractBeccaEntity#_getContent</a>
</li></ul></dd>
@@ -825,7 +825,117 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line62">line 62</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line250">line 250</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
|
<span class="param-type">Buffer</span>
</dd>
</dl>
<h4 class="name" id="_setContent"><span class="type-signature">(protected) </span>_setContent<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#_setContent">AbstractBeccaEntity#_setContent</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
</li></ul></dd>
@@ -914,7 +1024,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line18">line 18</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line20">line 20</a>
</li></ul></dd>
@@ -950,7 +1060,7 @@ and relation (representing named relationship between source and target note)</d
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"> &rarr; {string}</span></h4>
@@ -1003,7 +1113,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line30">line 30</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line59">line 59</a>
</li></ul></dd>
@@ -1028,95 +1138,24 @@ and relation (representing named relationship between source and target note)</d
<h5>Returns:</h5>
<h4 class="name" id="generateIdIfNecessary"><span class="type-signature">(protected) </span>generateIdIfNecessary<span class="signature">()</span><span class="type-signature"></span></h4>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#generateIdIfNecessary">AbstractBeccaEntity#generateIdIfNecessary</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line23">line 23</a>
</li></ul></dd>
</dd>
</dl>
@@ -1176,7 +1215,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line129">line 129</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line135">line 135</a>
</li></ul></dd>
@@ -1227,6 +1266,95 @@ and relation (representing named relationship between source and target note)</d
<h4 class="name" id="getPojo"><span class="type-signature">(abstract, protected) </span>getPojo<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#getPojo">AbstractBeccaEntity#getPojo</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line82">line 82</a>
</li></ul></dd>
</dl>
@@ -1370,7 +1498,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line142">line 142</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line148">line 148</a>
</li></ul></dd>
@@ -1480,7 +1608,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line45">line 45</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line27">line 27</a>
</li></ul></dd>
@@ -1564,7 +1692,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line157">line 157</a>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line163">line 163</a>
</li></ul></dd>
@@ -1628,7 +1756,7 @@ and relation (representing named relationship between source and target note)</d
<div class="description">
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.
This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
</div>
@@ -1741,7 +1869,96 @@ 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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line267">line 267</a>
</li></ul></dd>
</dl>
<h4 class="name" id="putEntityChange"><span class="type-signature">(protected) </span>putEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#putEntityChange">AbstractBeccaEntity#putEntityChange</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line44">line 44</a>
</li></ul></dd>
@@ -1834,7 +2051,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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line83">line 83</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line91">line 91</a>
</li></ul></dd>
@@ -1898,7 +2115,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -203,7 +203,7 @@ Always check noteId instead.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line53">line 53</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line35">line 35</a>
</li></ul></dd>
@@ -463,7 +463,7 @@ of deletion should not act as a clone.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_bbranch.js.html">becca/entities/bbranch.js</a>, <a href="becca_entities_bbranch.js.html#line133">line 133</a>
<a href="becca_entities_bbranch.js.html">becca/entities/bbranch.js</a>, <a href="becca_entities_bbranch.js.html#line134">line 134</a>
</li></ul></dd>
@@ -549,7 +549,7 @@ of deletion should not act as a clone.
<h4 class="name" id="notePosition"><span class="type-signature"></span>notePosition<span class="type-signature"> :int</span></h4>
<h4 class="name" id="notePosition"><span class="type-signature"></span>notePosition<span class="type-signature"> :<a href="global.html#int">int</a></span></h4>
@@ -560,7 +560,7 @@ of deletion should not act as a clone.
<ul>
<li>
<span class="param-type">int</span>
<span class="param-type"><a href="global.html#int">int</a></span>
</li>
@@ -657,7 +657,7 @@ of deletion should not act as a clone.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_bbranch.js.html">becca/entities/bbranch.js</a>, <a href="becca_entities_bbranch.js.html#line111">line 111</a>
<a href="becca_entities_bbranch.js.html">becca/entities/bbranch.js</a>, <a href="becca_entities_bbranch.js.html#line112">line 112</a>
</li></ul></dd>
@@ -892,7 +892,7 @@ of deletion should not act as a clone.
<h4 class="name" id="addEntityChange"><span class="type-signature">(protected) </span>addEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="_getContent"><span class="type-signature">(protected) </span>_getContent<span class="signature">()</span><span class="type-signature"> &rarr; {string|Buffer}</span></h4>
@@ -922,7 +922,7 @@ of deletion should not act as a clone.
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#addEntityChange">AbstractBeccaEntity#addEntityChange</a>
<a href="AbstractBeccaEntity.html#_getContent">AbstractBeccaEntity#_getContent</a>
</li></ul></dd>
@@ -945,7 +945,117 @@ of deletion should not act as a clone.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line62">line 62</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line250">line 250</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
|
<span class="param-type">Buffer</span>
</dd>
</dl>
<h4 class="name" id="_setContent"><span class="type-signature">(protected) </span>_setContent<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#_setContent">AbstractBeccaEntity#_setContent</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
</li></ul></dd>
@@ -1034,7 +1144,7 @@ of deletion should not act as a clone.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line18">line 18</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line20">line 20</a>
</li></ul></dd>
@@ -1216,7 +1326,7 @@ of deletion should not act as a clone.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_bbranch.js.html">becca/entities/bbranch.js</a>, <a href="becca_entities_bbranch.js.html#line145">line 145</a>
<a href="becca_entities_bbranch.js.html">becca/entities/bbranch.js</a>, <a href="becca_entities_bbranch.js.html#line146">line 146</a>
</li></ul></dd>
@@ -1274,7 +1384,7 @@ of deletion should not act as a clone.
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"> &rarr; {string}</span></h4>
@@ -1327,7 +1437,7 @@ of deletion should not act as a clone.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line30">line 30</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line59">line 59</a>
</li></ul></dd>
@@ -1352,6 +1462,24 @@ of deletion should not act as a clone.
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
</dd>
</dl>
@@ -1363,7 +1491,109 @@ of deletion should not act as a clone.
<h4 class="name" id="generateIdIfNecessary"><span class="type-signature">(protected) </span>generateIdIfNecessary<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="getNote"><span class="type-signature"></span>getNote<span class="signature">()</span><span class="type-signature"> &rarr; {<a href="BNote.html">BNote</a>}</span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_bbranch.js.html">becca/entities/bbranch.js</a>, <a href="becca_entities_bbranch.js.html#line107">line 107</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type"><a href="BNote.html">BNote</a></span>
</dd>
</dl>
<h4 class="name" id="getPojo"><span class="type-signature">(abstract, protected) </span>getPojo<span class="signature">()</span><span class="type-signature"></span></h4>
@@ -1393,7 +1623,7 @@ of deletion should not act as a clone.
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#generateIdIfNecessary">AbstractBeccaEntity#generateIdIfNecessary</a>
<a href="AbstractBeccaEntity.html#getPojo">AbstractBeccaEntity#getPojo</a>
</li></ul></dd>
@@ -1416,7 +1646,7 @@ of deletion should not act as a clone.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line23">line 23</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line82">line 82</a>
</li></ul></dd>
@@ -1594,7 +1824,7 @@ of deletion should not act as a clone.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line45">line 45</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line27">line 27</a>
</li></ul></dd>
@@ -1640,7 +1870,7 @@ of deletion should not act as a clone.
<div class="description">
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.
This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
</div>
@@ -1753,7 +1983,96 @@ 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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line267">line 267</a>
</li></ul></dd>
</dl>
<h4 class="name" id="putEntityChange"><span class="type-signature">(protected) </span>putEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#putEntityChange">AbstractBeccaEntity#putEntityChange</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line44">line 44</a>
</li></ul></dd>
@@ -1846,7 +2165,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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line83">line 83</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line91">line 91</a>
</li></ul></dd>
@@ -1910,7 +2229,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -205,7 +205,7 @@ from tokenHash and token.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line53">line 53</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line35">line 35</a>
</li></ul></dd>
@@ -641,7 +641,7 @@ from tokenHash and token.</div>
<h4 class="name" id="addEntityChange"><span class="type-signature">(protected) </span>addEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="_getContent"><span class="type-signature">(protected) </span>_getContent<span class="signature">()</span><span class="type-signature"> &rarr; {string|Buffer}</span></h4>
@@ -671,7 +671,7 @@ from tokenHash and token.</div>
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#addEntityChange">AbstractBeccaEntity#addEntityChange</a>
<a href="AbstractBeccaEntity.html#_getContent">AbstractBeccaEntity#_getContent</a>
</li></ul></dd>
@@ -694,7 +694,117 @@ from tokenHash and token.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line62">line 62</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line250">line 250</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
|
<span class="param-type">Buffer</span>
</dd>
</dl>
<h4 class="name" id="_setContent"><span class="type-signature">(protected) </span>_setContent<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#_setContent">AbstractBeccaEntity#_setContent</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
</li></ul></dd>
@@ -783,7 +893,7 @@ from tokenHash and token.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line18">line 18</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line20">line 20</a>
</li></ul></dd>
@@ -819,7 +929,7 @@ from tokenHash and token.</div>
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"> &rarr; {string}</span></h4>
@@ -872,7 +982,7 @@ from tokenHash and token.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line30">line 30</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line59">line 59</a>
</li></ul></dd>
@@ -897,6 +1007,24 @@ from tokenHash and token.</div>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
</dd>
</dl>
@@ -908,7 +1036,7 @@ from tokenHash and token.</div>
<h4 class="name" id="generateIdIfNecessary"><span class="type-signature">(protected) </span>generateIdIfNecessary<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="getPojo"><span class="type-signature">(abstract, protected) </span>getPojo<span class="signature">()</span><span class="type-signature"></span></h4>
@@ -938,7 +1066,7 @@ from tokenHash and token.</div>
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#generateIdIfNecessary">AbstractBeccaEntity#generateIdIfNecessary</a>
<a href="AbstractBeccaEntity.html#getPojo">AbstractBeccaEntity#getPojo</a>
</li></ul></dd>
@@ -961,7 +1089,7 @@ from tokenHash and token.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line23">line 23</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line82">line 82</a>
</li></ul></dd>
@@ -1139,7 +1267,7 @@ from tokenHash and token.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line45">line 45</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line27">line 27</a>
</li></ul></dd>
@@ -1185,7 +1313,7 @@ from tokenHash and token.</div>
<div class="description">
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.
This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
</div>
@@ -1298,7 +1426,96 @@ 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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line267">line 267</a>
</li></ul></dd>
</dl>
<h4 class="name" id="putEntityChange"><span class="type-signature">(protected) </span>putEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#putEntityChange">AbstractBeccaEntity#putEntityChange</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line44">line 44</a>
</li></ul></dd>
@@ -1391,7 +1608,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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line83">line 83</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line91">line 91</a>
</li></ul></dd>
@@ -1455,7 +1672,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,7 @@
<h2><span class="attribs"><span class="type-signature"></span></span>BOption<span class="signature">()</span><span class="type-signature"></span></h2>
<div class="class-description">Option represents name-value pair, either directly configurable by the user or some system property.</div>
<div class="class-description">Option represents a name-value pair, either directly configurable by the user or some system property.</div>
</header>
@@ -199,7 +199,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line53">line 53</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line35">line 35</a>
</li></ul></dd>
@@ -499,7 +499,7 @@
<h4 class="name" id="addEntityChange"><span class="type-signature">(protected) </span>addEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="_getContent"><span class="type-signature">(protected) </span>_getContent<span class="signature">()</span><span class="type-signature"> &rarr; {string|Buffer}</span></h4>
@@ -529,7 +529,7 @@
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#addEntityChange">AbstractBeccaEntity#addEntityChange</a>
<a href="AbstractBeccaEntity.html#_getContent">AbstractBeccaEntity#_getContent</a>
</li></ul></dd>
@@ -552,7 +552,117 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line62">line 62</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line250">line 250</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
|
<span class="param-type">Buffer</span>
</dd>
</dl>
<h4 class="name" id="_setContent"><span class="type-signature">(protected) </span>_setContent<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#_setContent">AbstractBeccaEntity#_setContent</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
</li></ul></dd>
@@ -641,7 +751,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line18">line 18</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line20">line 20</a>
</li></ul></dd>
@@ -677,7 +787,7 @@
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"> &rarr; {string}</span></h4>
@@ -730,7 +840,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line30">line 30</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line59">line 59</a>
</li></ul></dd>
@@ -755,6 +865,24 @@
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
</dd>
</dl>
@@ -766,7 +894,7 @@
<h4 class="name" id="generateIdIfNecessary"><span class="type-signature">(protected) </span>generateIdIfNecessary<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="getPojo"><span class="type-signature">(abstract, protected) </span>getPojo<span class="signature">()</span><span class="type-signature"></span></h4>
@@ -796,7 +924,7 @@
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#generateIdIfNecessary">AbstractBeccaEntity#generateIdIfNecessary</a>
<a href="AbstractBeccaEntity.html#getPojo">AbstractBeccaEntity#getPojo</a>
</li></ul></dd>
@@ -819,7 +947,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line23">line 23</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line82">line 82</a>
</li></ul></dd>
@@ -997,7 +1125,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line45">line 45</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line27">line 27</a>
</li></ul></dd>
@@ -1043,7 +1171,7 @@
<div class="description">
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.
This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
</div>
@@ -1156,7 +1284,96 @@ 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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line267">line 267</a>
</li></ul></dd>
</dl>
<h4 class="name" id="putEntityChange"><span class="type-signature">(protected) </span>putEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#putEntityChange">AbstractBeccaEntity#putEntityChange</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line44">line 44</a>
</li></ul></dd>
@@ -1249,7 +1466,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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line83">line 83</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line91">line 91</a>
</li></ul></dd>
@@ -1313,7 +1530,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -199,7 +199,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line53">line 53</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line35">line 35</a>
</li></ul></dd>
@@ -431,7 +431,7 @@
<h4 class="name" id="addEntityChange"><span class="type-signature">(protected) </span>addEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="_getContent"><span class="type-signature">(protected) </span>_getContent<span class="signature">()</span><span class="type-signature"> &rarr; {string|Buffer}</span></h4>
@@ -461,7 +461,7 @@
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#addEntityChange">AbstractBeccaEntity#addEntityChange</a>
<a href="AbstractBeccaEntity.html#_getContent">AbstractBeccaEntity#_getContent</a>
</li></ul></dd>
@@ -484,7 +484,117 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line62">line 62</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line250">line 250</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
|
<span class="param-type">Buffer</span>
</dd>
</dl>
<h4 class="name" id="_setContent"><span class="type-signature">(protected) </span>_setContent<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#_setContent">AbstractBeccaEntity#_setContent</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
</li></ul></dd>
@@ -573,7 +683,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line18">line 18</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line20">line 20</a>
</li></ul></dd>
@@ -609,7 +719,7 @@
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="generateHash"><span class="type-signature">(protected) </span>generateHash<span class="signature">()</span><span class="type-signature"> &rarr; {string}</span></h4>
@@ -662,7 +772,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line30">line 30</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line59">line 59</a>
</li></ul></dd>
@@ -687,6 +797,24 @@
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">string</span>
</dd>
</dl>
@@ -698,7 +826,7 @@
<h4 class="name" id="generateIdIfNecessary"><span class="type-signature">(protected) </span>generateIdIfNecessary<span class="signature">()</span><span class="type-signature"></span></h4>
<h4 class="name" id="getPojo"><span class="type-signature">(abstract, protected) </span>getPojo<span class="signature">()</span><span class="type-signature"></span></h4>
@@ -728,7 +856,7 @@
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#generateIdIfNecessary">AbstractBeccaEntity#generateIdIfNecessary</a>
<a href="AbstractBeccaEntity.html#getPojo">AbstractBeccaEntity#getPojo</a>
</li></ul></dd>
@@ -751,7 +879,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line23">line 23</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line82">line 82</a>
</li></ul></dd>
@@ -929,7 +1057,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line45">line 45</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line27">line 27</a>
</li></ul></dd>
@@ -975,7 +1103,7 @@
<div class="description">
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.
This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
</div>
@@ -1088,7 +1216,96 @@ 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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line128">line 128</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line267">line 267</a>
</li></ul></dd>
</dl>
<h4 class="name" id="putEntityChange"><span class="type-signature">(protected) </span>putEntityChange<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-overrides">Overrides:</dt>
<dd class="tag-overrides"><ul class="dummy"><li>
<a href="AbstractBeccaEntity.html#putEntityChange">AbstractBeccaEntity#putEntityChange</a>
</li></ul></dd>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line44">line 44</a>
</li></ul></dd>
@@ -1181,7 +1398,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_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line83">line 83</a>
<a href="becca_entities_abstract_becca_entity.js.html">becca/entities/abstract_becca_entity.js</a>, <a href="becca_entities_abstract_becca_entity.js.html#line91">line 91</a>
</li></ul></dd>
@@ -1245,7 +1462,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,8 @@ 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");
let becca = null;
@@ -44,31 +46,11 @@ let becca = null;
class AbstractBeccaEntity {
/** @protected */
beforeSaving() {
this.generateIdIfNecessary();
}
/** @protected */
generateIdIfNecessary() {
if (!this[this.constructor.primaryKeyName]) {
this[this.constructor.primaryKeyName] = utils.newEntityId();
}
}
/** @protected */
generateHash(isDeleted = false) {
let contentToHash = "";
for (const propertyName of this.constructor.hashedProperties) {
contentToHash += `|${this[propertyName]}`;
}
if (isDeleted) {
contentToHash += "|deleted";
}
return utils.hash(contentToHash).substr(0, 10);
}
/** @protected */
getUtcDateChanged() {
return this.utcDateModified || this.utcDateCreated;
@@ -87,8 +69,8 @@ class AbstractBeccaEntity {
}
/** @protected */
addEntityChange(isDeleted = false) {
entityChangesService.addEntityChange({
putEntityChange(isDeleted) {
entityChangesService.putEntityChange({
entityName: this.constructor.entityName,
entityId: this[this.constructor.primaryKeyName],
hash: this.generateHash(isDeleted),
@@ -98,11 +80,37 @@ class AbstractBeccaEntity {
});
}
/**
* @protected
* @returns {string}
*/
generateHash(isDeleted) {
let contentToHash = "";
for (const propertyName of this.constructor.hashedProperties) {
contentToHash += `|${this[propertyName]}`;
}
if (isDeleted) {
contentToHash += "|deleted";
}
return utils.hash(contentToHash).substr(0, 10);
}
/** @protected */
getPojoToSave() {
return this.getPojo();
}
/**
* @protected
* @abstract
*/
getPojo() {
throw new Error(`Unimplemented getPojo() for entity '${this.constructor.name}'`)
}
/**
* Saves entity - executes SQL, but doesn't commit the transaction on its own
*
@@ -114,9 +122,7 @@ class AbstractBeccaEntity {
const isNewEntity = !this[primaryKeyName];
if (this.beforeSaving) {
this.beforeSaving(opts);
}
this.beforeSaving(opts);
const pojo = this.getPojoToSave();
@@ -127,7 +133,7 @@ class AbstractBeccaEntity {
return;
}
this.addEntityChange(false);
this.putEntityChange(!!this.isDeleted);
if (!cls.isEntityEventsDisabled()) {
const eventPayload = {
@@ -146,10 +152,143 @@ class AbstractBeccaEntity {
return this;
}
/** @protected */
_setContent(content, opts = {}) {
// 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]}'`);
}
if (this.hasStringContent()) {
content = content.toString();
} else {
content = Buffer.isBuffer(content) ? content : Buffer.from(content);
}
const unencryptedContentForHashCalculation = this.#getUnencryptedContentForHashCalculation(content);
if (this.isProtected) {
if (protectedSessionService.isProtectedSessionAvailable()) {
content = protectedSessionService.encrypt(content);
} 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 oldBlobId = this.blobId;
if (newBlobId !== oldBlobId || opts.forceSave) {
this.blobId = newBlobId;
this.save();
if (newBlobId !== oldBlobId) {
this.#deleteBlobIfNotUsed(oldBlobId);
}
}
});
}
#deleteBlobIfNotUsed(oldBlobId) {
if (sql.getValue("SELECT 1 FROM notes WHERE blobId = ? LIMIT 1", [oldBlobId])) {
return;
}
if (sql.getValue("SELECT 1 FROM attachments WHERE blobId = ? LIMIT 1", [oldBlobId])) {
return;
}
if (sql.getValue("SELECT 1 FROM revisions WHERE blobId = ? LIMIT 1", [oldBlobId])) {
return;
}
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
sql.execute("DELETE FROM entity_changes WHERE entityName = 'blobs' AND entityId = ?", [oldBlobId]);
}
#getUnencryptedContentForHashCalculation(unencryptedContent) {
if (this.isProtected) {
// a "random" prefix makes sure that the calculated hash/blobId is different for a decrypted/encrypted content
const encryptedPrefixSuffix = "t$[nvQg7q)&amp;_ENCRYPTED_?M:Bf&amp;j3jr_";
return Buffer.isBuffer(unencryptedContent)
? Buffer.concat([Buffer.from(encryptedPrefixSuffix), unencryptedContent])
: `${encryptedPrefixSuffix}${unencryptedContent}`;
} else {
return unencryptedContent;
}
}
#saveBlob(content, unencryptedContentForHashCalculation, opts = {}) {
/*
* 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).
* This has minor security implications (it's easy to infer that given content is shared between different
* notes/attachments), but the trade-off comes out clearly positive.
*/
const newBlobId = utils.hashedBlobId(unencryptedContentForHashCalculation);
const blobNeedsInsert = !sql.getValue('SELECT 1 FROM blobs WHERE blobId = ?', [newBlobId]);
if (!blobNeedsInsert) {
return newBlobId;
}
const pojo = {
blobId: newBlobId,
content: content,
dateModified: dateUtils.localNowDateTime(),
utcDateModified: dateUtils.utcNowDateTime()
};
sql.upsert("blobs", "blobId", pojo);
// we can't reuse blobId as an entity_changes hash, because this one has to be calculatable without having
// access to the decrypted content
const hash = blobService.calculateContentHash(pojo);
entityChangesService.putEntityChange({
entityName: 'blobs',
entityId: newBlobId,
hash: hash,
isErased: false,
utcDateChanged: pojo.utcDateModified,
isSynced: true,
// 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
});
eventService.emit(eventService.ENTITY_CHANGED, {
entityName: 'blobs',
entity: this
});
return newBlobId;
}
/**
* @protected
* @returns {string|Buffer}
*/
_getContent() {
const row = sql.getRow(`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}'`);
}
return blobService.processContent(row.content, this.isProtected, 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.
* This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
*
* @param [deleteId=null]
*/
@@ -172,7 +311,7 @@ class AbstractBeccaEntity {
log.info(`Marking ${entityName} ${entityId} as deleted`);
this.addEntityChange(true);
this.putEntityChange(true);
eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this });
}
@@ -189,7 +328,7 @@ class AbstractBeccaEntity {
log.info(`Marking ${entityName} ${entityId} as deleted`);
this.addEntityChange(true);
this.putEntityChange(true);
eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this });
}
@@ -206,7 +345,7 @@ module.exports = AbstractBeccaEntity;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -0,0 +1,294 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: becca/entities/battachment.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: becca/entities/battachment.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>"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");
const attachmentRoleToNoteTypeMapping = {
'image': 'image'
};
/**
* 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 {
static get entityName() { return "attachments"; }
static get primaryKeyName() { return "attachmentId"; }
static get hashedProperties() { return ["attachmentId", "ownerId", "role", "mime", "title", "blobId", "utcDateScheduledForErasureSince"]; }
constructor(row) {
super();
if (!row.ownerId?.trim()) {
throw new Error("'ownerId' must be given to initialize a Attachment entity");
} else if (!row.role?.trim()) {
throw new Error("'role' must be given to initialize a Attachment entity");
} else if (!row.mime?.trim()) {
throw new Error("'mime' must be given to initialize a Attachment entity");
} else if (!row.title?.trim()) {
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() {
return new BAttachment({
ownerId: this.ownerId,
role: this.role,
mime: this.mime,
title: this.title,
blobId: this.blobId,
isProtected: this.isProtected
});
}
/** @returns {BNote} */
getNote() {
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);
}
isContentAvailable() {
return !this.attachmentId // new attachment which was not encrypted yet
|| !this.isProtected
|| protectedSessionService.isProtectedSessionAvailable()
}
getTitleOrProtected() {
return this.isContentAvailable() ? this.title : '[protected]';
}
decrypt() {
if (!this.isProtected || !this.attachmentId) {
this.isDecrypted = true;
return;
}
if (!this.isDecrypted &amp;&amp; protectedSessionService.isProtectedSessionAvailable()) {
try {
this.title = protectedSessionService.decryptString(this.title);
this.isDecrypted = true;
}
catch (e) {
log.error(`Could not decrypt attachment ${this.attachmentId}: ${e.message} ${e.stack}`);
}
}
}
/** @returns {string|Buffer} */
getContent() {
return this._getContent();
}
/**
* @param content
* @param {object} [opts]
* @param {object} [opts.forceSave=false] - will also save this BAttachment entity
* @param {object} [opts.forceFrontendReload=false] - override frontend heuristics on when to reload, instruct to reload
*/
setContent(content, opts) {
this._setContent(content, opts);
}
/** @returns {{note: BNote, branch: BBranch}} */
convertToNote() {
if (this.type === 'search') {
throw new Error(`Note of type search cannot have child notes`);
}
if (!this.getNote()) {
throw new Error("Cannot find note of this attachment. It is possible that this is note revision's attachment. " +
"Converting note revision's attachments to note is not (yet) supported.");
}
if (!(this.role in attachmentRoleToNoteTypeMapping)) {
throw new Error(`Mapping from attachment role '${this.role}' to note's type is not defined`);
}
if (!this.isContentAvailable()) { // isProtected is the same for attachment
throw new Error(`Cannot convert protected attachment outside of protected session`);
}
const noteService = require('../../services/notes');
const { note, branch } = noteService.createNewNote({
parentNoteId: this.ownerId,
title: this.title,
type: attachmentRoleToNoteTypeMapping[this.role],
mime: this.mime,
content: this.getContent(),
isProtected: this.isProtected
});
this.markAsDeleted();
const parentNote = this.getNote();
if (this.role === 'image' &amp;&amp; parentNote.type === 'text') {
const origContent = parentNote.getContent();
const oldAttachmentUrl = `api/attachments/${this.attachmentId}/image/`;
const newNoteUrl = `api/images/${note.noteId}/`;
const fixedContent = utils.replaceAll(origContent, oldAttachmentUrl, newNoteUrl);
if (fixedContent !== origContent) {
parentNote.setContent(fixedContent);
}
noteService.asyncPostProcessContent(note, fixedContent);
}
return { note, branch };
}
getFileName() {
const type = this.role === 'image' ? 'image' : 'file';
return utils.formatDownloadTitle(this.title, type, this.mime);
}
beforeSaving() {
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.dateModified = dateUtils.localNowDateTime();
this.utcDateModified = dateUtils.utcNowDateTime();
}
getPojo() {
return {
attachmentId: this.attachmentId,
ownerId: this.ownerId,
role: this.role,
mime: this.mime,
title: this.title,
position: this.position,
blobId: this.blobId,
isProtected: !!this.isProtected,
isDeleted: false,
dateModified: this.dateModified,
utcDateModified: this.utcDateModified,
utcDateScheduledForErasureSince: this.utcDateScheduledForErasureSince,
contentLength: this.contentLength
};
}
getPojoToSave() {
const pojo = this.getPojo();
delete pojo.contentLength;
if (pojo.isProtected) {
if (this.isDecrypted) {
pojo.title = protectedSessionService.encrypt(pojo.title);
}
else {
// updating protected note outside of protected session means we will keep original ciphertexts
delete pojo.title;
}
}
return pojo;
}
}
module.exports = BAttachment;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@@ -35,6 +35,12 @@ const dateUtils = require("../../services/date_utils");
const promotedAttributeDefinitionParser = require("../../services/promoted_attribute_definition_parser");
const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name");
/**
* There are currently only two types of attributes, labels or relations.
* @typedef {"label" | "relation"} AttributeType
*/
/**
* Attribute is an abstract concept which has two real uses - label (key - value pair)
* and relation (representing named relationship between source and target note)
@@ -75,7 +81,7 @@ class BAttribute extends AbstractBeccaEntity {
this.attributeId = attributeId;
/** @type {string} */
this.noteId = noteId;
/** @type {string} */
/** @type {AttributeType} */
this.type = type;
/** @type {string} */
this.name = name;
@@ -169,7 +175,7 @@ class BAttribute extends AbstractBeccaEntity {
*/
getTargetNote() {
if (this.type !== 'relation') {
throw new Error(`Attribute ${this.attributeId} is not relation`);
throw new Error(`Attribute '${this.attributeId}' is not a relation.`);
}
if (!this.value) {
@@ -216,9 +222,11 @@ class BAttribute extends AbstractBeccaEntity {
this.value = "";
}
if (this.position === undefined) {
// TODO: can be calculated from becca
this.position = 1 + sql.getValue(`SELECT COALESCE(MAX(position), 0) FROM attributes WHERE noteId = ?`, [this.noteId]);
if (this.position === undefined || this.position === null) {
const maxExistingPosition = this.getNote().getAttributes()
.reduce((maxPosition, attr) => Math.max(maxPosition, attr.position || 0), 0);
this.position = maxExistingPosition + 10;
}
if (!this.isInheritable) {
@@ -270,7 +278,7 @@ module.exports = BAttribute;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: becca/entities/bblob.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: becca/entities/bblob.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>class BBlob {
static get entityName() { return "blobs"; }
static get primaryKeyName() { return "blobId"; }
static get hashedProperties() { return ["blobId", "content"]; }
constructor(row) {
/** @type {string} */
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,
contentLength: this.contentLength,
dateModified: this.dateModified,
utcDateModified: this.utcDateModified
};
}
}
module.exports = BBlob;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@@ -131,6 +131,7 @@ class BBranch extends AbstractBeccaEntity {
return this.becca.notes[this.noteId];
}
/** @returns {BNote} */
getNote() {
return this.childNote;
}
@@ -214,11 +215,11 @@ class BBranch extends AbstractBeccaEntity {
// first delete children and then parent - this will show up better in recent changes
log.info(`Deleting note ${note.noteId}`);
log.info(`Deleting note '${note.noteId}'`);
this.becca.notes[note.noteId].isBeingDeleted = true;
for (const attribute of note.getOwnedAttributes()) {
for (const attribute of note.getOwnedAttributes().slice()) {
attribute.markAsDeleted(deleteId);
}
@@ -226,6 +227,10 @@ class BBranch extends AbstractBeccaEntity {
relation.markAsDeleted(deleteId);
}
for (const attachment of note.getAttachments()) {
attachment.markAsDeleted(deleteId);
}
note.markAsDeleted(deleteId);
return true;
@@ -247,7 +252,7 @@ class BBranch extends AbstractBeccaEntity {
for (const childBranch of this.parentNote.getChildBranches()) {
if (maxNotePos &lt; childBranch.notePosition
&amp;&amp; childBranch.noteId !== '_hidden' // hidden has very large notePosition to always stay last
&amp;&amp; childBranch.noteId !== '_hidden' // hidden has a very large notePosition to always stay last
) {
maxNotePos = childBranch.notePosition;
}
@@ -313,7 +318,7 @@ module.exports = BBranch;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -114,7 +114,7 @@ module.exports = BEtapiToken;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -33,9 +33,9 @@ const log = require('../../services/log');
const sql = require('../../services/sql');
const utils = require('../../services/utils');
const dateUtils = require('../../services/date_utils');
const entityChangesService = require('../../services/entity_changes');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const BNoteRevision = require("./bnote_revision");
const BRevision = require("./brevision");
const BAttachment = require("./battachment");
const TaskContext = require("../../services/task_context");
const dayjs = require("dayjs");
const utc = require('dayjs/plugin/utc');
@@ -46,14 +46,29 @@ const LABEL = 'label';
const RELATION = 'relation';
/**
* Trilium's main entity which can represent text note, image, code note, file attachment etc.
* There are many different Note types, some of which are entirely opaque to the
* end user. Those types should be used only for checking against, they are
* not for direct use.
* @typedef {"file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code"} NoteType
*/
/**
* @typedef {Object} NotePathRecord
* @property {boolean} isArchived
* @property {boolean} isInHoistedSubTree
* @property {Array&lt;string>} notePath
* @property {boolean} isHidden
*/
/**
* Trilium's main entity, which can represent text note, image, code note, file attachment etc.
*
* @extends AbstractBeccaEntity
*/
class BNote extends AbstractBeccaEntity {
static get entityName() { return "notes"; }
static get primaryKeyName() { return "noteId"; }
static get hashedProperties() { return ["noteId", "title", "isProtected", "type", "mime"]; }
static get hashedProperties() { return ["noteId", "title", "isProtected", "type", "mime", "blobId"]; }
constructor(row) {
super();
@@ -73,6 +88,7 @@ class BNote extends AbstractBeccaEntity {
row.type,
row.mime,
row.isProtected,
row.blobId,
row.dateCreated,
row.dateModified,
row.utcDateCreated,
@@ -80,19 +96,21 @@ class BNote extends AbstractBeccaEntity {
]);
}
update([noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified]) {
update([noteId, title, type, mime, isProtected, blobId, dateCreated, dateModified, utcDateCreated, utcDateModified]) {
// ------ Database persisted attributes ------
/** @type {string} */
this.noteId = noteId;
/** @type {string} */
this.title = title;
/** @type {boolean} */
this.isProtected = !!isProtected;
/** @type {string} */
/** @type {NoteType} */
this.type = type;
/** @type {string} */
this.mime = mime;
/** @type {boolean} */
this.isProtected = !!isProtected;
/** @type {string} */
this.blobId = blobId;
/** @type {string} */
this.dateCreated = dateCreated || dateUtils.localNowDateTime();
/** @type {string} */
@@ -101,7 +119,10 @@ class BNote extends AbstractBeccaEntity {
this.utcDateCreated = utcDateCreated || dateUtils.utcNowDateTime();
/** @type {string} */
this.utcDateModified = utcDateModified;
/** @type {boolean} - set during the deletion operation, before it is completed (removed from becca completely) */
/**
* set during the deletion operation, before it is completed (removed from becca completely)
* @type {boolean}
*/
this.isBeingDeleted = false;
// ------ Derived attributes ------
@@ -112,7 +133,7 @@ class BNote extends AbstractBeccaEntity {
this.decrypt();
/** @type {string|null} */
this.flatTextCache = null;
this.__flatTextCache = null;
return this;
}
@@ -136,7 +157,7 @@ class BNote extends AbstractBeccaEntity {
this.__attributeCache = null;
/** @type {BAttribute[]|null}
* @private */
this.inheritableAttributeCache = null;
this.__inheritableAttributeCache = null;
/** @type {BAttribute[]}
* @private */
@@ -146,9 +167,9 @@ class BNote extends AbstractBeccaEntity {
/** @type {BNote[]|null}
* @private */
this.ancestorCache = null;
this.__ancestorCache = null;
// following attributes are filled during searching from database
// following attributes are filled during searching in the database
/**
* size of the content in bytes
@@ -157,11 +178,17 @@ class BNote extends AbstractBeccaEntity {
*/
this.contentSize = null;
/**
* size of the content and note revision contents in bytes
* size of the note content, attachment contents in bytes
* @type {int|null}
* @private
*/
this.noteSize = null;
this.contentAndAttachmentsSize = null;
/**
* size of the note content, attachment contents and revision contents in bytes
* @type {int|null}
* @private
*/
this.contentAndAttachmentsAndRevisionsSize = null;
/**
* number of note revisions for this note
* @type {int|null}
@@ -231,49 +258,48 @@ class BNote extends AbstractBeccaEntity {
* - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity)
*/
/** @returns {*} */
getContent(silentNotFoundError = false) {
const row = sql.getRow(`SELECT content FROM note_contents WHERE noteId = ?`, [this.noteId]);
/** @returns {string|Buffer} */
getContent() {
return this._getContent();
}
if (!row) {
if (silentNotFoundError) {
return undefined;
}
else {
throw new Error(`Cannot find note content for noteId=${this.noteId}`);
}
/**
* @returns {*}
* @throws Error in case of invalid JSON */
getJsonContent() {
const content = this.getContent();
if (!content || !content.trim()) {
return null;
}
let content = row.content;
return JSON.parse(content);
}
if (this.isProtected) {
if (protectedSessionService.isProtectedSessionAvailable()) {
content = content === null ? null : protectedSessionService.decrypt(content);
}
else {
content = "";
}
/** @returns {*|null} valid object or null if the content cannot be parsed as JSON */
getJsonContentSafely() {
try {
return this.getJsonContent();
}
if (this.isStringNote()) {
return content === null
? ""
: content.toString("UTF-8");
}
else {
return content;
catch (e) {
return null;
}
}
/** @returns {{contentLength, dateModified, utcDateModified}} */
getContentMetadata() {
return sql.getRow(`
SELECT
LENGTH(content) AS contentLength,
dateModified,
utcDateModified
FROM note_contents
WHERE noteId = ?`, [this.noteId]);
/**
* @param content
* @param {object} [opts]
* @param {object} [opts.forceSave=false] - will also save this BNote entity
* @param {object} [opts.forceFrontendReload=false] - override frontend heuristics on when to reload, instruct to reload
*/
setContent(content, opts) {
this._setContent(content, opts);
eventService.emit(eventService.NOTE_CONTENT_CHANGE, { entity: this });
}
setJsonContent(content) {
this.setContent(JSON.stringify(content, null, '\t'));
}
get dateCreatedObj() {
@@ -292,68 +318,6 @@ class BNote extends AbstractBeccaEntity {
return this.utcDateModified === null ? null : dayjs.utc(this.utcDateModified);
}
/** @returns {*} */
getJsonContent() {
const content = this.getContent();
if (!content || !content.trim()) {
return null;
}
return JSON.parse(content);
}
setContent(content, ignoreMissingProtectedSession = false) {
if (content === null || content === undefined) {
throw new Error(`Cannot set null content to note '${this.noteId}'`);
}
if (this.isStringNote()) {
content = content.toString();
}
else {
content = Buffer.isBuffer(content) ? content : Buffer.from(content);
}
const pojo = {
noteId: this.noteId,
content: content,
dateModified: dateUtils.localNowDateTime(),
utcDateModified: dateUtils.utcNowDateTime()
};
if (this.isProtected) {
if (protectedSessionService.isProtectedSessionAvailable()) {
pojo.content = protectedSessionService.encrypt(pojo.content);
}
else if (!ignoreMissingProtectedSession) {
throw new Error(`Cannot update content of noteId '${this.noteId}' since we're out of protected session.`);
}
}
sql.upsert("note_contents", "noteId", pojo);
const hash = utils.hash(`${this.noteId}|${pojo.content.toString()}`);
entityChangesService.addEntityChange({
entityName: 'note_contents',
entityId: this.noteId,
hash: hash,
isErased: false,
utcDateChanged: pojo.utcDateModified,
isSynced: true
});
eventService.emit(eventService.ENTITY_CHANGED, {
entityName: 'note_contents',
entity: this
});
}
setJsonContent(content) {
this.setContent(JSON.stringify(content, null, '\t'));
}
/** @returns {boolean} true if this note is the root of the note tree. Root note has "root" noteId */
isRoot() {
return this.noteId === 'root';
@@ -384,8 +348,13 @@ class BNote extends AbstractBeccaEntity {
|| (this.type === 'file' &amp;&amp; this.mime?.startsWith('image/'));
}
/** @returns {boolean} true if the note has string content (not binary) */
/** @deprecated use hasStringContent() instead */
isStringNote() {
return this.hasStringContent();
}
/** @returns {boolean} true if the note has string content (not binary) */
hasStringContent() {
return utils.isStringNote(this.type, this.mime);
}
@@ -407,6 +376,9 @@ class BNote extends AbstractBeccaEntity {
}
/**
* Beware that the method must not create a copy of the array, but actually returns its internal array
* (for performance reasons)
*
* @param {string} [type] - (optional) attribute type to filter
* @param {string} [name] - (optional) attribute name to filter
* @returns {BAttribute[]} all note's attributes, including inherited ones
@@ -425,7 +397,6 @@ class BNote extends AbstractBeccaEntity {
return this.__attributeCache.filter(attr => attr.name === name);
}
else {
// a bit unsafe to return the original array, but defensive copy would be costly
return this.__attributeCache;
}
}
@@ -482,11 +453,11 @@ class BNote extends AbstractBeccaEntity {
}
}
this.inheritableAttributeCache = [];
this.__inheritableAttributeCache = [];
for (const attr of this.__attributeCache) {
if (attr.isInheritable) {
this.inheritableAttributeCache.push(attr);
this.__inheritableAttributeCache.push(attr);
}
}
}
@@ -503,11 +474,11 @@ class BNote extends AbstractBeccaEntity {
return [];
}
if (!this.inheritableAttributeCache) {
this.__getAttributes(path); // will refresh also this.inheritableAttributeCache
if (!this.__inheritableAttributeCache) {
this.__getAttributes(path); // will refresh also this.__inheritableAttributeCache
}
return this.inheritableAttributeCache;
return this.__inheritableAttributeCache;
}
__validateTypeName(type, name) {
@@ -656,7 +627,8 @@ class BNote extends AbstractBeccaEntity {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @returns {BAttribute} attribute of given type and name. If there's more such attributes, first is returned. Returns null if there's no such attribute belonging to this note.
* @returns {BAttribute} attribute of the given type and name. If there are more such attributes, first is returned.
* Returns null if there's no such attribute belonging to this note.
*/
getAttribute(type, name) {
const attributes = this.getAttributes();
@@ -735,6 +707,9 @@ class BNote extends AbstractBeccaEntity {
}
/**
* Beware that the method must not create a copy of the array, but actually returns its internal array
* (for performance reasons)
*
* @param {string|null} [type] - (optional) attribute type to filter
* @param {string|null} [name] - (optional) attribute name to filter
* @param {string|null} [value] - (optional) attribute value to filter
@@ -756,7 +731,7 @@ class BNote extends AbstractBeccaEntity {
return this.ownedAttributes.filter(attr => attr.name === name);
}
else {
return this.ownedAttributes.slice();
return this.ownedAttributes;
}
}
@@ -778,7 +753,7 @@ class BNote extends AbstractBeccaEntity {
areAllNotePathsArchived() {
// there's a slight difference between note being itself archived and all its note paths being archived
// - note is archived when it itself has an archived label or inherits it
// - note does not have or inherit archived label, but each note paths contains a note with (non-inheritable)
// - note does not have or inherit archived label, but each note path contains a note with (non-inheritable)
// archived label
const bestNotePathRecord = this.getSortedNotePathRecords()[0];
@@ -809,7 +784,7 @@ class BNote extends AbstractBeccaEntity {
} else if (a.parentNote?.isHiddenCompletely()) {
return 1;
} else {
return -1;
return 0;
}
});
@@ -829,7 +804,7 @@ class BNote extends AbstractBeccaEntity {
const aBranch = becca.getBranchFromChildAndParent(a.noteId, this.noteId);
const bBranch = becca.getBranchFromChildAndParent(b.noteId, this.noteId);
return aBranch?.notePosition &lt; bBranch?.notePosition ? -1 : 1;
return (aBranch?.notePosition - bBranch?.notePosition) || 0;
});
}
@@ -841,40 +816,40 @@ class BNote extends AbstractBeccaEntity {
* @returns {string} - returns flattened textual representation of note, prefixes and attributes
*/
getFlatText() {
if (!this.flatTextCache) {
this.flatTextCache = `${this.noteId} ${this.type} ${this.mime} `;
if (!this.__flatTextCache) {
this.__flatTextCache = `${this.noteId} ${this.type} ${this.mime} `;
for (const branch of this.parentBranches) {
if (branch.prefix) {
this.flatTextCache += `${branch.prefix} `;
this.__flatTextCache += `${branch.prefix} `;
}
}
this.flatTextCache += `${this.title} `;
this.__flatTextCache += `${this.title} `;
for (const attr of this.getAttributes()) {
// it's best to use space as separator since spaces are filtered from the search string by the tokenization into words
this.flatTextCache += `${attr.type === 'label' ? '#' : '~'}${attr.name}`;
this.__flatTextCache += `${attr.type === 'label' ? '#' : '~'}${attr.name}`;
if (attr.value) {
this.flatTextCache += `=${attr.value}`;
this.__flatTextCache += `=${attr.value}`;
}
this.flatTextCache += ' ';
this.__flatTextCache += ' ';
}
this.flatTextCache = utils.normalize(this.flatTextCache);
this.__flatTextCache = utils.normalize(this.__flatTextCache);
}
return this.flatTextCache;
return this.__flatTextCache;
}
invalidateThisCache() {
this.flatTextCache = null;
this.__flatTextCache = null;
this.__attributeCache = null;
this.inheritableAttributeCache = null;
this.ancestorCache = null;
this.__inheritableAttributeCache = null;
this.__ancestorCache = null;
}
invalidateSubTree(path = []) {
@@ -903,24 +878,6 @@ class BNote extends AbstractBeccaEntity {
}
}
invalidateSubtreeFlatText() {
this.flatTextCache = null;
for (const childNote of this.children) {
childNote.invalidateSubtreeFlatText();
}
for (const targetRelation of this.targetRelations) {
if (targetRelation.name === 'template' || targetRelation.name === 'inherit') {
const note = targetRelation.note;
if (note) {
note.invalidateSubtreeFlatText();
}
}
}
}
getRelationDefinitions() {
return this.getLabels()
.filter(l => l.name.startsWith("relation:"));
@@ -1049,7 +1006,7 @@ class BNote extends AbstractBeccaEntity {
};
}
/** @returns {String[]} - includes the subtree node as well */
/** @returns {string[]} - includes the subtree root note as well */
getSubtreeNoteIds({includeArchived = true, includeHidden = false, resolveSearch = false} = {}) {
return this.getSubtree({includeArchived, includeHidden, resolveSearch})
.notes
@@ -1111,28 +1068,33 @@ class BNote extends AbstractBeccaEntity {
/** @returns {BNote[]} */
getAncestors() {
if (!this.ancestorCache) {
if (!this.__ancestorCache) {
const noteIds = new Set();
this.ancestorCache = [];
this.__ancestorCache = [];
for (const parent of this.parents) {
if (noteIds.has(parent.noteId)) {
continue;
}
this.ancestorCache.push(parent);
this.__ancestorCache.push(parent);
noteIds.add(parent.noteId);
for (const ancestorNote of parent.getAncestors()) {
if (!noteIds.has(ancestorNote.noteId)) {
this.ancestorCache.push(ancestorNote);
this.__ancestorCache.push(ancestorNote);
noteIds.add(ancestorNote.noteId);
}
}
}
}
return this.ancestorCache;
return this.__ancestorCache;
}
/** @returns {string[]} */
getAncestorNoteIds() {
return this.getAncestors().map(note => note.noteId);
}
/** @returns {boolean} */
@@ -1150,6 +1112,7 @@ class BNote extends AbstractBeccaEntity {
return this.noteId === '_hidden' || this.hasAncestor('_hidden');
}
/** @returns {BAttribute[]} */
getTargetRelations() {
return this.targetRelations;
}
@@ -1186,10 +1149,61 @@ class BNote extends AbstractBeccaEntity {
return minDistance;
}
/** @returns {BNoteRevision[]} */
getNoteRevisions() {
return sql.getRows("SELECT * FROM note_revisions WHERE noteId = ?", [this.noteId])
.map(row => new BNoteRevision(row));
/** @returns {BRevision[]} */
getRevisions() {
return sql.getRows("SELECT * FROM revisions WHERE noteId = ?", [this.noteId])
.map(row => new BRevision(row));
}
/** @returns {BAttachment[]} */
getAttachments(opts = {}) {
opts.includeContentLength = !!opts.includeContentLength;
// from testing, it looks like calculating length does not make a difference in performance even on large-ish DB
// given that we're always fetching attachments only for a specific note, we might just do it always
const query = opts.includeContentLength
? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength
FROM attachments
JOIN blobs USING (blobId)
WHERE ownerId = ? AND isDeleted = 0
ORDER BY position`
: `SELECT * FROM attachments WHERE ownerId = ? AND isDeleted = 0 ORDER BY position`;
return sql.getRows(query, [this.noteId])
.map(row => new BAttachment(row));
}
/** @returns {BAttachment|null} */
getAttachmentById(attachmentId, opts = {}) {
opts.includeContentLength = !!opts.includeContentLength;
const query = opts.includeContentLength
? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength
FROM attachments
JOIN blobs USING (blobId)
WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`
: `SELECT * FROM attachments WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`;
return sql.getRows(query, [this.noteId, attachmentId])
.map(row => new BAttachment(row))[0];
}
/** @returns {BAttachment[]} */
getAttachmentsByRole(role) {
return sql.getRows(`
SELECT attachments.*
FROM attachments
WHERE ownerId = ?
AND role = ?
AND isDeleted = 0
ORDER BY position`, [this.noteId, role])
.map(row => new BAttachment(row));
}
/** @returns {BAttachment} */
getAttachmentByTitle(title) {
// cannot use SQL to filter by title since it can be encrypted
return this.getAttachments().filter(attachment => attachment.title === title)[0];
}
/**
@@ -1203,13 +1217,10 @@ class BNote extends AbstractBeccaEntity {
}
const parentNotes = this.getParentNotes();
let notePaths = [];
if (parentNotes.length === 1) { // optimization for most common case
notePaths = parentNotes[0].getAllNotePaths();
} else {
notePaths = parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
}
const notePaths = parentNotes.length === 1
? parentNotes[0].getAllNotePaths() // optimization for the most common case
: parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
for (const notePath of notePaths) {
notePath.push(this.noteId);
@@ -1220,7 +1231,7 @@ class BNote extends AbstractBeccaEntity {
/**
* @param {string} [hoistedNoteId='root']
* @return {Array&lt;{isArchived: boolean, isInHoistedSubTree: boolean, notePath: Array&lt;string>, isHidden: boolean}>}
* @return {Array&lt;NotePathRecord>}
*/
getSortedNotePathRecords(hoistedNoteId = 'root') {
const isHoistedRoot = hoistedNoteId === 'root';
@@ -1248,7 +1259,7 @@ class BNote extends AbstractBeccaEntity {
}
/**
* Returns note path considered to be the "best"
* Returns a note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @return {string[]} array of noteIds constituting the particular note path
@@ -1258,7 +1269,7 @@ class BNote extends AbstractBeccaEntity {
}
/**
* Returns note path considered to be the "best"
* Returns a note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @return {string} serialized note path (e.g. 'root/a1h315/js725h')
@@ -1356,10 +1367,10 @@ class BNote extends AbstractBeccaEntity {
* @param {string} name - name of the attribute, not including the leading ~/#
* @param {string} [value] - value of the attribute - text for labels, target note ID for relations; optional.
* @param {boolean} [isInheritable=false]
* @param {int} [position]
* @param {int|null} [position]
* @returns {BAttribute}
*/
addAttribute(type, name, value = "", isInheritable = false, position = 1000) {
addAttribute(type, name, value = "", isInheritable = false, position = null) {
const BAttribute = require("./battribute");
return new BAttribute({
@@ -1398,7 +1409,7 @@ class BNote extends AbstractBeccaEntity {
}
/**
* Based on enabled, attribute is either set or removed.
* Based on enabled, the attribute is either set or removed.
*
* @param {string} type - attribute type ('relation', 'label' etc.)
* @param {boolean} enabled - toggle On or Off
@@ -1457,7 +1468,7 @@ class BNote extends AbstractBeccaEntity {
removeLabel(name, value) { return this.removeAttribute(LABEL, name, value); }
/**
* Remove relation name-value pair, if it exists.
* Remove the relation name-value pair, if it exists.
*
* @param {string} name - relation name
* @param {string} [value] - relation value (noteId)
@@ -1486,13 +1497,89 @@ class BNote extends AbstractBeccaEntity {
return cloningService.cloneNoteToBranch(this.noteId, branch.branchId);
}
isEligibleForConversionToAttachment(opts = {autoConversion: false}) {
if (this.type !== 'image' || !this.isContentAvailable() || this.hasChildren() || this.getParentBranches().length !== 1) {
return false;
}
const targetRelations = this.getTargetRelations().filter(relation => relation.name === 'imageLink');
if (opts.autoConversion &amp;&amp; targetRelations.length === 0) {
return false;
} else if (targetRelations.length > 1) {
return false;
}
const parentNote = this.getParentNotes()[0]; // at this point note can have only one parent
const referencingNote = targetRelations[0]?.getNote();
if (referencingNote &amp;&amp; parentNote !== referencingNote) {
return false;
} else if (parentNote.type !== 'text' || !parentNote.isContentAvailable()) {
return false;
}
return true;
}
/**
* Some notes are eligible for conversion into an attachment of its parent, note must have these properties:
* - it has exactly one target relation
* - it has a relation from its parent note
* - it has no children
* - it has no clones
* - the parent is of type text
* - both notes are either unprotected or user is in protected session
*
* Currently, works only for image notes.
*
* In the future, this functionality might get more generic and some of the requirements relaxed.
*
* @params {Object} [opts]
* @params {bolean} [opts.autoConversion=false} if true, the action is not triggered by user, but e.g. by migration,
* and only perfect candidates will be migrated
*
* @returns {BAttachment|null} - null if note is not eligible for conversion
*/
convertToParentAttachment(opts = {autoConversion: false}) {
if (!this.isEligibleForConversionToAttachment(opts)) {
return null;
}
const content = this.getContent();
const parentNote = this.getParentNotes()[0];
const attachment = parentNote.saveAttachment({
role: 'image',
mime: this.mime,
title: this.title,
content: content
});
let parentContent = parentNote.getContent();
const oldNoteUrl = `api/images/${this.noteId}/`;
const newAttachmentUrl = `api/attachments/${attachment.attachmentId}/image/`;
const fixedContent = utils.replaceAll(parentContent, oldNoteUrl, newAttachmentUrl);
parentNote.setContent(fixedContent);
const noteService = require("../../services/notes");
noteService.asyncPostProcessContent(parentNote, fixedContent); // to mark an unused attachment for deletion
this.deleteNote();
return attachment;
}
/**
* (Soft) delete a note and all its descendants.
*
* @param {string} [deleteId] - optional delete identified
* @param {string} [deleteId=null] - optional delete identified
* @param {TaskContext} [taskContext]
*/
deleteNote(deleteId, taskContext) {
deleteNote(deleteId = null, taskContext = null) {
if (this.isDeleted) {
return;
}
@@ -1519,7 +1606,7 @@ class BNote extends AbstractBeccaEntity {
if (this.isProtected &amp;&amp; !this.isDecrypted &amp;&amp; protectedSessionService.isProtectedSessionAvailable()) {
try {
this.title = protectedSessionService.decryptString(this.title);
this.flatTextCache = null;
this.__flatTextCache = null;
this.isDecrypted = true;
}
@@ -1538,42 +1625,90 @@ class BNote extends AbstractBeccaEntity {
}
get isDeleted() {
// isBeingDeleted is relevant only in the transition period when the deletion process has begun, but not yet
// finished (note is still in becca)
return !(this.noteId in this.becca.notes) || this.isBeingDeleted;
}
/**
* @returns {BNoteRevision|null}
* @returns {BRevision|null}
*/
saveNoteRevision() {
const content = this.getContent();
saveRevision() {
return sql.transactional(() => {
let noteContent = this.getContent();
if (!content || (Buffer.isBuffer(content) &amp;&amp; content.byteLength === 0)) {
return null;
const revision = new BRevision({
noteId: this.noteId,
// title and text should be decrypted now
title: this.title,
type: this.type,
mime: this.mime,
isProtected: this.isProtected,
utcDateLastEdited: this.utcDateModified,
utcDateCreated: dateUtils.utcNowDateTime(),
utcDateModified: dateUtils.utcNowDateTime(),
dateLastEdited: this.dateModified,
dateCreated: dateUtils.localNowDateTime()
}, true);
revision.save(); // to generate revisionId, which is then used to save attachments
for (const noteAttachment of this.getAttachments()) {
const revisionAttachment = noteAttachment.copy();
revisionAttachment.ownerId = revision.revisionId;
revisionAttachment.setContent(noteAttachment.getContent(), {forceSave: true});
if (this.type === 'text') {
// content is rewritten to point to the revision attachments
noteContent = noteContent.replaceAll(`attachments/${noteAttachment.attachmentId}`,
`attachments/${revisionAttachment.attachmentId}`);
noteContent = noteContent.replaceAll(new RegExp(`href="[^"]*attachmentId=${noteAttachment.attachmentId}[^"]*"`, 'gi'),
`href="api/attachments/${revisionAttachment.attachmentId}/download"`);
}
}
revision.setContent(noteContent);
return revision;
});
}
/**
* @param {string} matchBy - choose by which property we detect if to update an existing attachment.
* Supported values are either 'attachmentId' (default) or 'title'
* @returns {BAttachment}
*/
saveAttachment({attachmentId, role, mime, title, content, position}, matchBy = 'attachmentId') {
if (!['attachmentId', 'title'].includes(matchBy)) {
throw new Error(`Unsupported value '${matchBy}' for matchBy param, has to be either 'attachmentId' or 'title'.`);
}
const contentMetadata = this.getContentMetadata();
let attachment;
const noteRevision = new BNoteRevision({
noteId: this.noteId,
// title and text should be decrypted now
title: this.title,
type: this.type,
mime: this.mime,
if (matchBy === 'title') {
attachment = this.getAttachmentByTitle(title);
} else if (matchBy === 'attachmentId' &amp;&amp; attachmentId) {
attachment = this.becca.getAttachmentOrThrow(attachmentId);
}
attachment = attachment || new BAttachment({
ownerId: this.noteId,
title,
role,
mime,
isProtected: this.isProtected,
utcDateLastEdited: this.utcDateModified > contentMetadata.utcDateModified
? this.utcDateModified
: contentMetadata.utcDateModified,
utcDateCreated: dateUtils.utcNowDateTime(),
utcDateModified: dateUtils.utcNowDateTime(),
dateLastEdited: this.dateModified > contentMetadata.dateModified
? this.dateModified
: contentMetadata.dateModified,
dateCreated: dateUtils.localNowDateTime()
}, true).save();
position
});
noteRevision.setContent(content);
content = content || "";
attachment.setContent(content, {forceSave: true});
return noteRevision;
return attachment;
}
getFileName() {
return utils.formatDownloadTitle(this.title, this.type, this.mime);
}
beforeSaving() {
@@ -1592,6 +1727,7 @@ class BNote extends AbstractBeccaEntity {
isProtected: this.isProtected,
type: this.type,
mime: this.mime,
blobId: this.blobId,
isDeleted: false,
dateCreated: this.dateCreated,
dateModified: this.dateModified,
@@ -1628,7 +1764,7 @@ module.exports = BNote;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -32,7 +32,7 @@ const dateUtils = require('../../services/date_utils');
const AbstractBeccaEntity = require("./abstract_becca_entity");
/**
* Option represents name-value pair, either directly configurable by the user or some system property.
* Option represents a name-value pair, either directly configurable by the user or some system property.
*
* @extends AbstractBeccaEntity
*/
@@ -86,7 +86,7 @@ module.exports = BOption;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -71,7 +71,7 @@ module.exports = BRecentNote;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: becca/entities/bnote_revision.js</title>
<title>JSDoc: Source: becca/entities/brevision.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
@@ -17,7 +17,7 @@
<div id="main">
<h1 class="page-title">Source: becca/entities/bnote_revision.js</h1>
<h1 class="page-title">Source: becca/entities/brevision.js</h1>
@@ -30,28 +30,29 @@
const protectedSessionService = require('../../services/protected_session');
const utils = require('../../services/utils');
const sql = require('../../services/sql');
const dateUtils = require('../../services/date_utils');
const becca = require('../becca');
const entityChangesService = require('../../services/entity_changes');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const sql = require("../../services/sql");
const BAttachment = require("./battachment");
/**
* NoteRevision represents snapshot of note's title and content at some point in the past.
* Revision represents a snapshot of note's title and content at some point in the past.
* It's used for seamless note versioning.
*
* @extends AbstractBeccaEntity
*/
class BNoteRevision extends AbstractBeccaEntity {
static get entityName() { return "note_revisions"; }
static get primaryKeyName() { return "noteRevisionId"; }
static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; }
class BRevision extends AbstractBeccaEntity {
static get entityName() { return "revisions"; }
static get primaryKeyName() { return "revisionId"; }
static get hashedProperties() { return ["revisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated",
"utcDateLastEdited", "utcDateCreated", "utcDateModified", "blobId"]; }
constructor(row, titleDecrypted = false) {
super();
/** @type {string} */
this.noteRevisionId = row.noteRevisionId;
this.revisionId = row.revisionId;
/** @type {string} */
this.noteId = row.noteId;
/** @type {string} */
@@ -63,6 +64,8 @@ class BNoteRevision extends AbstractBeccaEntity {
/** @type {string} */
this.title = row.title;
/** @type {string} */
this.blobId = row.blobId;
/** @type {string} */
this.dateLastEdited = row.dateLastEdited;
/** @type {string} */
this.dateCreated = row.dateCreated;
@@ -72,7 +75,7 @@ class BNoteRevision extends AbstractBeccaEntity {
this.utcDateCreated = row.utcDateCreated;
/** @type {string} */
this.utcDateModified = row.utcDateModified;
/** @type {number} */
/** @type {int} */
this.contentLength = row.contentLength;
if (this.isProtected &amp;&amp; !titleDecrypted) {
@@ -87,92 +90,103 @@ class BNoteRevision extends AbstractBeccaEntity {
}
/** @returns {boolean} true if the note has string content (not binary) */
isStringNote() {
hasStringContent() {
return utils.isStringNote(this.type, this.mime);
}
isContentAvailable() {
return !this.revisionId // new note which was not encrypted yet
|| !this.isProtected
|| protectedSessionService.isProtectedSessionAvailable()
}
/*
* Note revision content has quite special handling - it's not a separate entity, but a lazily loaded
* part of NoteRevision entity with its own sync. Reason behind this hybrid design is that
* part of Revision entity with its own sync. The reason behind this hybrid design is that
* content can be quite large, and it's not necessary to load it / fill memory for any note access even
* if we don't need a content, especially for bulk operations like search.
*
* This is the same approach as is used for Note's content.
*/
/** @returns {*} */
getContent(silentNotFoundError = false) {
const res = sql.getRow(`SELECT content FROM note_revision_contents WHERE noteRevisionId = ?`, [this.noteRevisionId]);
/** @returns {string|Buffer} */
getContent() {
return this._getContent();
}
if (!res) {
if (silentNotFoundError) {
return undefined;
}
else {
throw new Error(`Cannot find note revision content for noteRevisionId=${this.noteRevisionId}`);
}
/**
* @returns {*}
* @throws Error in case of invalid JSON */
getJsonContent() {
const content = this.getContent();
if (!content || !content.trim()) {
return null;
}
let content = res.content;
return JSON.parse(content);
}
if (this.isProtected) {
if (protectedSessionService.isProtectedSessionAvailable()) {
content = protectedSessionService.decrypt(content);
}
else {
content = "";
}
/** @returns {*|null} valid object or null if the content cannot be parsed as JSON */
getJsonContentSafely() {
try {
return this.getJsonContent();
}
if (this.isStringNote()) {
return content === null
? ""
: content.toString("UTF-8");
}
else {
return content;
catch (e) {
return null;
}
}
setContent(content) {
const pojo = {
noteRevisionId: this.noteRevisionId,
content: content,
utcDateModified: dateUtils.utcNowDateTime()
};
if (this.isProtected) {
if (protectedSessionService.isProtectedSessionAvailable()) {
pojo.content = protectedSessionService.encrypt(pojo.content);
}
else {
throw new Error(`Cannot update content of noteRevisionId=${this.noteRevisionId} since we're out of protected session.`);
}
}
sql.upsert("note_revision_contents", "noteRevisionId", pojo);
const hash = utils.hash(`${this.noteRevisionId}|${pojo.content.toString()}`);
entityChangesService.addEntityChange({
entityName: 'note_revision_contents',
entityId: this.noteRevisionId,
hash: hash,
isErased: false,
utcDateChanged: this.getUtcDateChanged(),
isSynced: true
});
/**
* @param content
* @param {object} [opts]
* @param {object} [opts.forceSave=false] - will also save this BRevision entity
*/
setContent(content, opts) {
this._setContent(content, opts);
}
/** @returns {{contentLength, dateModified, utcDateModified}} */
getContentMetadata() {
return sql.getRow(`
SELECT
LENGTH(content) AS contentLength,
dateModified,
utcDateModified
FROM note_revision_contents
WHERE noteRevisionId = ?`, [this.noteRevisionId]);
/** @returns {BAttachment[]} */
getAttachments() {
return sql.getRows(`
SELECT attachments.*
FROM attachments
WHERE ownerId = ?
AND isDeleted = 0`, [this.revisionId])
.map(row => new BAttachment(row));
}
/** @returns {BAttachment|null} */
getAttachmentById(attachmentId, opts = {}) {
opts.includeContentLength = !!opts.includeContentLength;
const query = opts.includeContentLength
? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength
FROM attachments
JOIN blobs USING (blobId)
WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`
: `SELECT * FROM attachments WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`;
return sql.getRows(query, [this.revisionId, attachmentId])
.map(row => new BAttachment(row))[0];
}
/** @returns {BAttachment[]} */
getAttachmentsByRole(role) {
return sql.getRows(`
SELECT attachments.*
FROM attachments
WHERE ownerId = ?
AND role = ?
AND isDeleted = 0
ORDER BY position`, [this.revisionId, role])
.map(row => new BAttachment(row));
}
/** @returns {BAttachment} */
getAttachmentByTitle(title) {
// cannot use SQL to filter by title since it can be encrypted
return this.getAttachments().filter(attachment => attachment.title === title)[0];
}
beforeSaving() {
@@ -183,12 +197,13 @@ class BNoteRevision extends AbstractBeccaEntity {
getPojo() {
return {
noteRevisionId: this.noteRevisionId,
revisionId: this.revisionId,
noteId: this.noteId,
type: this.type,
mime: this.mime,
isProtected: this.isProtected,
title: this.title,
blobId: this.blobId,
dateLastEdited: this.dateLastEdited,
dateCreated: this.dateCreated,
utcDateLastEdited: this.utcDateLastEdited,
@@ -218,7 +233,7 @@ class BNoteRevision extends AbstractBeccaEntity {
}
}
module.exports = BNoteRevision;
module.exports = BRevision;
</code></pre>
</article>
</section>
@@ -229,7 +244,7 @@ module.exports = BNoteRevision;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -0,0 +1,657 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Global</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Global</h1>
<section>
<header>
<h2></h2>
</header>
<article>
<div class="container-overview">
<dl class="details">
</dl>
</div>
<h3 class="subsection-title">Members</h3>
<h4 class="name" id="api"><span class="type-signature"></span>api<span class="type-signature"> :<a href="BackendScriptApi.html">BackendScriptApi</a></span></h4>
<div class="description">
An instance of the frontend api available globally.
</div>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type"><a href="BackendScriptApi.html">BackendScriptApi</a></span>
</li>
</ul>
<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#line32">line 32</a>
</li></ul></dd>
</dl>
<h3 class="subsection-title">Type Definitions</h3>
<h4 class="name" id="AttributeType">AttributeType</h4>
<div class="description">
There are currently only two types of attributes, labels or relations.
</div>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type">"label"</span>
|
<span class="param-type">"relation"</span>
</li>
</ul>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line11">line 11</a>
</li></ul></dd>
</dl>
<h4 class="name" id="NotePathRecord">NotePathRecord</h4>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type">Object</span>
</li>
</ul>
<h5 class="subsection-title">Properties:</h5>
<table class="props">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>isArchived</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="description last"></td>
</tr>
<tr>
<td class="name"><code>isInHoistedSubTree</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="description last"></td>
</tr>
<tr>
<td class="name"><code>notePath</code></td>
<td class="type">
<span class="param-type">Array.&lt;string></span>
</td>
<td class="description last"></td>
</tr>
<tr>
<td class="name"><code>isHidden</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
<dl class="details">
<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#line27">line 27</a>
</li></ul></dd>
</dl>
<h4 class="name" id="NoteType">NoteType</h4>
<div class="description">
There are many different Note types, some of which are entirely opaque to the
end user. Those types should be used only for checking against, they are
not for direct use.
</div>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type">"file"</span>
|
<span class="param-type">"image"</span>
|
<span class="param-type">"search"</span>
|
<span class="param-type">"noteMap"</span>
|
<span class="param-type">"launcher"</span>
|
<span class="param-type">"doc"</span>
|
<span class="param-type">"contentWidget"</span>
|
<span class="param-type">"text"</span>
|
<span class="param-type">"relationMap"</span>
|
<span class="param-type">"render"</span>
|
<span class="param-type">"canvas"</span>
|
<span class="param-type">"mermaid"</span>
|
<span class="param-type">"book"</span>
|
<span class="param-type">"webView"</span>
|
<span class="param-type">"code"</span>
</li>
</ul>
<dl class="details">
<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#line20">line 20</a>
</li></ul></dd>
</dl>
<h4 class="name" id="int">int</h4>
<div class="description">
A whole number
</div>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type">number</span>
</li>
</ul>
<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#line27">line 27</a>
</li></ul></dd>
</dl>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@@ -50,7 +50,7 @@
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -250,7 +250,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line364">line 364</a>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line377">line 377</a>
</li></ul></dd>
@@ -430,7 +430,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line355">line 355</a>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line368">line 368</a>
</li></ul></dd>
@@ -632,7 +632,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line345">line 345</a>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line358">line 358</a>
</li></ul></dd>
@@ -834,7 +834,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line321">line 321</a>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line334">line 334</a>
</li></ul></dd>
@@ -1036,7 +1036,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line332">line 332</a>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line345">line 345</a>
</li></ul></dd>
@@ -1238,7 +1238,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line311">line 311</a>
<a href="services_sql.js.html">services/sql.js</a>, <a href="services_sql.js.html#line324">line 324</a>
</li></ul></dd>
@@ -1294,7 +1294,7 @@
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -47,6 +47,21 @@ const SpacedUpdate = require("./spaced_update");
const specialNotesService = require("./special_notes");
const branchService = require("./branches");
const exportService = require("./export/zip");
const syncMutex = require("./sync_mutex");
const backupService = require("./backup");
const optionsService = require("./options");
/**
* A whole number
* @typedef {number} int
*/
/**
* An instance of the frontend api available globally.
* @global
* @var {BackendScriptApi} api
*/
/**
* &lt;p>This is the main backend API interface for scripts. All the properties and methods are published in the "api" object
@@ -55,11 +70,20 @@ const exportService = require("./export/zip");
* @constructor
*/
function BackendScriptApi(currentNote, apiParams) {
/** @property {BNote} note where script started executing */
/**
* Note where the script started executing
* @type {BNote}
*/
this.startNote = apiParams.startNote;
/** @property {BNote} note where script is currently executing. Don't mix this up with concept of active note */
/**
* Note where the script is currently executing. Don't mix this up with the concept of active note
* @type {BNote}
*/
this.currentNote = currentNote;
/** @property {AbstractBeccaEntity} entity whose event triggered this executions */
/**
* Entity whose event triggered this execution
* @type {AbstractBeccaEntity}
*/
this.originEntity = apiParams.originEntity;
for (const key in apiParams) {
@@ -67,13 +91,20 @@ function BackendScriptApi(currentNote, apiParams) {
}
/**
* @property {axios} Axios library for HTTP requests. See {@link https://axios-http.com} for documentation
* Axios library for HTTP requests. See {@link https://axios-http.com} for documentation
* @type {axios}
* @deprecated use native (browser compatible) fetch() instead
*/
this.axios = axios;
/** @property {dayjs} day.js library for date manipulation. See {@link https://day.js.org} for documentation */
/**
* day.js library for date manipulation. See {@link https://day.js.org} for documentation
* @type {dayjs}
*/
this.dayjs = dayjs;
/** @property {axios} xml2js library for XML parsing. See {@link https://github.com/Leonidas-from-XIV/node-xml2js} for documentation */
/**
* xml2js library for XML parsing. See {@link https://github.com/Leonidas-from-XIV/node-xml2js} for documentation
* @type {xml2js}
*/
this.xml2js = xml2js;
/**
@@ -105,6 +136,53 @@ function BackendScriptApi(currentNote, apiParams) {
*/
this.getAttribute = attributeId => becca.getAttribute(attributeId);
/**
* @method
* @param {string} attachmentId
* @returns {BAttachment|null}
*/
this.getAttachment = attachmentId => becca.getAttachment(attachmentId);
/**
* @method
* @param {string} revisionId
* @returns {BRevision|null}
*/
this.getRevision = revisionId => becca.getRevision(revisionId);
/**
* @method
* @param {string} etapiTokenId
* @returns {BEtapiToken|null}
*/
this.getEtapiToken = etapiTokenId => becca.getEtapiToken(etapiTokenId);
/**
* @method
* @returns {BEtapiToken[]}
*/
this.getEtapiTokens = () => becca.getEtapiTokens();
/**
* @method
* @param {string} optionName
* @returns {BOption|null}
*/
this.getOption = optionName => becca.getOption(optionName);
/**
* @method
* @returns {BOption[]}
*/
this.getOptions = () => optionsService.getOptions();
/**
* @method
* @param {string} attributeId
* @returns {BAttribute|null}
*/
this.getAttribute = attributeId => becca.getAttribute(attributeId);
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
* "#dateModified =* MONTH AND #log". See {@link https://github.com/zadam/trilium/wiki/Search} for full documentation for all options
@@ -170,7 +248,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @param {string} noteId
* @param {string} parentNoteId
* @param {string} prefix - if branch will be created between note and parent note, set this prefix
* @param {string} prefix - if branch is created between note and parent note, set this prefix
* @returns {{branch: BBranch|null}}
*/
this.ensureNoteIsPresentInParent = cloningService.ensureNoteIsPresentInParent;
@@ -192,7 +270,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {boolean} present - true if we want the branch to exist, false if we want it gone
* @param {string} noteId
* @param {string} parentNoteId
* @param {string} prefix - if branch will be created between note and parent note, set this prefix
* @param {string} prefix - if branch is created between note and parent note, set this prefix
* @returns {void}
*/
this.toggleNoteInParent = cloningService.toggleNoteInParent;
@@ -234,16 +312,16 @@ function BackendScriptApi(currentNote, apiParams) {
/**
* @method
*
* @property {object} params
* @property {string} params.parentNoteId
* @property {string} params.title
* @property {string|buffer} params.content
* @property {string} params.type - text, code, file, image, search, book, relationMap, canvas
* @property {string} [params.mime] - value is derived from default mimes for type
* @property {boolean} [params.isProtected=false]
* @property {boolean} [params.isExpanded=false]
* @property {string} [params.prefix='']
* @property {int} [params.notePosition] - default is last existing notePosition in a parent + 10
* @param {object} params
* @param {string} params.parentNoteId
* @param {string} params.title
* @param {string|Buffer} params.content
* @param {NoteType} params.type - text, code, file, image, search, book, relationMap, canvas
* @param {string} [params.mime] - value is derived from default mimes for type
* @param {boolean} [params.isProtected=false]
* @param {boolean} [params.isExpanded=false]
* @param {string} [params.prefix='']
* @param {int} [params.notePosition] - default is last existing notePosition in a parent + 10
* @returns {{note: BNote, branch: BBranch}} object contains newly created entities note and branch
*/
this.createNewNote = noteService.createNewNote;
@@ -256,14 +334,14 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {string} title
* @param {string} [content=""]
* @param {object} [extraOptions={}]
* @property {boolean} [extraOptions.json=false] - should the note be JSON
* @property {boolean} [extraOptions.isProtected=false] - should the note be protected
* @property {string} [extraOptions.type='text'] - note type
* @property {string} [extraOptions.mime='text/html'] - MIME type of the note
* @property {object[]} [extraOptions.attributes=[]] - attributes to be created for this note
* @property {string} extraOptions.attributes.type - attribute type - label, relation etc.
* @property {string} extraOptions.attributes.name - attribute name
* @property {string} [extraOptions.attributes.value] - attribute value
* @param {boolean} [extraOptions.json=false] - should the note be JSON
* @param {boolean} [extraOptions.isProtected=false] - should the note be protected
* @param {string} [extraOptions.type='text'] - note type
* @param {string} [extraOptions.mime='text/html'] - MIME type of the note
* @param {object[]} [extraOptions.attributes=[]] - attributes to be created for this note
* @param {AttributeType} extraOptions.attributes.type - attribute type - label, relation etc.
* @param {string} extraOptions.attributes.name - attribute name
* @param {string} [extraOptions.attributes.value] - attribute value
* @returns {{note: BNote, branch: BBranch}} object contains newly created entities note and branch
*/
this.createNote = (parentNoteId, title, content = "", extraOptions= {}) => {
@@ -272,7 +350,7 @@ function BackendScriptApi(currentNote, apiParams) {
const parentNote = becca.getNote(parentNoteId);
// code note type can be inherited, otherwise text is default
// code note type can be inherited, otherwise "text" is the default
extraOptions.type = parentNote.type === 'code' ? 'code' : 'text';
extraOptions.mime = parentNote.type === 'code' ? parentNote.mime : 'text/html';
@@ -373,7 +451,7 @@ function BackendScriptApi(currentNote, apiParams) {
this.getWeekNote = dateNoteService.getWeekNote;
/**
* Returns month note for given date. If such note doesn't exist, it is created.
* Returns month note for given date. If such a note doesn't exist, it is created.
*
* @method
* @param {string} date in YYYY-MM format
@@ -383,7 +461,7 @@ function BackendScriptApi(currentNote, apiParams) {
this.getMonthNote = dateNoteService.getMonthNote;
/**
* Returns year note for given year. If such note doesn't exist, it is created.
* Returns year note for given year. If such a note doesn't exist, it is created.
*
* @method
* @param {string} year in YYYY format
@@ -398,10 +476,10 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @param {string} parentNoteId - this note's child notes will be sorted
* @param {object} [sortConfig]
* @property {string} [sortConfig.sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name
* @param {string} [sortConfig.sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name
* See {@link https://github.com/zadam/trilium/wiki/Sorting} for details.
* @property {boolean} [sortConfig.reverse=false]
* @property {boolean} [sortConfig.foldersFirst=false]
* @param {boolean} [sortConfig.reverse=false]
* @param {boolean} [sortConfig.foldersFirst=false]
* @returns {void}
*/
this.sortNotes = (parentNoteId, sortConfig = {}) => treeService.sortNotes(
@@ -432,7 +510,7 @@ function BackendScriptApi(currentNote, apiParams) {
*
* @method
* @param {function} func
* @returns {?} result of func callback
* @returns {any} result of func callback
*/
this.transactional = sql.transactional;
@@ -440,7 +518,7 @@ function BackendScriptApi(currentNote, apiParams) {
* Return randomly generated string of given length. This random string generation is NOT cryptographically secure.
*
* @method
* @param {number} length of the string
* @param {int} length of the string
* @returns {string} random string
*/
this.randomString = utils.randomString;
@@ -460,7 +538,8 @@ function BackendScriptApi(currentNote, apiParams) {
this.unescapeHtml = utils.unescapeHtml;
/**
* @property {module:sql} sql
* sql
* @type {module:sql}
*/
this.sql = sql;
@@ -468,25 +547,25 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @returns {{syncVersion, appVersion, buildRevision, dbVersion, dataDirectory, buildDate}|*} - object representing basic info about running Trilium version
*/
this.getAppInfo = () => appInfo
this.getAppInfo = () => appInfo;
/**
* Creates a new launcher to the launchbar. If the launcher (id) already exists, it will be updated.
*
* @method
* @param {object} opts
* @property {string} opts.id - id of the launcher, only alphanumeric at least 6 characters long
* @property {string} opts.type - one of
* @param {string} opts.id - id of the launcher, only alphanumeric at least 6 characters long
* @param {"note" | "script" | "customWidget"} opts.type - one of
* * "note" - activating the launcher will navigate to the target note (specified in targetNoteId param)
* * "script" - activating the launcher will execute the script (specified in scriptNoteId param)
* * "customWidget" - the launcher will be rendered with a custom widget (specified in widgetNoteId param)
* @property {string} opts.title
* @property {boolean} [opts.isVisible=false] - if true, will be created in the "Visible launchers", otherwise in "Available launchers"
* @property {string} [opts.icon] - name of the boxicon to be used (e.g. "bx-time")
* @property {string} [opts.keyboardShortcut] - will activate the target note/script upon pressing, e.g. "ctrl+e"
* @property {string} [opts.targetNoteId] - for type "note"
* @property {string} [opts.scriptNoteId] - for type "script"
* @property {string} [opts.widgetNoteId] - for type "customWidget"
* @param {string} opts.title
* @param {boolean} [opts.isVisible=false] - if true, will be created in the "Visible launchers", otherwise in "Available launchers"
* @param {string} [opts.icon] - name of the boxicon to be used (e.g. "bx-time")
* @param {string} [opts.keyboardShortcut] - will activate the target note/script upon pressing, e.g. "ctrl+e"
* @param {string} [opts.targetNoteId] - for type "note"
* @param {string} [opts.scriptNoteId] - for type "script"
* @param {string} [opts.widgetNoteId] - for type "customWidget"
* @returns {{note: BNote}}
*/
this.createOrUpdateLauncher = opts => {
@@ -557,6 +636,69 @@ function BackendScriptApi(currentNote, apiParams) {
*/
this.exportSubtreeToZipFile = async (noteId, format, zipFilePath) => await exportService.exportToZipFile(noteId, format, zipFilePath);
/**
* Executes given anonymous function on the frontend(s).
* Internally, this serializes the anonymous function into string and sends it to frontend(s) via WebSocket.
* Note that there can be multiple connected frontend instances (e.g. in different tabs). In such case, all
* instances execute the given function.
*
* @method
* @param {string} script - script to be executed on the frontend
* @param {Array.&lt;?>} params - list of parameters to the anonymous function to be sent to frontend
* @returns {undefined} - no return value is provided.
*/
this.runOnFrontend = async (script, params = []) => {
if (typeof script === "function") {
script = script.toString();
}
ws.sendMessageToAllClients({
type: 'execute-script',
script: script,
params: prepareParams(params),
startNoteId: this.startNote.noteId,
currentNoteId: this.currentNote.noteId,
originEntityName: "notes", // currently there's no other entity on the frontend which can trigger event
originEntityId: this.originEntity?.noteId || null
});
function prepareParams(params) {
if (!params) {
return params;
}
return params.map(p => {
if (typeof p === "function") {
return `!@#Function: ${p.toString()}`;
}
else {
return p;
}
});
}
};
/**
* Sync process can make data intermittently inconsistent. Scripts which require strong data consistency
* can use this function to wait for a possible sync process to finish and prevent new sync process from starting
* while it is running.
*
* Because this is an async process, the inner callback doesn't have automatic transaction handling, so in case
* you need to make some DB changes, you need to surround your call with api.transactional(...)
*
* @method
* @param {function} callback - function to be executed while sync process is not running
* @returns {Promise} - resolves once the callback is finished (callback is awaited)
*/
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.
*
@@ -578,7 +720,7 @@ module.exports = BackendScriptApi;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -54,7 +54,7 @@ const LOG_ALL_QUERIES = false;
});
function insert(tableName, rec, replace = false) {
const keys = Object.keys(rec);
const keys = Object.keys(rec || {});
if (keys.length === 0) {
log.error(`Can't insert empty object into table ${tableName}`);
return;
@@ -81,7 +81,7 @@ function replace(tableName, rec) {
}
function upsert(tableName, primaryKey, rec) {
const keys = Object.keys(rec);
const keys = Object.keys(rec || {});
if (keys.length === 0) {
log.error(`Can't upsert empty object into table ${tableName}`);
return;
@@ -253,7 +253,7 @@ function wrap(query, func) {
const milliseconds = Date.now() - startTimestamp;
if (milliseconds >= 20) {
if (milliseconds >= 20 &amp;&amp; !cls.isSlowQueryLoggingDisabled()) {
if (query.includes("WITH RECURSIVE")) {
log.info(`Slow recursive query took ${milliseconds}ms.`);
}
@@ -323,6 +323,19 @@ async function copyDatabase(targetFilePath) {
await dbConnection.backup(targetFilePath);
}
function disableSlowQueryLogging(cb) {
const orig = cls.isSlowQueryLoggingDisabled();
try {
cls.disableSlowQueryLogging(true);
return cb();
}
finally {
cls.disableSlowQueryLogging(orig);
}
}
module.exports = {
dbConnection,
insert,
@@ -395,7 +408,8 @@ module.exports = {
transactional,
upsert,
fillParamList,
copyDatabase
copyDatabase,
disableSlowQueryLogging
};
</code></pre>
</article>
@@ -407,7 +421,7 @@ module.exports = {
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BNoteRevision.html">BNoteRevision</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul>
</nav>
<br class="clear">

View File

@@ -0,0 +1,426 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Class: BasicWidget</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Class: BasicWidget</h1>
<section>
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>BasicWidget<span class="signature">()</span><span class="type-signature"></span></h2>
<div class="class-description">This is the base widget for all other widgets.
For information on using widgets, see the tutorial widget_basics.</div>
</header>
<article>
<div class="container-overview">
<h2>Constructor</h2>
<h4 class="name" id="BasicWidget"><span class="type-signature"></span>new BasicWidget<span class="signature">()</span><span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="widgets_basic_widget.js.html">widgets/basic_widget.js</a>, <a href="widgets_basic_widget.js.html#line9">line 9</a>
</li></ul></dd>
</dl>
</div>
<h3 class="subsection-title">Methods</h3>
<h4 class="name" id="cssBlock"><span class="type-signature"></span>cssBlock<span class="signature">(block)</span><span class="type-signature"> &rarr; {this}</span></h4>
<div class="description">
Accepts a string of CSS to add with the widget.
</div>
<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>block</code></td>
<td class="type">
<span class="param-type">string</span>
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="widgets_basic_widget.js.html">widgets/basic_widget.js</a>, <a href="widgets_basic_widget.js.html#line78">line 78</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
for chaining
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">this</span>
</dd>
</dl>
<h4 class="name" id="doRender"><span class="type-signature"></span>doRender<span class="signature">()</span><span class="type-signature"></span></h4>
<div class="description">
Method used for rendering the widget.
Your class should override this method.
The method is expected to create a this.$widget containing jQuery object
</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="widgets_basic_widget.js.html">widgets/basic_widget.js</a>, <a href="widgets_basic_widget.js.html#line132">line 132</a>
</li></ul></dd>
</dl>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="BasicWidget.html">BasicWidget</a></li><li><a href="FAttachment.html">FAttachment</a></li><li><a href="FAttribute.html">FAttribute</a></li><li><a href="FBranch.html">FBranch</a></li><li><a href="FNote.html">FNote</a></li><li><a href="FrontendScriptApi.html">FrontendScriptApi</a></li><li><a href="NoteContextAwareWidget.html">NoteContextAwareWidget</a></li><li><a href="RightPanelWidget.html">RightPanelWidget</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li><li><a href="global.html#getJsonContent">getJsonContent</a></li><li><a href="global.html#getJsonContentSafely">getJsonContentSafely</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -94,7 +94,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line7">line 7</a>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line12">line 12</a>
</li></ul></dd>
@@ -194,7 +194,75 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line16">line 16</a>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line22">line 22</a>
</li></ul></dd>
</dl>
<h4 class="name" id="froca"><span class="type-signature"></span>froca<span class="type-signature"> :Froca</span></h4>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type">Froca</span>
</li>
</ul>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line15">line 15</a>
</li></ul></dd>
@@ -262,7 +330,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line28">line 28</a>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line34">line 34</a>
</li></ul></dd>
@@ -330,7 +398,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line22">line 22</a>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line28">line 28</a>
</li></ul></dd>
@@ -398,7 +466,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line18">line 18</a>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line24">line 24</a>
</li></ul></dd>
@@ -416,7 +484,7 @@ and relation (representing named relationship between source and target note)</d
<h4 class="name" id="position"><span class="type-signature"></span>position<span class="type-signature"> :int</span></h4>
<h4 class="name" id="position"><span class="type-signature"></span>position<span class="type-signature"> :<a href="global.html#int">int</a></span></h4>
@@ -427,7 +495,75 @@ and relation (representing named relationship between source and target note)</d
<ul>
<li>
<span class="param-type">int</span>
<span class="param-type"><a href="global.html#int">int</a></span>
</li>
</ul>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line32">line 32</a>
</li></ul></dd>
</dl>
<h4 class="name" id="type"><span class="type-signature"></span>type<span class="type-signature"> :<a href="global.html#AttributeType">AttributeType</a></span></h4>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type"><a href="global.html#AttributeType">AttributeType</a></span>
</li>
@@ -484,74 +620,6 @@ and relation (representing named relationship between source and target note)</d
<h4 class="name" id="type"><span class="type-signature"></span>type<span class="type-signature"> :string</span></h4>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type">string</span>
</li>
</ul>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line20">line 20</a>
</li></ul></dd>
</dl>
<h4 class="name" id="value"><span class="type-signature"></span>value<span class="type-signature"> :string</span></h4>
@@ -602,7 +670,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line24">line 24</a>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line30">line 30</a>
</li></ul></dd>
@@ -678,7 +746,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line32">line 32</a>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line38">line 38</a>
</li></ul></dd>
@@ -780,7 +848,7 @@ and relation (representing named relationship between source and target note)</d
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line37">line 37</a>
<a href="entities_fattribute.js.html">entities/fattribute.js</a>, <a href="entities_fattribute.js.html#line43">line 43</a>
</li></ul></dd>
@@ -844,7 +912,7 @@ and relation (representing named relationship between source and target note)</d
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="FAttribute.html">FAttribute</a></li><li><a href="FBranch.html">FBranch</a></li><li><a href="FNote.html">FNote</a></li><li><a href="FNoteComplement.html">FNoteComplement</a></li><li><a href="FrontendScriptApi.html">FrontendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="BasicWidget.html">BasicWidget</a></li><li><a href="FAttachment.html">FAttachment</a></li><li><a href="FAttribute.html">FAttribute</a></li><li><a href="FBranch.html">FBranch</a></li><li><a href="FNote.html">FNote</a></li><li><a href="FrontendScriptApi.html">FrontendScriptApi</a></li><li><a href="NoteContextAwareWidget.html">NoteContextAwareWidget</a></li><li><a href="RightPanelWidget.html">RightPanelWidget</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li><li><a href="global.html#getJsonContent">getJsonContent</a></li><li><a href="global.html#getJsonContentSafely">getJsonContentSafely</a></li></ul>
</nav>
<br class="clear">

View File

@@ -198,7 +198,75 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line17">line 17</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line18">line 18</a>
</li></ul></dd>
</dl>
<h4 class="name" id="froca"><span class="type-signature"></span>froca<span class="type-signature"> :Froca</span></h4>
<h5>Type:</h5>
<ul>
<li>
<span class="param-type">Froca</span>
</li>
</ul>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line8">line 8</a>
</li></ul></dd>
@@ -266,7 +334,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line29">line 29</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line30">line 30</a>
</li></ul></dd>
@@ -334,7 +402,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line27">line 27</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line28">line 28</a>
</li></ul></dd>
@@ -402,7 +470,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line19">line 19</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line20">line 20</a>
</li></ul></dd>
@@ -420,7 +488,7 @@ parents.</div>
<h4 class="name" id="notePosition"><span class="type-signature"></span>notePosition<span class="type-signature"> :int</span></h4>
<h4 class="name" id="notePosition"><span class="type-signature"></span>notePosition<span class="type-signature"> :<a href="global.html#int">int</a></span></h4>
@@ -431,7 +499,7 @@ parents.</div>
<ul>
<li>
<span class="param-type">int</span>
<span class="param-type"><a href="global.html#int">int</a></span>
</li>
@@ -470,7 +538,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line23">line 23</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line24">line 24</a>
</li></ul></dd>
@@ -538,7 +606,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line21">line 21</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line22">line 22</a>
</li></ul></dd>
@@ -606,7 +674,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line25">line 25</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line26">line 26</a>
</li></ul></dd>
@@ -682,7 +750,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line33">line 33</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line34">line 34</a>
</li></ul></dd>
@@ -784,7 +852,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line38">line 38</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line39">line 39</a>
</li></ul></dd>
@@ -886,7 +954,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line43">line 43</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line44">line 44</a>
</li></ul></dd>
@@ -988,7 +1056,7 @@ parents.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line48">line 48</a>
<a href="entities_fbranch.js.html">entities/fbranch.js</a>, <a href="entities_fbranch.js.html#line49">line 49</a>
</li></ul></dd>
@@ -1017,7 +1085,7 @@ parents.</div>
<div class="param-desc">
true if it's top level, meaning its parent is root note
true if it's top level, meaning its parent is the root note
</div>
@@ -1056,7 +1124,7 @@ parents.</div>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="FAttribute.html">FAttribute</a></li><li><a href="FBranch.html">FBranch</a></li><li><a href="FNote.html">FNote</a></li><li><a href="FNoteComplement.html">FNoteComplement</a></li><li><a href="FrontendScriptApi.html">FrontendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="BasicWidget.html">BasicWidget</a></li><li><a href="FAttachment.html">FAttachment</a></li><li><a href="FAttribute.html">FAttribute</a></li><li><a href="FBranch.html">FBranch</a></li><li><a href="FNote.html">FNote</a></li><li><a href="FrontendScriptApi.html">FrontendScriptApi</a></li><li><a href="NoteContextAwareWidget.html">NoteContextAwareWidget</a></li><li><a href="RightPanelWidget.html">RightPanelWidget</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li><li><a href="global.html#getJsonContent">getJsonContent</a></li><li><a href="global.html#getJsonContentSafely">getJsonContentSafely</a></li></ul>
</nav>
<br class="clear">

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More