From 786f3e8d406f6e2d026eebd04117f9855d8a5fbb Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Thu, 13 Feb 2025 22:51:51 +0100
Subject: [PATCH 01/36] chore(scripts): namespace server:start
---
.gitpod.yml | 2 +-
README-ZH_CN.md | 2 +-
README.es.md | 2 +-
README.it.md | 2 +-
README.ja.md | 2 +-
README.md | 2 +-
README.ru.md | 2 +-
docs/X4N03xLYEWnN.html | 4 ++--
docs/XxqZW6JjkW2g.html | 2 +-
docs/backend_api/index.html | 2 +-
docs/backend_api/media/README-ZH_CN.md | 2 +-
docs/backend_api/media/README.es.md | 2 +-
docs/backend_api/media/README.it.md | 2 +-
docs/backend_api/media/README.ja.md | 2 +-
docs/backend_api/media/README.md | 2 +-
docs/backend_api/media/README.ru.md | 2 +-
docs/btM6L9JtG301.html | 2 +-
package.json | 4 ++--
18 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/.gitpod.yml b/.gitpod.yml
index 2b77be7b7..f87a115d0 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -4,7 +4,7 @@ image:
tasks:
- before: nvm install 20.15.1 && nvm use 20.15.1
init: npm install
- command: npm run start-server
+ command: npm run server:start
ports:
- port: 8080
diff --git a/README-ZH_CN.md b/README-ZH_CN.md
index f6aa860b1..1f6bbaf55 100644
--- a/README-ZH_CN.md
+++ b/README-ZH_CN.md
@@ -78,7 +78,7 @@ Trilium 也提供 Flatpak:
```shell
npm install
-npm run start-server
+npm run server:start
```
## 👏 致谢
diff --git a/README.es.md b/README.es.md
index a2ea94144..bfa57fe45 100644
--- a/README.es.md
+++ b/README.es.md
@@ -86,7 +86,7 @@ Clone localmente y ejecute
```shell
npm install
-npm run start-server
+npm run server:start
```
## 👏 Reconocimientos
diff --git a/README.it.md b/README.it.md
index a778230c7..750027c1a 100644
--- a/README.it.md
+++ b/README.it.md
@@ -73,7 +73,7 @@ Clona localmente ed esegui
```shell
npm install
-npm run start-server
+npm run server:start
```
## 👏 Riconoscimenti
diff --git a/README.ja.md b/README.ja.md
index 110b779c5..757638770 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -54,7 +54,7 @@ Trilium は Flatpak としても提供されます:
```shell
npm install
-npm run start-server
+npm run server:start
```
## 📢 シャウトアウト
diff --git a/README.md b/README.md
index e2a81aa4c..0170c8135 100644
--- a/README.md
+++ b/README.md
@@ -102,7 +102,7 @@ You can also read [Patterns of personal knowledge base](https://triliumnext.gith
git clone https://github.com/TriliumNext/Notes.git
cd Notes
npm install
-npm run start-server
+npm run server:start
```
### Documentation
diff --git a/README.ru.md b/README.ru.md
index d78738915..e2336efb3 100644
--- a/README.ru.md
+++ b/README.ru.md
@@ -44,7 +44,7 @@ Trilium предоставляется в виде десктопного при
```shell
npm install
-npm run start-server
+npm run server:start
```
## 👏 Благодарности
diff --git a/docs/X4N03xLYEWnN.html b/docs/X4N03xLYEWnN.html
index 2b686480d..9e9bcfef6 100644
--- a/docs/X4N03xLYEWnN.html
+++ b/docs/X4N03xLYEWnN.html
@@ -38,12 +38,12 @@
-
The native node bindings better-sqlite3
has native Node bindings. With updates of better-sqlite3
, but also of Electron and Node.js versions, these bindings need to be updated.
Note that Electron and Node.js versions need different versions of these bindings, since Electron usually packs a different version of Node.js.
During development, npm install
tries to build or reuse prebuilt natives for the current Node.js version. This makes npm run start-server
work out of the box. Trying to run npm run start-electron
with these versions generally causes an error such as this:
Uncaught Exception:
+ The native node bindings better-sqlite3
has native Node bindings. With updates of better-sqlite3
, but also of Electron and Node.js versions, these bindings need to be updated.
Note that Electron and Node.js versions need different versions of these bindings, since Electron usually packs a different version of Node.js.
During development, npm install
tries to build or reuse prebuilt natives for the current Node.js version. This makes npm run server:start
work out of the box. Trying to run npm run start-electron
with these versions generally causes an error such as this:
Uncaught Exception:
Error: The module '/Users/elian/Projects/Notes/node_modules/better-sqlite3/build/Release/better_sqlite3.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 108. This version of Node.js requires
NODE_MODULE_VERSION 116. Please try re-compiling or re-installing
-the module (for instance, using `npm rebuild` or `npm install`).
How the natives are handled Locally, this can be fixed by rebuilding the binaries, which is what npm run switch-electron
does, which uses electron-rebuild
under the hood.
When the deliveries are built (see Build deliveries locally ), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, better-sqlite3
provides these prebuilt binaries from us, available as artifacts on their GitHub releases page .
The build script manages the natives for better-sqlite3
by keeping a copy of the .node
file for every platform in bin/better-sqlite3
.
Whenever the version of better-sqlite3
changes, the .node
files must also be renewed based on their releases page. To simplify this process, a script was created in bin/better-sqlite3/update.sh
.
How to update the natives The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries.
If you get errors during download, check on the releases page to ensure that this particular combination of Electron/Node actually exists for the given release.
To determine the NODE_MODULE_VERSION
that is required, look for This version of Node.js requires
NODE_MODULE_VERSION
in the error when starting Trilium via:
npm run start-electron
(or run any Electron delivery ), case in which the ELECTRON_VERSION
variable needs to be changed.npm run start-server
(or run the Linux server delivery), case in which the NODE_VERSION
variable needs to be changed.Check which files got changed after running the update script and for each platform that got changed, test it locally via Build deliveries locally or via the CI.
+the module (for instance, using `npm rebuild` or `npm install`).
How the natives are handled Locally, this can be fixed by rebuilding the binaries, which is what npm run switch-electron
does, which uses electron-rebuild
under the hood.
When the deliveries are built (see Build deliveries locally ), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, better-sqlite3
provides these prebuilt binaries from us, available as artifacts on their GitHub releases page .
The build script manages the natives for better-sqlite3
by keeping a copy of the .node
file for every platform in bin/better-sqlite3
.
Whenever the version of better-sqlite3
changes, the .node
files must also be renewed based on their releases page. To simplify this process, a script was created in bin/better-sqlite3/update.sh
.
How to update the natives The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries.
If you get errors during download, check on the releases page to ensure that this particular combination of Electron/Node actually exists for the given release.
To determine the NODE_MODULE_VERSION
that is required, look for This version of Node.js requires
NODE_MODULE_VERSION
in the error when starting Trilium via:
npm run start-electron
(or run any Electron delivery ), case in which the ELECTRON_VERSION
variable needs to be changed.npm run server:start
(or run the Linux server delivery), case in which the NODE_VERSION
variable needs to be changed.Check which files got changed after running the update script and for each platform that got changed, test it locally via Build deliveries locally or via the CI.
diff --git a/docs/XxqZW6JjkW2g.html b/docs/XxqZW6JjkW2g.html
index 3307c8c4f..666d8ae9f 100644
--- a/docs/XxqZW6JjkW2g.html
+++ b/docs/XxqZW6JjkW2g.html
@@ -38,7 +38,7 @@
-
Server live reload If running the server using npm run start-server
, the server will watch for changes in src/public
and trigger a frontend reload if that occurs.
Electron live reload Similarly, npm run start-electron
supports live refresh as well.
However, a core difference is that Electron watches dist/src/public
instead of src/public
since Electron runs on its own copy of the files.
To ameliorate that, a separate watch script has been implemented which automatically copies files from src/public
to dist/src/public
whenever a change is detected. To run it:
npm run
Technical details This mechanism is managed at server level by watching for changes inservices/ws.ts
.
+
Server live reload If running the server using npm run server:start
, the server will watch for changes in src/public
and trigger a frontend reload if that occurs.
Electron live reload Similarly, npm run start-electron
supports live refresh as well.
However, a core difference is that Electron watches dist/src/public
instead of src/public
since Electron runs on its own copy of the files.
To ameliorate that, a separate watch script has been implemented which automatically copies files from src/public
to dist/src/public
whenever a change is detected. To run it:
npm run
Technical details This mechanism is managed at server level by watching for changes inservices/ws.ts
.
diff --git a/docs/backend_api/index.html b/docs/backend_api/index.html
index 612058e6f..6c27bd07a 100644
--- a/docs/backend_api/index.html
+++ b/docs/backend_api/index.html
@@ -71,7 +71,7 @@
Server To install TriliumNext on your own server (including via Docker from Dockerhub ) follow the server installation docs .
📝 Documentation See wiki for complete list of documentation pages.
You can also read Patterns of personal knowledge base to get some inspiration on how you might use TriliumNext.
-💻 Contribute Code git clone https://github.com/TriliumNext/Notes.git cd Notes npm install npm run start-server
+💻 Contribute Code git clone https://github.com/TriliumNext/Notes.git cd Notes npm install npm run server:start
Copy
Documentation Head on over to our Docs repo
diff --git a/docs/backend_api/media/README-ZH_CN.md b/docs/backend_api/media/README-ZH_CN.md
index f6aa860b1..1f6bbaf55 100644
--- a/docs/backend_api/media/README-ZH_CN.md
+++ b/docs/backend_api/media/README-ZH_CN.md
@@ -78,7 +78,7 @@ Trilium 也提供 Flatpak:
```shell
npm install
-npm run start-server
+npm run server:start
```
## 👏 致谢
diff --git a/docs/backend_api/media/README.es.md b/docs/backend_api/media/README.es.md
index a2ea94144..bfa57fe45 100644
--- a/docs/backend_api/media/README.es.md
+++ b/docs/backend_api/media/README.es.md
@@ -86,7 +86,7 @@ Clone localmente y ejecute
```shell
npm install
-npm run start-server
+npm run server:start
```
## 👏 Reconocimientos
diff --git a/docs/backend_api/media/README.it.md b/docs/backend_api/media/README.it.md
index a778230c7..750027c1a 100644
--- a/docs/backend_api/media/README.it.md
+++ b/docs/backend_api/media/README.it.md
@@ -73,7 +73,7 @@ Clona localmente ed esegui
```shell
npm install
-npm run start-server
+npm run server:start
```
## 👏 Riconoscimenti
diff --git a/docs/backend_api/media/README.ja.md b/docs/backend_api/media/README.ja.md
index 110b779c5..757638770 100644
--- a/docs/backend_api/media/README.ja.md
+++ b/docs/backend_api/media/README.ja.md
@@ -54,7 +54,7 @@ Trilium は Flatpak としても提供されます:
```shell
npm install
-npm run start-server
+npm run server:start
```
## 📢 シャウトアウト
diff --git a/docs/backend_api/media/README.md b/docs/backend_api/media/README.md
index 1800f667e..c427d98d0 100644
--- a/docs/backend_api/media/README.md
+++ b/docs/backend_api/media/README.md
@@ -102,7 +102,7 @@ You can also read [Patterns of personal knowledge base](https://triliumnext.gith
git clone https://github.com/TriliumNext/Notes.git
cd Notes
npm install
-npm run start-server
+npm run server:start
```
### Documentation
diff --git a/docs/backend_api/media/README.ru.md b/docs/backend_api/media/README.ru.md
index d78738915..e2336efb3 100644
--- a/docs/backend_api/media/README.ru.md
+++ b/docs/backend_api/media/README.ru.md
@@ -44,7 +44,7 @@ Trilium предоставляется в виде десктопного при
```shell
npm install
-npm run start-server
+npm run server:start
```
## 👏 Благодарности
diff --git a/docs/btM6L9JtG301.html b/docs/btM6L9JtG301.html
index a16f503c9..3edf3154a 100644
--- a/docs/btM6L9JtG301.html
+++ b/docs/btM6L9JtG301.html
@@ -38,7 +38,7 @@
-
Run server Run with default settings:
npm run start-server
Run with custom port:
TRILIUM_PORT=8082 npm run start-server
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run start-electron
To run Electron using the same data directory as the production version:
npm run start-electron-no-dir
When done, switch back the better-sqlite3
dependency:
npm run switch-server
+
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run start-electron
To run Electron using the same data directory as the production version:
npm run start-electron-no-dir
When done, switch back the better-sqlite3
dependency:
npm run switch-server
diff --git a/package.json b/package.json
index 9829a639f..65bc95ddc 100644
--- a/package.json
+++ b/package.json
@@ -20,11 +20,11 @@
},
"type": "module",
"scripts": {
- "start-server": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
+ "server:start": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
"start-server-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
"start-server-no-dir": "cross-env TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
"start-test-server": "npm run switch-server && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
- "qstart-server": "npm run switch-server && npm run start-server",
+ "qstart-server": "npm run switch-server && npm run server:start",
"start-electron": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
"start-electron-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
"start-electron-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
From f3dda940ec149e67425206bf99b5d4a51195794b Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Thu, 13 Feb 2025 23:00:53 +0100
Subject: [PATCH 02/36] chore(scripts): namespace server
server:start-safe
server:start-no-dir
server:start-test
server:qstart
---
package.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/package.json b/package.json
index 65bc95ddc..14f731c44 100644
--- a/package.json
+++ b/package.json
@@ -21,10 +21,10 @@
"type": "module",
"scripts": {
"server:start": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
- "start-server-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
- "start-server-no-dir": "cross-env TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
- "start-test-server": "npm run switch-server && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
- "qstart-server": "npm run switch-server && npm run server:start",
+ "server:start-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
+ "server:start-no-dir": "cross-env TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
+ "server:start-test": "npm run switch-server && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
+ "server:qstart": "npm run switch-server && npm run server:start",
"start-electron": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
"start-electron-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
"start-electron-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
From 7b062badf032643b49b04d3c2c4d017ceac4aa90 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Thu, 13 Feb 2025 23:18:57 +0100
Subject: [PATCH 03/36] chore(scripts): namespace server
server:switch
---
docs/btM6L9JtG301.html | 2 +-
package.json | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/btM6L9JtG301.html b/docs/btM6L9JtG301.html
index 3edf3154a..64a04eb8a 100644
--- a/docs/btM6L9JtG301.html
+++ b/docs/btM6L9JtG301.html
@@ -38,7 +38,7 @@
-
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run start-electron
To run Electron using the same data directory as the production version:
npm run start-electron-no-dir
When done, switch back the better-sqlite3
dependency:
npm run switch-server
+
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run start-electron
To run Electron using the same data directory as the production version:
npm run start-electron-no-dir
When done, switch back the better-sqlite3
dependency:
npm run server:switch
diff --git a/package.json b/package.json
index 14f731c44..3b117de43 100644
--- a/package.json
+++ b/package.json
@@ -23,8 +23,9 @@
"server:start": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
"server:start-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
"server:start-no-dir": "cross-env TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
- "server:start-test": "npm run switch-server && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
- "server:qstart": "npm run switch-server && npm run server:start",
+ "server:start-test": "npm run server:switch && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
+ "server:qstart": "npm run server:switch && npm run server:start",
+ "server:switch": "rimraf ./node_modules/better-sqlite3 && npm install",
"start-electron": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
"start-electron-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
"start-electron-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
@@ -34,7 +35,6 @@
"start-electron-prod-no-dir": "npm run prepare-dist && cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
"start-electron-prod-no-dir-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
"qstart-electron": "npm run switch-electron && npm run start-electron",
- "switch-server": "rimraf ./node_modules/better-sqlite3 && npm install",
"switch-electron": "electron-rebuild",
"build-backend-docs": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
"build-frontend-docs": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
From 469519f5dfe6a67ebb48bc7dde13429ee26e5ac7 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Thu, 13 Feb 2025 23:25:38 +0100
Subject: [PATCH 04/36] chore(scripts): namespace electron:start
---
docs/X4N03xLYEWnN.html | 4 ++--
docs/XxqZW6JjkW2g.html | 2 +-
docs/btM6L9JtG301.html | 2 +-
package.json | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/docs/X4N03xLYEWnN.html b/docs/X4N03xLYEWnN.html
index 9e9bcfef6..dca059b84 100644
--- a/docs/X4N03xLYEWnN.html
+++ b/docs/X4N03xLYEWnN.html
@@ -38,12 +38,12 @@
-
The native node bindings better-sqlite3
has native Node bindings. With updates of better-sqlite3
, but also of Electron and Node.js versions, these bindings need to be updated.
Note that Electron and Node.js versions need different versions of these bindings, since Electron usually packs a different version of Node.js.
During development, npm install
tries to build or reuse prebuilt natives for the current Node.js version. This makes npm run server:start
work out of the box. Trying to run npm run start-electron
with these versions generally causes an error such as this:
Uncaught Exception:
+ The native node bindings better-sqlite3
has native Node bindings. With updates of better-sqlite3
, but also of Electron and Node.js versions, these bindings need to be updated.
Note that Electron and Node.js versions need different versions of these bindings, since Electron usually packs a different version of Node.js.
During development, npm install
tries to build or reuse prebuilt natives for the current Node.js version. This makes npm run server:start
work out of the box. Trying to run npm run electron:start
with these versions generally causes an error such as this:
Uncaught Exception:
Error: The module '/Users/elian/Projects/Notes/node_modules/better-sqlite3/build/Release/better_sqlite3.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 108. This version of Node.js requires
NODE_MODULE_VERSION 116. Please try re-compiling or re-installing
-the module (for instance, using `npm rebuild` or `npm install`).
How the natives are handled Locally, this can be fixed by rebuilding the binaries, which is what npm run switch-electron
does, which uses electron-rebuild
under the hood.
When the deliveries are built (see Build deliveries locally ), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, better-sqlite3
provides these prebuilt binaries from us, available as artifacts on their GitHub releases page .
The build script manages the natives for better-sqlite3
by keeping a copy of the .node
file for every platform in bin/better-sqlite3
.
Whenever the version of better-sqlite3
changes, the .node
files must also be renewed based on their releases page. To simplify this process, a script was created in bin/better-sqlite3/update.sh
.
How to update the natives The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries.
If you get errors during download, check on the releases page to ensure that this particular combination of Electron/Node actually exists for the given release.
To determine the NODE_MODULE_VERSION
that is required, look for This version of Node.js requires
NODE_MODULE_VERSION
in the error when starting Trilium via:
npm run start-electron
(or run any Electron delivery ), case in which the ELECTRON_VERSION
variable needs to be changed.npm run server:start
(or run the Linux server delivery), case in which the NODE_VERSION
variable needs to be changed.Check which files got changed after running the update script and for each platform that got changed, test it locally via Build deliveries locally or via the CI.
+the module (for instance, using `npm rebuild` or `npm install`).
How the natives are handled Locally, this can be fixed by rebuilding the binaries, which is what npm run switch-electron
does, which uses electron-rebuild
under the hood.
When the deliveries are built (see Build deliveries locally ), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, better-sqlite3
provides these prebuilt binaries from us, available as artifacts on their GitHub releases page .
The build script manages the natives for better-sqlite3
by keeping a copy of the .node
file for every platform in bin/better-sqlite3
.
Whenever the version of better-sqlite3
changes, the .node
files must also be renewed based on their releases page. To simplify this process, a script was created in bin/better-sqlite3/update.sh
.
How to update the natives The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries.
If you get errors during download, check on the releases page to ensure that this particular combination of Electron/Node actually exists for the given release.
To determine the NODE_MODULE_VERSION
that is required, look for This version of Node.js requires
NODE_MODULE_VERSION
in the error when starting Trilium via:
npm run electron:start
(or run any Electron delivery ), case in which the ELECTRON_VERSION
variable needs to be changed.npm run server:start
(or run the Linux server delivery), case in which the NODE_VERSION
variable needs to be changed.Check which files got changed after running the update script and for each platform that got changed, test it locally via Build deliveries locally or via the CI.
diff --git a/docs/XxqZW6JjkW2g.html b/docs/XxqZW6JjkW2g.html
index 666d8ae9f..25b34176c 100644
--- a/docs/XxqZW6JjkW2g.html
+++ b/docs/XxqZW6JjkW2g.html
@@ -38,7 +38,7 @@
-
Server live reload If running the server using npm run server:start
, the server will watch for changes in src/public
and trigger a frontend reload if that occurs.
Electron live reload Similarly, npm run start-electron
supports live refresh as well.
However, a core difference is that Electron watches dist/src/public
instead of src/public
since Electron runs on its own copy of the files.
To ameliorate that, a separate watch script has been implemented which automatically copies files from src/public
to dist/src/public
whenever a change is detected. To run it:
npm run
Technical details This mechanism is managed at server level by watching for changes inservices/ws.ts
.
+
Server live reload If running the server using npm run server:start
, the server will watch for changes in src/public
and trigger a frontend reload if that occurs.
Electron live reload Similarly, npm run electron:start
supports live refresh as well.
However, a core difference is that Electron watches dist/src/public
instead of src/public
since Electron runs on its own copy of the files.
To ameliorate that, a separate watch script has been implemented which automatically copies files from src/public
to dist/src/public
whenever a change is detected. To run it:
npm run
Technical details This mechanism is managed at server level by watching for changes inservices/ws.ts
.
diff --git a/docs/btM6L9JtG301.html b/docs/btM6L9JtG301.html
index 64a04eb8a..4608a1ead 100644
--- a/docs/btM6L9JtG301.html
+++ b/docs/btM6L9JtG301.html
@@ -38,7 +38,7 @@
-
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run start-electron
To run Electron using the same data directory as the production version:
npm run start-electron-no-dir
When done, switch back the better-sqlite3
dependency:
npm run server:switch
+
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run electron:start
To run Electron using the same data directory as the production version:
npm run start-electron-no-dir
When done, switch back the better-sqlite3
dependency:
npm run server:switch
diff --git a/package.json b/package.json
index 3b117de43..4d5bfec2f 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
"server:start-test": "npm run server:switch && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
"server:qstart": "npm run server:switch && npm run server:start",
"server:switch": "rimraf ./node_modules/better-sqlite3 && npm install",
- "start-electron": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
+ "electron:start": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
"start-electron-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
"start-electron-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
"start-electron-no-dir-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
From 0f0ebed78aa143ecd5cc5d424ebecee681a2a7ea Mon Sep 17 00:00:00 2001
From: FliegendeWurst
Date: Thu, 13 Feb 2025 23:51:42 +0100
Subject: [PATCH 05/36] Document sync push/pull
---
bin/generate-openapi.js | 33 ++++++++++++-
src/routes/api/sync.ts | 105 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 137 insertions(+), 1 deletion(-)
diff --git a/bin/generate-openapi.js b/bin/generate-openapi.js
index ae6818482..cbd88c014 100644
--- a/bin/generate-openapi.js
+++ b/bin/generate-openapi.js
@@ -24,17 +24,48 @@ const options = {
},
},
},
- apis: ['./src/routes/api/*.ts', './bin/generate-openapi.js'],
+ apis: [
+ // Put individual files here to have them ordered first.
+ './src/routes/api/setup.ts',
+ // all other files
+ './src/routes/api/*.ts', './bin/generate-openapi.js'
+ ],
};
const openapiSpecification = swaggerJsdoc(options);
console.log(JSON.stringify(openapiSpecification));
+/**
+ * @swagger
+ * tags:
+ * - name: auth
+ * description: Authentication
+ * - name: sync
+ * description: Synchronization
+ */
+
/**
* @swagger
* components:
* schemas:
+ * EntityChange:
+ * type: object
+ * properties:
+ * entityChange:
+ * type: object
+ * properties:
+ * entityName:
+ * type: string
+ * example: "notes"
+ * description: Database table for this entity.
+ * changeId:
+ * type: string
+ * example: "changeId9630"
+ * description: ID, referenced in `entity_changes` table.
+ * entity:
+ * type: object
+ * description: Encoded entity data. Object has one property for each database column.
* UtcDateTime:
* type: string
* example: "2025-02-13T07:42:47.698Z"
diff --git a/src/routes/api/sync.ts b/src/routes/api/sync.ts
index d157fb4ed..49fc97fd0 100644
--- a/src/routes/api/sync.ts
+++ b/src/routes/api/sync.ts
@@ -86,6 +86,57 @@ function forceFullSync() {
syncService.sync();
}
+/**
+ * @swagger
+ * /api/sync/changed:
+ * get:
+ * summary: Pull sync changes
+ * operationId: sync-changed
+ * externalDocs:
+ * description: Server implementation
+ * url: https://github.com/TriliumNext/Notes/blob/v0.91.6/src/routes/api/sync.ts
+ * parameters:
+ * - in: query
+ * name: instanceId
+ * required: true
+ * schema:
+ * type: string
+ * description: Local instance ID
+ * - in: query
+ * name: lastEntityChangeId
+ * required: true
+ * schema:
+ * type: integer
+ * description: Last locally present change ID
+ * - in: query
+ * name: logMarkerId
+ * required: true
+ * schema:
+ * type: string
+ * description: Marker to identify this request in server log
+ * responses:
+ * '200':
+ * content:
+ * application/json:
+ * schema:
+ * type: object
+ * properties:
+ * entityChanges:
+ * type: list
+ * items:
+ * $ref: '#/components/schemas/EntityChange'
+ * lastEntityChangeId:
+ * type: integer
+ * description: If `outstandingPullCount > 0`, pass this as parameter in your next request to continue.
+ * outstandingPullCount:
+ * type: int
+ * example: 42
+ * description: Number of changes not yet returned by the remote.
+ * security:
+ * - session: []
+ * tags:
+ * - sync
+ */
function getChanged(req: Request) {
const startTime = Date.now();
@@ -151,6 +202,60 @@ const partialRequests: Record<
}
> = {};
+/**
+ * @swagger
+ * /api/sync/update:
+ * put:
+ * summary: Push sync changes
+ * description:
+ * "Basic usage: set `pageCount = 1`, `pageIndex = 0`, and omit `requestId`. Supply your entity changes in the request body."
+ * operationId: sync-update
+ * externalDocs:
+ * description: Server implementation
+ * url: https://github.com/TriliumNext/Notes/blob/v0.91.6/src/routes/api/sync.ts
+ * parameters:
+ * - in: header
+ * name: pageCount
+ * required: true
+ * schema:
+ * type: integer
+ * - in: header
+ * name: pageIndex
+ * required: true
+ * schema:
+ * type: integer
+ * - in: header
+ * name: requestId
+ * schema:
+ * type: string
+ * description: ID to identify paginated requests
+ * - in: query
+ * name: logMarkerId
+ * required: true
+ * schema:
+ * type: string
+ * description: Marker to identify this request in server log
+ * requestBody:
+ * content:
+ * application/json:
+ * schema:
+ * type: object
+ * properties:
+ * instanceId:
+ * type: string
+ * description: Local instance ID
+ * entities:
+ * type: list
+ * items:
+ * $ref: '#/components/schemas/EntityChange'
+ * responses:
+ * '200':
+ * description: Changes processed successfully
+ * security:
+ * - session: []
+ * tags:
+ * - sync
+ */
function update(req: Request) {
let { body } = req;
From 4dfce746e94749523c2636b6db1f07490361fd4a Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 14 Feb 2025 02:12:18 +0000
Subject: [PATCH 06/36] chore(deps): update dependency prettier to v3.5.1
---
package-lock.json | 8 ++++----
package.json | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 5fdf64248..3de275613 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -162,7 +162,7 @@
"jsdoc": "4.0.4",
"lorem-ipsum": "2.0.8",
"nodemon": "3.1.9",
- "prettier": "3.5.0",
+ "prettier": "3.5.1",
"rcedit": "4.0.1",
"rimraf": "6.0.1",
"swagger-jsdoc": "6.2.8",
@@ -14000,9 +14000,9 @@
}
},
"node_modules/prettier": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.0.tgz",
- "integrity": "sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA==",
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz",
+ "integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==",
"dev": true,
"license": "MIT",
"bin": {
diff --git a/package.json b/package.json
index 9829a639f..350d84be5 100644
--- a/package.json
+++ b/package.json
@@ -209,7 +209,7 @@
"jsdoc": "4.0.4",
"lorem-ipsum": "2.0.8",
"nodemon": "3.1.9",
- "prettier": "3.5.0",
+ "prettier": "3.5.1",
"rcedit": "4.0.1",
"rimraf": "6.0.1",
"swagger-jsdoc": "6.2.8",
From 35f9af15e52fabb7395c6635ed0ea8a8150ee35a Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 14 Feb 2025 02:12:30 +0000
Subject: [PATCH 07/36] chore(deps): update dependency electron to v34.2.0
---
package-lock.json | 14 +++++++-------
package.json | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 5fdf64248..02a0411ab 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -157,7 +157,7 @@
"@types/yargs": "17.0.33",
"@vitest/coverage-v8": "3.0.5",
"cross-env": "7.0.3",
- "electron": "34.1.1",
+ "electron": "34.2.0",
"esm": "3.2.25",
"jsdoc": "4.0.4",
"lorem-ipsum": "2.0.8",
@@ -8004,9 +8004,9 @@
}
},
"node_modules/electron": {
- "version": "34.1.1",
- "resolved": "https://registry.npmjs.org/electron/-/electron-34.1.1.tgz",
- "integrity": "sha512-1aDYk9Gsv1/fFeClMrxWGoVMl7uCUgl1pe26BiTnLXmAoqEXCa3f3sCKFWV+cuDzUjQGAZcpkWhGYTgWUSQrLA==",
+ "version": "34.2.0",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-34.2.0.tgz",
+ "integrity": "sha512-SYwBJNeXBTm1q/ErybQMUBZAYqEreBUqBwTrNkw1rV4YatDZk5Aittpcus3PPeC4UoI/tqmJ946uG8AKHTd6CA==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
@@ -8725,9 +8725,9 @@
}
},
"node_modules/electron/node_modules/@types/node": {
- "version": "20.17.17",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.17.tgz",
- "integrity": "sha512-/WndGO4kIfMicEQLTi/mDANUu/iVUhT7KboZPdEqqHQ4aTS+3qT3U5gIqWDFV+XouorjfgGqvKILJeHhuQgFYg==",
+ "version": "20.17.19",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.19.tgz",
+ "integrity": "sha512-LEwC7o1ifqg/6r2gn9Dns0f1rhK+fPFDoMiceTJ6kWmVk6bgXBI/9IOWfVan4WiAavK9pIVWdX0/e3J+eEUh5A==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.2"
diff --git a/package.json b/package.json
index 9829a639f..56d4cad22 100644
--- a/package.json
+++ b/package.json
@@ -204,7 +204,7 @@
"@types/yargs": "17.0.33",
"@vitest/coverage-v8": "3.0.5",
"cross-env": "7.0.3",
- "electron": "34.1.1",
+ "electron": "34.2.0",
"esm": "3.2.25",
"jsdoc": "4.0.4",
"lorem-ipsum": "2.0.8",
From 325431f0501454ece7e4127dbe478b1bdc79d549 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 14 Feb 2025 02:12:39 +0000
Subject: [PATCH 08/36] chore(deps): update dependency webpack to v5.98.0
---
package-lock.json | 245 ++++++++++------------------------------------
package.json | 2 +-
2 files changed, 52 insertions(+), 195 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 5fdf64248..0a601d256 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -171,7 +171,7 @@
"typedoc": "0.27.7",
"typescript": "5.7.3",
"vitest": "3.0.5",
- "webpack": "5.97.1",
+ "webpack": "5.98.0",
"webpack-cli": "6.0.1",
"webpack-dev-middleware": "7.4.2"
}
@@ -4970,15 +4970,15 @@
}
},
"node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
@@ -5002,35 +5002,16 @@
}
}
},
- "node_modules/ajv-formats/node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"license": "MIT",
"dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-uri": "^3.0.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2"
+ "fast-deep-equal": "^3.1.3"
},
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ajv-formats/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "license": "MIT"
- },
- "node_modules/ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "license": "MIT",
"peerDependencies": {
- "ajv": "^6.9.1"
+ "ajv": "^8.8.2"
}
},
"node_modules/amator": {
@@ -9027,6 +9008,28 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-scope/node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/esm": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
@@ -9547,12 +9550,6 @@
"node": ">= 6"
}
},
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "license": "MIT"
- },
"node_modules/fast-uri": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
@@ -11707,9 +11704,9 @@
"license": "MIT"
},
"node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
},
"node_modules/json-stringify-safe": {
@@ -15215,14 +15212,15 @@
}
},
"node_modules/schema-utils": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
- "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
"license": "MIT",
"dependencies": {
- "@types/json-schema": "^7.0.8",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
},
"engines": {
"node": ">= 10.13.0"
@@ -16502,59 +16500,6 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/terser-webpack-plugin/node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-uri": "^3.0.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
- "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3"
- },
- "peerDependencies": {
- "ajv": "^8.8.2"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "license": "MIT"
- },
- "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
- "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
- "license": "MIT",
- "dependencies": {
- "@types/json-schema": "^7.0.9",
- "ajv": "^8.9.0",
- "ajv-formats": "^2.1.1",
- "ajv-keywords": "^5.1.0"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -17295,15 +17240,6 @@
"browserslist": ">= 4.21.0"
}
},
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
"node_modules/username": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz",
@@ -18149,9 +18085,9 @@
}
},
"node_modules/webpack": {
- "version": "5.97.1",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz",
- "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==",
+ "version": "5.98.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
+ "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
"license": "MIT",
"dependencies": {
"@types/eslint-scope": "^3.7.7",
@@ -18172,9 +18108,9 @@
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
- "schema-utils": "^3.2.0",
+ "schema-utils": "^4.3.0",
"tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.3.10",
+ "terser-webpack-plugin": "^5.3.11",
"watchpack": "^2.4.1",
"webpack-sources": "^3.2.3"
},
@@ -18277,63 +18213,6 @@
}
}
},
- "node_modules/webpack-dev-middleware/node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-uri": "^3.0.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
- "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3"
- },
- "peerDependencies": {
- "ajv": "^8.8.2"
- }
- },
- "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/webpack-dev-middleware/node_modules/schema-utils": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
- "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/json-schema": "^7.0.9",
- "ajv": "^8.9.0",
- "ajv-formats": "^2.1.1",
- "ajv-keywords": "^5.1.0"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/webpack-merge": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz",
@@ -18358,28 +18237,6 @@
"node": ">=10.13.0"
}
},
- "node_modules/webpack/node_modules/eslint-scope": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
- "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^4.1.1"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/webpack/node_modules/estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=4.0"
- }
- },
"node_modules/whatwg-encoding": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
diff --git a/package.json b/package.json
index 9829a639f..f6154c6d3 100644
--- a/package.json
+++ b/package.json
@@ -218,7 +218,7 @@
"typedoc": "0.27.7",
"typescript": "5.7.3",
"vitest": "3.0.5",
- "webpack": "5.97.1",
+ "webpack": "5.98.0",
"webpack-cli": "6.0.1",
"webpack-dev-middleware": "7.4.2"
}
From 3d320308c955e1600d170c9e8af90f17883062d1 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 14 Feb 2025 02:12:50 +0000
Subject: [PATCH 09/36] chore(deps): update node.js to v22.14.0
---
Dockerfile | 4 ++--
Dockerfile.alpine | 4 ++--
package-lock.json | 8 ++++----
package.json | 2 +-
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 959c244a9..d2ceb1c91 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Build stage
-FROM node:22.13.1-bullseye-slim AS builder
+FROM node:22.14.0-bullseye-slim AS builder
# Configure build dependencies in a single layer
RUN apt-get update && apt-get install -y --no-install-recommends \
@@ -36,7 +36,7 @@ RUN cp -R build/src/* src/. && \
rm -r build
# Runtime stage
-FROM node:22.13.1-bullseye-slim
+FROM node:22.14.0-bullseye-slim
# Install only runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
diff --git a/Dockerfile.alpine b/Dockerfile.alpine
index f7b49b94c..a506193eb 100644
--- a/Dockerfile.alpine
+++ b/Dockerfile.alpine
@@ -1,5 +1,5 @@
# Build stage
-FROM node:22.13.1-alpine AS builder
+FROM node:22.14.0-alpine AS builder
# Configure build dependencies
RUN apk add --no-cache --virtual .build-dependencies \
@@ -35,7 +35,7 @@ RUN cp -R build/src/* src/. && \
rm -r build
# Runtime stage
-FROM node:22.13.1-alpine
+FROM node:22.14.0-alpine
# Install runtime dependencies
RUN apk add --no-cache su-exec shadow
diff --git a/package-lock.json b/package-lock.json
index 5fdf64248..c75074c94 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -141,7 +141,7 @@
"@types/leaflet-gpx": "1.3.7",
"@types/mime-types": "2.1.4",
"@types/multer": "1.4.12",
- "@types/node": "22.13.1",
+ "@types/node": "22.13.4",
"@types/react": "18.3.18",
"@types/safe-compare": "1.1.2",
"@types/sanitize-html": "2.13.0",
@@ -4239,9 +4239,9 @@
}
},
"node_modules/@types/node": {
- "version": "22.13.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
- "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
+ "version": "22.13.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz",
+ "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.20.0"
diff --git a/package.json b/package.json
index 9829a639f..9a421f033 100644
--- a/package.json
+++ b/package.json
@@ -188,7 +188,7 @@
"@types/leaflet-gpx": "1.3.7",
"@types/mime-types": "2.1.4",
"@types/multer": "1.4.12",
- "@types/node": "22.13.1",
+ "@types/node": "22.13.4",
"@types/react": "18.3.18",
"@types/safe-compare": "1.1.2",
"@types/sanitize-html": "2.13.0",
From 06890585d2b9e63d458dc5a91ed4bf0d55554e94 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 07:36:49 +0100
Subject: [PATCH 10/36] chore(scripts): namespace "electron:"
---
docs/btM6L9JtG301.html | 2 +-
package.json | 18 +++++++++---------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/docs/btM6L9JtG301.html b/docs/btM6L9JtG301.html
index 4608a1ead..6188237d3 100644
--- a/docs/btM6L9JtG301.html
+++ b/docs/btM6L9JtG301.html
@@ -38,7 +38,7 @@
-
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run electron:start
To run Electron using the same data directory as the production version:
npm run start-electron-no-dir
When done, switch back the better-sqlite3
dependency:
npm run server:switch
+
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run electron:start
To run Electron using the same data directory as the production version:
npm run electron:start-no-dir
When done, switch back the better-sqlite3
dependency:
npm run server:switch
diff --git a/package.json b/package.json
index 4d5bfec2f..04fbb65ec 100644
--- a/package.json
+++ b/package.json
@@ -27,15 +27,15 @@
"server:qstart": "npm run server:switch && npm run server:start",
"server:switch": "rimraf ./node_modules/better-sqlite3 && npm install",
"electron:start": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
- "start-electron-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
- "start-electron-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
- "start-electron-no-dir-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
- "start-electron-prod": "npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .",
- "start-electron-prod-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
- "start-electron-prod-no-dir": "npm run prepare-dist && cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
- "start-electron-prod-no-dir-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
- "qstart-electron": "npm run switch-electron && npm run start-electron",
- "switch-electron": "electron-rebuild",
+ "electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
+ "electron:start-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
+ "electron:start-nix-no-dir": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
+ "electron:start-prod": "npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .",
+ "electron:start-prod-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
+ "electron:start-prod-no-dir": "npm run prepare-dist && cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
+ "electron:start-prod-no-dir-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
+ "electron:qstart": "npm run electron:switch && npm run electron:start",
+ "electron:switch": "electron-rebuild",
"build-backend-docs": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
"build-frontend-docs": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
"build-docs": "npm run build-backend-docs && npm run build-frontend-docs",
From 0145636fc51d04835a1d6a6811178b5084369247 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 07:39:01 +0100
Subject: [PATCH 11/36] chore(scripts): namespace "electron:"
reorder entries
---
package.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index 04fbb65ec..f1a30b350 100644
--- a/package.json
+++ b/package.json
@@ -27,13 +27,13 @@
"server:qstart": "npm run server:switch && npm run server:start",
"server:switch": "rimraf ./node_modules/better-sqlite3 && npm install",
"electron:start": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
- "electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
"electron:start-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
+ "electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
"electron:start-nix-no-dir": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
"electron:start-prod": "npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .",
- "electron:start-prod-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
"electron:start-prod-no-dir": "npm run prepare-dist && cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
- "electron:start-prod-no-dir-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
+ "electron:start-prod-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
+ "electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
"electron:qstart": "npm run electron:switch && npm run electron:start",
"electron:switch": "electron-rebuild",
"build-backend-docs": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
From a30d361b1d75c03d3e7fc912efdfeb42f527b354 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 07:52:34 +0100
Subject: [PATCH 12/36] deps: remove leftover @types/jasmine
---
package-lock.json | 8 --------
package.json | 1 -
2 files changed, 9 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 5fdf64248..137f45027 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -135,7 +135,6 @@
"@types/fs-extra": "11.0.4",
"@types/html": "1.0.4",
"@types/ini": "4.1.1",
- "@types/jasmine": "5.1.5",
"@types/jquery": "3.5.32",
"@types/jsdom": "21.1.7",
"@types/leaflet-gpx": "1.3.7",
@@ -4104,13 +4103,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/jasmine": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.5.tgz",
- "integrity": "sha512-SaCZ3kM5NjOiJqMRYwHpLbTfUC2Dyk1KS3QanNFsUYPGTk70CWVK/J9ueun6zNhw/UkgV7xl8V4ZLQZNRbfnNw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@types/jquery": {
"version": "3.5.32",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz",
diff --git a/package.json b/package.json
index 9829a639f..1f92328a4 100644
--- a/package.json
+++ b/package.json
@@ -182,7 +182,6 @@
"@types/fs-extra": "11.0.4",
"@types/html": "1.0.4",
"@types/ini": "4.1.1",
- "@types/jasmine": "5.1.5",
"@types/jquery": "3.5.32",
"@types/jsdom": "21.1.7",
"@types/leaflet-gpx": "1.3.7",
From 58eaf5eb5bd83b0906a3d01fa87667dcf33c8bf5 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:01:30 +0100
Subject: [PATCH 13/36] test(etapi): mark as TODO for now
fixes typescript build for now
(not even sure, why we are building the tests as well)
---
spec/etapi/app_info.ts | 3 ++-
spec/etapi/backup.ts | 2 ++
spec/etapi/import.ts | 2 ++
spec/etapi/notes.ts | 2 ++
spec/support/etapi.ts | 1 +
5 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/spec/etapi/app_info.ts b/spec/etapi/app_info.ts
index 4bb8c4064..08aade29b 100644
--- a/spec/etapi/app_info.ts
+++ b/spec/etapi/app_info.ts
@@ -1,8 +1,9 @@
import etapi from "../support/etapi.js";
-
+/* TriliumNextTODO: port to Vitest
etapi.describeEtapi("app_info", () => {
it("get", async () => {
const appInfo = await etapi.getEtapi("app-info");
expect(appInfo.clipperProtocolVersion).toEqual("1.0");
});
});
+*/
\ No newline at end of file
diff --git a/spec/etapi/backup.ts b/spec/etapi/backup.ts
index 78aa01d7f..88e487f9e 100644
--- a/spec/etapi/backup.ts
+++ b/spec/etapi/backup.ts
@@ -1,8 +1,10 @@
import etapi from "../support/etapi.js";
+/* TriliumNextTODO: port to Vitest
etapi.describeEtapi("backup", () => {
it("create", async () => {
const response = await etapi.putEtapiContent("backup/etapi_test");
expect(response.status).toEqual(204);
});
});
+*/
\ No newline at end of file
diff --git a/spec/etapi/import.ts b/spec/etapi/import.ts
index d36a01c58..fc88a9ef5 100644
--- a/spec/etapi/import.ts
+++ b/spec/etapi/import.ts
@@ -3,6 +3,7 @@ import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
+/* TriliumNextTODO: port to Vitest
etapi.describeEtapi("import", () => {
// temporarily skip this test since test-export.zip is missing
xit("import", async () => {
@@ -22,3 +23,4 @@ etapi.describeEtapi("import", () => {
expect(content).toContain("test export content");
});
});
+*/
\ No newline at end of file
diff --git a/spec/etapi/notes.ts b/spec/etapi/notes.ts
index 6efcd88a1..dccb668df 100644
--- a/spec/etapi/notes.ts
+++ b/spec/etapi/notes.ts
@@ -1,6 +1,7 @@
import crypto from "crypto";
import etapi from "../support/etapi.js";
+/* TriliumNextTODO: port to Vitest
etapi.describeEtapi("notes", () => {
it("create", async () => {
const { note, branch } = await etapi.postEtapi("create-note", {
@@ -99,3 +100,4 @@ etapi.describeEtapi("notes", () => {
expect(error.message).toEqual(`Note '${note.noteId}' not found.`);
});
});
+*/
\ No newline at end of file
diff --git a/spec/support/etapi.ts b/spec/support/etapi.ts
index d653707d5..307868d7d 100644
--- a/spec/support/etapi.ts
+++ b/spec/support/etapi.ts
@@ -1,4 +1,5 @@
import type child_process from "child_process";
+import { describe, beforeAll, afterAll } from "vitest";
let etapiAuthToken: string | undefined;
From 688eb4d93f52c6dfd0c5ba77f175959697765061 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:31:07 +0100
Subject: [PATCH 14/36] chore(scripts): namespace "docs:"
---
package.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index f1a30b350..73af47986 100644
--- a/package.json
+++ b/package.json
@@ -36,9 +36,9 @@
"electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
"electron:qstart": "npm run electron:switch && npm run electron:start",
"electron:switch": "electron-rebuild",
- "build-backend-docs": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
- "build-frontend-docs": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
- "build-docs": "npm run build-backend-docs && npm run build-frontend-docs",
+ "docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
+ "docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
+ "docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
"webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
"test-playwright": "playwright test",
"test": "cross-env TRILIUM_DATA_DIR=./data-test vitest",
From d2e8f946a0bae86cd35afa100c2c8c0daf698903 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:35:46 +0100
Subject: [PATCH 15/36] chore(scripts): namespace
"chore:ci-update-nightly-version"
---
.github/workflows/nightly.yml | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 2b1fbe57e..f7cee700a 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -38,7 +38,7 @@ jobs:
shell: bash
run: npm ci
- name: Update nightly version
- run: npm run ci-update-nightly-version
+ run: npm run chore:ci-update-nightly-version
- name: Run the build
uses: ./.github/actions/build-electron
with:
diff --git a/package.json b/package.json
index 73af47986..29577415c 100644
--- a/package.json
+++ b/package.json
@@ -54,7 +54,7 @@
"integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
"generate-openapi": "node bin/generate-openapi.js",
- "ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts",
+ "chore:ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts",
"prettier-check": "prettier . --check",
"prettier-fix": "prettier . --write"
},
From 47002aa95ad155bb50b7179a755e9fd388861b9b Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:38:18 +0100
Subject: [PATCH 16/36] chore(scripts): namespace "chore:update-build-info"
---
.github/actions/build-electron/action.yml | 2 +-
.github/actions/build-server/action.yml | 2 +-
bin/release.sh | 2 +-
docs/mPGbEmYGitWe.html | 2 +-
package.json | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml
index b55ffea4b..e4081b906 100644
--- a/.github/actions/build-electron/action.yml
+++ b/.github/actions/build-electron/action.yml
@@ -33,7 +33,7 @@ runs:
run: sed -e "s/case 'armv7l'/case 'arm64'/g" -e "s/return 'arm'/return 'aarch64'/g" -i node_modules/@electron-forge/maker-flatpak/dist/MakerFlatpak.js
- name: Update build info
shell: bash
- run: npm run update-build-info
+ run: npm run chore:update-build-info
- name: Run electron-forge
shell: bash
run: npm run make-electron -- --arch=${{ inputs.arch }}
diff --git a/.github/actions/build-server/action.yml b/.github/actions/build-server/action.yml
index 694005c1b..cf8057c70 100644
--- a/.github/actions/build-server/action.yml
+++ b/.github/actions/build-server/action.yml
@@ -18,7 +18,7 @@ runs:
MATRIX_ARCH: ${{ inputs.arch }}
shell: bash
run: |
- npm run update-build-info
+ npm run chore:update-build-info
./bin/build-server.sh
- name: Prepare artifacts
shell: bash
diff --git a/bin/release.sh b/bin/release.sh
index fea1e030f..74559a88c 100755
--- a/bin/release.sh
+++ b/bin/release.sh
@@ -32,7 +32,7 @@ mv package.json.tmp package.json
git add package.json
-npm run update-build-info
+npm run chore:update-build-info
git add src/services/build.ts
diff --git a/docs/mPGbEmYGitWe.html b/docs/mPGbEmYGitWe.html
index a66680a97..017d198b7 100644
--- a/docs/mPGbEmYGitWe.html
+++ b/docs/mPGbEmYGitWe.html
@@ -38,7 +38,7 @@
-
Provides context about when the build was made and the corresponding Git revision. The information is displayed to the client when going in the about dialog. The build information is hard-coded in src/services/build.ts
. This file is generated automatically via npm run update-build-info
which itself is run automatically whenever making a build in the CI, or a local delivery .
+
Provides context about when the build was made and the corresponding Git revision. The information is displayed to the client when going in the about dialog. The build information is hard-coded in src/services/build.ts
. This file is generated automatically via npm run chore:update-build-info
which itself is run automatically whenever making a build in the CI, or a local delivery .
diff --git a/package.json b/package.json
index 29577415c..8d81b7cc3 100644
--- a/package.json
+++ b/package.json
@@ -48,12 +48,12 @@
"package-electron": "electron-forge package",
"prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
"watch-dist": "tsx ./bin/watch-dist.ts",
- "update-build-info": "tsx bin/update-build-info.ts",
"integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
"generate-openapi": "node bin/generate-openapi.js",
+ "chore:update-build-info": "tsx bin/update-build-info.ts",
"chore:ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts",
"prettier-check": "prettier . --check",
"prettier-fix": "prettier . --write"
From 9cddb1deac183596327678da7b819bce388875f8 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:41:34 +0100
Subject: [PATCH 17/36] chore(scripts): namespace "build:webpack"
---
Dockerfile | 2 +-
Dockerfile.alpine | 2 +-
bin/copy-trilium.sh | 2 +-
package.json | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 959c244a9..620c13789 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -25,7 +25,7 @@ RUN cp -R build/src/* src/. && \
cp build/docker_healthcheck.js . && \
rm docker_healthcheck.ts && \
npm install && \
- npm run webpack && \
+ npm run build:webpack && \
npm prune --omit=dev && \
npm cache clean --force && \
cp -r src/public/app/doc_notes src/public/app-dist/. && \
diff --git a/Dockerfile.alpine b/Dockerfile.alpine
index f7b49b94c..cac6d1871 100644
--- a/Dockerfile.alpine
+++ b/Dockerfile.alpine
@@ -24,7 +24,7 @@ RUN cp -R build/src/* src/. && \
cp build/docker_healthcheck.js . && \
rm docker_healthcheck.ts && \
npm install && \
- npm run webpack && \
+ npm run build:webpack && \
npm prune --omit=dev && \
npm cache clean --force && \
cp -r src/public/app/doc_notes src/public/app-dist/. && \
diff --git a/bin/copy-trilium.sh b/bin/copy-trilium.sh
index 221e8a0ea..e1d0e197f 100755
--- a/bin/copy-trilium.sh
+++ b/bin/copy-trilium.sh
@@ -23,7 +23,7 @@ rm -rf "$DIR"
mkdir -pv "$DIR"
echo Webpack start
-npm run webpack
+npm run build:webpack
echo Webpack finish
echo "Copying Trilium to build directory $DIR"
diff --git a/package.json b/package.json
index 8d81b7cc3..2f9f1a406 100644
--- a/package.json
+++ b/package.json
@@ -39,12 +39,12 @@
"docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
"docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
"docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
- "webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
+ "build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
"test-playwright": "playwright test",
"test": "cross-env TRILIUM_DATA_DIR=./data-test vitest",
"test-coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
"start-electron-forge": "npm run prepare-dist && electron-forge start",
- "make-electron": "npm run webpack && npm run prepare-dist && electron-forge make",
+ "make-electron": "npm run build:webpack && npm run prepare-dist && electron-forge make",
"package-electron": "electron-forge package",
"prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
"watch-dist": "tsx ./bin/watch-dist.ts",
From 4f6085a1a4e1e15c132f8cb4fb6f0b2bc222ece7 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:43:41 +0100
Subject: [PATCH 18/36] chore(scripts): namespace "build:prepare-dist"
---
package.json | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/package.json b/package.json
index 2f9f1a406..95b51dc71 100644
--- a/package.json
+++ b/package.json
@@ -30,23 +30,23 @@
"electron:start-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
"electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
"electron:start-nix-no-dir": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
- "electron:start-prod": "npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .",
- "electron:start-prod-no-dir": "npm run prepare-dist && cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
- "electron:start-prod-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
- "electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
+ "electron:start-prod": "npm run build:prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .",
+ "electron:start-prod-no-dir": "npm run build:prepare-dist && cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
+ "electron:start-prod-nix": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
+ "electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
"electron:qstart": "npm run electron:switch && npm run electron:start",
"electron:switch": "electron-rebuild",
"docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
"docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
"docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
"build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
+ "build:prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
"test-playwright": "playwright test",
"test": "cross-env TRILIUM_DATA_DIR=./data-test vitest",
"test-coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
- "start-electron-forge": "npm run prepare-dist && electron-forge start",
- "make-electron": "npm run build:webpack && npm run prepare-dist && electron-forge make",
+ "start-electron-forge": "npm run build:prepare-dist && electron-forge start",
+ "make-electron": "npm run build:webpack && npm run build:prepare-dist && electron-forge make",
"package-electron": "electron-forge package",
- "prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
"watch-dist": "tsx ./bin/watch-dist.ts",
"integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
From d23734dd3f091b257d5893ea17e52c67c65ca43a Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:44:25 +0100
Subject: [PATCH 19/36] chore(scripts): add some line breaks for better
separation
---
package.json | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/package.json b/package.json
index 95b51dc71..1cd4c29e4 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"server:start-test": "npm run server:switch && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
"server:qstart": "npm run server:switch && npm run server:start",
"server:switch": "rimraf ./node_modules/better-sqlite3 && npm install",
+
"electron:start": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
"electron:start-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
"electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
@@ -36,11 +37,14 @@
"electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
"electron:qstart": "npm run electron:switch && npm run electron:start",
"electron:switch": "electron-rebuild",
+
"docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
"docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
"docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
+
"build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
"build:prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
+
"test-playwright": "playwright test",
"test": "cross-env TRILIUM_DATA_DIR=./data-test vitest",
"test-coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
From 5f5d7b54320981f87b2a2f3cb5127f92c61591c6 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:48:14 +0100
Subject: [PATCH 20/36] chore(scripts): namespace "electron-forge:*"
---
.github/actions/build-electron/action.yml | 2 +-
package.json | 7 ++++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml
index e4081b906..76e8161b5 100644
--- a/.github/actions/build-electron/action.yml
+++ b/.github/actions/build-electron/action.yml
@@ -36,7 +36,7 @@ runs:
run: npm run chore:update-build-info
- name: Run electron-forge
shell: bash
- run: npm run make-electron -- --arch=${{ inputs.arch }}
+ run: npm run electron-forge:make -- --arch=${{ inputs.arch }}
- name: Prepare artifacts
shell: bash
run: |
diff --git a/package.json b/package.json
index 1cd4c29e4..ab706733d 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,10 @@
"electron:qstart": "npm run electron:switch && npm run electron:start",
"electron:switch": "electron-rebuild",
+ "electron-forge:start": "npm run build:prepare-dist && electron-forge start",
+ "electron-forge:make": "npm run build:webpack && npm run build:prepare-dist && electron-forge make",
+ "electron-forge:package": "electron-forge package",
+
"docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
"docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
"docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
@@ -48,9 +52,6 @@
"test-playwright": "playwright test",
"test": "cross-env TRILIUM_DATA_DIR=./data-test vitest",
"test-coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
- "start-electron-forge": "npm run build:prepare-dist && electron-forge start",
- "make-electron": "npm run build:webpack && npm run build:prepare-dist && electron-forge make",
- "package-electron": "electron-forge package",
"watch-dist": "tsx ./bin/watch-dist.ts",
"integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
From ae41555b514bd0398225e710dc08920b763810f6 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:50:43 +0100
Subject: [PATCH 21/36] chore(scripts): namespace "test:*"
---
package.json | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index ab706733d..7cb3974ad 100644
--- a/package.json
+++ b/package.json
@@ -49,9 +49,10 @@
"build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
"build:prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
- "test-playwright": "playwright test",
"test": "cross-env TRILIUM_DATA_DIR=./data-test vitest",
- "test-coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
+ "test:coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
+ "test:playwright": "playwright test",
+
"watch-dist": "tsx ./bin/watch-dist.ts",
"integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
From 218a88972566d064ebf6508cd4abb5f70293aab4 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:54:05 +0100
Subject: [PATCH 22/36] chore(scripts): namespace "dev:*"
---
package.json | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/package.json b/package.json
index 7cb3974ad..2b6457a20 100644
--- a/package.json
+++ b/package.json
@@ -53,16 +53,17 @@
"test:coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
"test:playwright": "playwright test",
- "watch-dist": "tsx ./bin/watch-dist.ts",
+ "dev:watch-dist": "tsx ./bin/watch-dist.ts",
+ "dev:prettier-check": "prettier . --check",
+ "dev:prettier-fix": "prettier . --write",
+
"integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
"generate-openapi": "node bin/generate-openapi.js",
"chore:update-build-info": "tsx bin/update-build-info.ts",
- "chore:ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts",
- "prettier-check": "prettier . --check",
- "prettier-fix": "prettier . --write"
+ "chore:ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts"
},
"dependencies": {
"@braintree/sanitize-url": "7.1.1",
From 0cace7f3f9da5799dbf5158de3ba3aff60a64739 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 08:56:45 +0100
Subject: [PATCH 23/36] chore(scripts): add integration test servers to
namespace "test:*"
---
package.json | 7 ++++---
playwright.config.ts | 2 +-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/package.json b/package.json
index 2b6457a20..aa0756308 100644
--- a/package.json
+++ b/package.json
@@ -53,13 +53,14 @@
"test:coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
"test:playwright": "playwright test",
+ "test:integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
+ "test:integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
+ "test:integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
+
"dev:watch-dist": "tsx ./bin/watch-dist.ts",
"dev:prettier-check": "prettier . --check",
"dev:prettier-fix": "prettier . --write",
- "integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
- "integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
- "integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
"generate-openapi": "node bin/generate-openapi.js",
"chore:update-build-info": "tsx bin/update-build-info.ts",
diff --git a/playwright.config.ts b/playwright.config.ts
index 9015af28e..e5377db4b 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -74,7 +74,7 @@ export default defineConfig({
/* Run your local dev server before starting the tests */
webServer: !process.env.TRILIUM_DOCKER ? {
- command: 'npm run integration-mem-db-dev',
+ command: 'npm run test:integration-mem-db-dev',
url: SERVER_URL,
reuseExistingServer: !process.env.CI,
} : undefined,
From 21d18b1bdfecd8da448abcf574e39618e4199b6d Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 09:00:42 +0100
Subject: [PATCH 24/36] chore(scripts): add generate-* to namespace "chore:*"
---
package.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index aa0756308..53070e6ed 100644
--- a/package.json
+++ b/package.json
@@ -61,10 +61,10 @@
"dev:prettier-check": "prettier . --check",
"dev:prettier-fix": "prettier . --write",
- "generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
- "generate-openapi": "node bin/generate-openapi.js",
"chore:update-build-info": "tsx bin/update-build-info.ts",
- "chore:ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts"
+ "chore:ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts",
+ "chore:generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
+ "chore:generate-openapi": "node bin/generate-openapi.js"
},
"dependencies": {
"@braintree/sanitize-url": "7.1.1",
From e89d1b24131700a76302fb063f0fbde5b9d4a023 Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 09:11:35 +0100
Subject: [PATCH 25/36] chore(scripts): fix electron:switch in docs
---
docs/X4N03xLYEWnN.html | 2 +-
docs/btM6L9JtG301.html | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/X4N03xLYEWnN.html b/docs/X4N03xLYEWnN.html
index dca059b84..b8e844cba 100644
--- a/docs/X4N03xLYEWnN.html
+++ b/docs/X4N03xLYEWnN.html
@@ -43,7 +43,7 @@ Error: The module '/Users/elian/Projects/Notes/node_modules/better-sqlite3/build
was compiled against a different Node.js version using
NODE_MODULE_VERSION 108. This version of Node.js requires
NODE_MODULE_VERSION 116. Please try re-compiling or re-installing
-the module (for instance, using `npm rebuild` or `npm install`).
How the natives are handled Locally, this can be fixed by rebuilding the binaries, which is what npm run switch-electron
does, which uses electron-rebuild
under the hood.
When the deliveries are built (see Build deliveries locally ), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, better-sqlite3
provides these prebuilt binaries from us, available as artifacts on their GitHub releases page .
The build script manages the natives for better-sqlite3
by keeping a copy of the .node
file for every platform in bin/better-sqlite3
.
Whenever the version of better-sqlite3
changes, the .node
files must also be renewed based on their releases page. To simplify this process, a script was created in bin/better-sqlite3/update.sh
.
How to update the natives The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries.
If you get errors during download, check on the releases page to ensure that this particular combination of Electron/Node actually exists for the given release.
To determine the NODE_MODULE_VERSION
that is required, look for This version of Node.js requires
NODE_MODULE_VERSION
in the error when starting Trilium via:
npm run electron:start
(or run any Electron delivery ), case in which the ELECTRON_VERSION
variable needs to be changed.npm run server:start
(or run the Linux server delivery), case in which the NODE_VERSION
variable needs to be changed.Check which files got changed after running the update script and for each platform that got changed, test it locally via Build deliveries locally or via the CI.
+the module (for instance, using `npm rebuild` or `npm install`).How the natives are handled Locally, this can be fixed by rebuilding the binaries, which is what npm run electron:switch
does, which uses electron-rebuild
under the hood.
When the deliveries are built (see Build deliveries locally ), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, better-sqlite3
provides these prebuilt binaries from us, available as artifacts on their GitHub releases page .
The build script manages the natives for better-sqlite3
by keeping a copy of the .node
file for every platform in bin/better-sqlite3
.
Whenever the version of better-sqlite3
changes, the .node
files must also be renewed based on their releases page. To simplify this process, a script was created in bin/better-sqlite3/update.sh
.
How to update the natives The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries.
If you get errors during download, check on the releases page to ensure that this particular combination of Electron/Node actually exists for the given release.
To determine the NODE_MODULE_VERSION
that is required, look for This version of Node.js requires
NODE_MODULE_VERSION
in the error when starting Trilium via:
npm run electron:start
(or run any Electron delivery ), case in which the ELECTRON_VERSION
variable needs to be changed.npm run server:start
(or run the Linux server delivery), case in which the NODE_VERSION
variable needs to be changed.Check which files got changed after running the update script and for each platform that got changed, test it locally via Build deliveries locally or via the CI.
diff --git a/docs/btM6L9JtG301.html b/docs/btM6L9JtG301.html
index 6188237d3..f8a6b4701 100644
--- a/docs/btM6L9JtG301.html
+++ b/docs/btM6L9JtG301.html
@@ -38,7 +38,7 @@
-
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run switch-electron
Then run Electron:
npm run electron:start
To run Electron using the same data directory as the production version:
npm run electron:start-no-dir
When done, switch back the better-sqlite3
dependency:
npm run server:switch
+
Run server Run with default settings:
npm run server:start
Run with custom port:
TRILIUM_PORT=8082 npm run server:start
Run Electron Rebuild better-sqlite3
dependency:
npm run electron:switch
Then run Electron:
npm run electron:start
To run Electron using the same data directory as the production version:
npm run electron:start-no-dir
When done, switch back the better-sqlite3
dependency:
npm run server:switch
From 0e18c405d890a600211a8d1fff0fe7947b15575e Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 09:17:57 +0100
Subject: [PATCH 26/36] test: "unskip" skipped tests
---
src/services/search/services/search.spec.ts | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/services/search/services/search.spec.ts b/src/services/search/services/search.spec.ts
index e468ffd07..493eff030 100644
--- a/src/services/search/services/search.spec.ts
+++ b/src/services/search/services/search.spec.ts
@@ -22,7 +22,7 @@ describe("Search", () => {
});
});
- it.skip("simple path match", () => {
+ it("simple path match", () => {
rootNote.child(note("Europe").child(note("Austria")));
const searchContext = new SearchContext();
@@ -32,7 +32,7 @@ describe("Search", () => {
expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy();
});
- it.skip("normal search looks also at attributes", () => {
+ it("normal search looks also at attributes", () => {
const austria = note("Austria");
const vienna = note("Vienna");
@@ -50,7 +50,7 @@ describe("Search", () => {
expect(findNoteByTitle(searchResults, "Vienna")).toBeTruthy();
});
- it.skip("normal search looks also at type and mime", () => {
+ it("normal search looks also at type and mime", () => {
rootNote.child(note("Effective Java", { type: "book", mime: "" })).child(note("Hello World.java", { type: "code", mime: "text/x-java" }));
const searchContext = new SearchContext();
@@ -69,7 +69,7 @@ describe("Search", () => {
expect(searchResults.length).toEqual(2);
});
- it.skip("only end leafs are results", () => {
+ it("only end leafs are results", () => {
rootNote.child(note("Europe").child(note("Austria")));
const searchContext = new SearchContext();
@@ -79,7 +79,7 @@ describe("Search", () => {
expect(findNoteByTitle(searchResults, "Europe")).toBeTruthy();
});
- it.skip("only end leafs are results", () => {
+ it("only end leafs are results", () => {
rootNote.child(note("Europe").child(note("Austria").label("capital", "Vienna")));
const searchContext = new SearchContext();
@@ -132,7 +132,7 @@ describe("Search", () => {
expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy();
});
- it.skip("inherited label comparison", () => {
+ it("inherited label comparison", () => {
rootNote.child(note("Europe").label("country", "", true).child(note("Austria")).child(note("Czech Republic")));
const searchContext = new SearchContext();
@@ -527,7 +527,7 @@ describe("Search", () => {
expect(becca.notes[searchResults[0].noteId].title).toEqual("Europe");
});
- it.skip("test note.text *=* something", () => {
+ it("test note.text *=* something", () => {
const italy = note("Italy").label("capital", "Rome");
const slovakia = note("Slovakia").label("capital", "Bratislava");
@@ -540,7 +540,7 @@ describe("Search", () => {
expect(becca.notes[searchResults[0].noteId].title).toEqual("Slovakia");
});
- it.skip("test that fulltext does not match archived notes", () => {
+ it("test that fulltext does not match archived notes", () => {
const italy = note("Italy").label("capital", "Rome");
const slovakia = note("Slovakia").label("capital", "Bratislava");
From a115214070f42a9be6b1fe766aeda909b7ea0e2d Mon Sep 17 00:00:00 2001
From: FliegendeWurst
Date: Fri, 14 Feb 2025 09:40:38 +0100
Subject: [PATCH 27/36] Document some note, branch, tree routes
---
bin/generate-openapi.js | 102 +++++++++++++++++++++++++++++++++++
src/routes/api/app_info.ts | 1 +
src/routes/api/branches.ts | 45 ++++++++++++++++
src/routes/api/notes.ts | 108 +++++++++++++++++++++++++++++++++++++
src/routes/api/sync.ts | 1 +
src/routes/api/tree.ts | 40 ++++++++++++++
6 files changed, 297 insertions(+)
diff --git a/bin/generate-openapi.js b/bin/generate-openapi.js
index cbd88c014..3ec26b2c3 100644
--- a/bin/generate-openapi.js
+++ b/bin/generate-openapi.js
@@ -43,12 +43,78 @@ console.log(JSON.stringify(openapiSpecification));
* description: Authentication
* - name: sync
* description: Synchronization
+ * - name: data
*/
/**
* @swagger
* components:
* schemas:
+ * Attribute:
+ * type: object
+ * properties:
+ * attributeId:
+ * type: string
+ * example: "4G1DPrI58PAb"
+ * noteId:
+ * $ref: "#/components/schemas/NoteId"
+ * type:
+ * type: string
+ * enum: ["attribute", "relation"]
+ * name:
+ * type: string
+ * example: "internalLink"
+ * value:
+ * type: string
+ * example: "hA8aHSpTRdZ6"
+ * description: "If type = \"relation\", a note ID. Otherwise, the attribute content."
+ * position:
+ * type: integer
+ * example: 20
+ * isInheritable:
+ * type: boolean
+ * Blob:
+ * type: object
+ * properties:
+ * blobId:
+ * type: string
+ * example: "8iqMIB8eiY1tPYmElfjm"
+ * content:
+ * type:
+ * - string
+ * - 'null'
+ * description: "`null` if not text."
+ * contentLength:
+ * type: integer
+ * dateModified:
+ * $ref: "#/components/schemas/DateTime"
+ * utcDateModified:
+ * $ref: "#/components/schemas/UtcDateTime"
+ * Branch:
+ * type: object
+ * properties:
+ * branchId:
+ * $ref: "#/components/schemas/BranchId"
+ * noteId:
+ * $ref: "#/components/schemas/NoteId"
+ * parentNoteId:
+ * $ref: "#/components/schemas/NoteId"
+ * notePosition:
+ * type: integer
+ * example: 20
+ * prefix:
+ * type:
+ * - string
+ * - 'null'
+ * isExpanded:
+ * type: boolean
+ * BranchId:
+ * type: string
+ * example: "WUjhaGp4EKah_ur11rSfHkzeV"
+ * description: Equal to `{parentNoteId}_{noteId}`
+ * DateTime:
+ * type: string
+ * example: "2025-02-14 08:19:59.203+0100"
* EntityChange:
* type: object
* properties:
@@ -66,9 +132,45 @@ console.log(JSON.stringify(openapiSpecification));
* entity:
* type: object
* description: Encoded entity data. Object has one property for each database column.
+ * Note:
+ * type: object
+ * properties:
+ * noteId:
+ * $ref: "#/components/schemas/NoteId"
+ * title:
+ * type: string
+ * isProtected:
+ * type: boolean
+ * type:
+ * type: string
+ * example: "text"
+ * enum: ["text", "code", "render", "file", "image", "search", "relationMap", "book", "noteMap", "mermaid", "canvas", "webView", "launcher", "doc", "contentWidget", "mindMap", "geoMap"]
+ * description: "[Reference list](https://github.com/TriliumNext/Notes/blob/v0.91.6/src/services/note_types.ts)"
+ * mime:
+ * type: string
+ * example: "text/html"
+ * blobId:
+ * type: string
+ * example: "z4PhNX7vuL3xVChQ1m2A"
+ * NoteId:
+ * type: string
+ * example: "ur11rSfHkzeV"
+ * description: "12-character note ID. Special values: \"none\"`, `\"root\"."
+ * Timestamps:
+ * type: object
+ * properties:
+ * dateCreated:
+ * $ref: "#/components/schemas/DateTime"
+ * dateModified:
+ * $ref: "#/components/schemas/DateTime"
+ * utcDateCreated:
+ * $ref: "#/components/schemas/UtcDateTime"
+ * utcDateModified:
+ * $ref: "#/components/schemas/UtcDateTime"
* UtcDateTime:
* type: string
* example: "2025-02-13T07:42:47.698Z"
+ * description: "Result of `new Date().toISOString().replace('T', ' ')`"
* securitySchemes:
* user-password:
* type: apiKey
diff --git a/src/routes/api/app_info.ts b/src/routes/api/app_info.ts
index 560a52d1f..fb2f84aec 100644
--- a/src/routes/api/app_info.ts
+++ b/src/routes/api/app_info.ts
@@ -13,6 +13,7 @@ import appInfo from "../../services/app_info.js";
* url: https://github.com/TriliumNext/Notes/blob/v0.91.6/src/services/app_info.ts
* responses:
* '200':
+ * description: Installation info
* content:
* application/json:
* schema:
diff --git a/src/routes/api/branches.ts b/src/routes/api/branches.ts
index b9c5f751d..b81d0cfc0 100644
--- a/src/routes/api/branches.ts
+++ b/src/routes/api/branches.ts
@@ -186,6 +186,51 @@ function setExpandedForSubtree(req: Request) {
};
}
+/**
+ * @swagger
+ * /api/branches/{branchId}:
+ * delete:
+ * summary: Delete branch (note clone)
+ * operationId: branches-delete
+ * parameters:
+ * - name: branchId
+ * in: path
+ * required: true
+ * schema:
+ * $ref: "#/components/schemas/BranchId"
+ * - name: taskId
+ * in: query
+ * required: true
+ * schema:
+ * type: string
+ * description: Task group identifier
+ * - name: eraseNotes
+ * in: query
+ * schema:
+ * type: boolean
+ * required: false
+ * description: Whether to erase the note immediately
+ * - name: last
+ * in: query
+ * schema:
+ * type: boolean
+ * required: true
+ * description: Whether this is the last request of this task group
+ * responses:
+ * '200':
+ * description: Branch successfully deleted
+ * content:
+ * application/json:
+ * schema:
+ * type: object
+ * properties:
+ * noteDeleted:
+ * type: boolean
+ * description: Whether the last note clone was deleted
+ * security:
+ * - session: []
+ * tags: ["data"]
+ */
function deleteBranch(req: Request) {
const last = req.query.last === "true";
const eraseNotes = req.query.eraseNotes === "true";
diff --git a/src/routes/api/notes.ts b/src/routes/api/notes.ts
index 9f1dc5e41..853032938 100644
--- a/src/routes/api/notes.ts
+++ b/src/routes/api/notes.ts
@@ -14,14 +14,85 @@ import type { Request } from "express";
import type BBranch from "../../becca/entities/bbranch.js";
import type { AttributeRow } from "../../becca/entities/rows.js";
+/**
+ * @swagger
+ * /api/notes/{noteId}:
+ * get:
+ * summary: Retrieve note metadata
+ * operationId: notes-get
+ * parameters:
+ * - name: noteId
+ * in: path
+ * required: true
+ * schema:
+ * $ref: "#/components/schemas/NoteId"
+ * responses:
+ * '200':
+ * description: Note metadata
+ * content:
+ * application/json:
+ * schema:
+ * allOf:
+ * - $ref: '#/components/schemas/Note'
+ * - $ref: "#/components/schemas/Timestamps"
+ * security:
+ * - session: []
+ * tags: ["data"]
+ */
function getNote(req: Request) {
return becca.getNoteOrThrow(req.params.noteId);
}
+/**
+ * @swagger
+ * /api/notes/{noteId}/blob:
+ * get:
+ * summary: Retrieve note content
+ * operationId: notes-blob
+ * parameters:
+ * - name: noteId
+ * in: path
+ * required: true
+ * schema:
+ * $ref: "#/components/schemas/NoteId"
+ * responses:
+ * '304':
+ * description: Note content
+ * content:
+ * application/json:
+ * schema:
+ * $ref: '#/components/schemas/Blob'
+ * security:
+ * - session: []
+ * tags: ["data"]
+ */
function getNoteBlob(req: Request) {
return blobService.getBlobPojo("notes", req.params.noteId);
}
+/**
+ * @swagger
+ * /api/notes/{noteId}/metadata:
+ * get:
+ * summary: Retrieve note metadata (limited to timestamps)
+ * operationId: notes-metadata
+ * parameters:
+ * - name: noteId
+ * in: path
+ * required: true
+ * schema:
+ * $ref: "#/components/schemas/NoteId"
+ * responses:
+ * '200':
+ * description: Note metadata
+ * content:
+ * application/json:
+ * schema:
+ * $ref: "#/components/schemas/Timestamps"
+ * security:
+ * - session: []
+ * tags: ["data"]
+ */
function getNoteMetadata(req: Request) {
const note = becca.getNoteOrThrow(req.params.noteId);
@@ -62,6 +133,43 @@ function updateNoteData(req: Request) {
return noteService.updateNoteData(noteId, content, attachments);
}
+/**
+ * @swagger
+ * /api/notes/{noteId}:
+ * delete:
+ * summary: Delete note
+ * operationId: notes-delete
+ * parameters:
+ * - name: noteId
+ * in: path
+ * required: true
+ * schema:
+ * $ref: "#/components/schemas/NoteId"
+ * - name: taskId
+ * in: query
+ * required: true
+ * schema:
+ * type: string
+ * description: Task group identifier
+ * - name: eraseNotes
+ * in: query
+ * schema:
+ * type: boolean
+ * required: false
+ * description: Whether to erase the note immediately
+ * - name: last
+ * in: query
+ * schema:
+ * type: boolean
+ * required: true
+ * description: Whether this is the last request of this task group
+ * responses:
+ * '200':
+ * description: Note successfully deleted
+ * security:
+ * - session: []
+ * tags: ["data"]
+ */
function deleteNote(req: Request) {
const noteId = req.params.noteId;
const taskId = req.query.taskId;
diff --git a/src/routes/api/sync.ts b/src/routes/api/sync.ts
index 49fc97fd0..736e1e97b 100644
--- a/src/routes/api/sync.ts
+++ b/src/routes/api/sync.ts
@@ -116,6 +116,7 @@ function forceFullSync() {
* description: Marker to identify this request in server log
* responses:
* '200':
+ * description: Sync changes, limited to approximately one megabyte.
* content:
* application/json:
* schema:
diff --git a/src/routes/api/tree.ts b/src/routes/api/tree.ts
index d90470993..610c82fde 100644
--- a/src/routes/api/tree.ts
+++ b/src/routes/api/tree.ts
@@ -127,6 +127,46 @@ function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set) {
};
}
+/**
+ * @swagger
+ * /api/tree:
+ * get:
+ * summary: Retrieve tree data
+ * operationId: tree
+ * externalDocs:
+ * description: Server implementation
+ * url: https://github.com/TriliumNext/Notes/blob/v0.91.6/src/routes/api/tree.ts
+ * parameters:
+ * - in: query
+ * name: subTreeNoteId
+ * required: false
+ * schema:
+ * type: string
+ * description: Limit tree data to this note and descendants
+ * responses:
+ * '200':
+ * description: Notes, branches and attributes
+ * content:
+ * application/json:
+ * schema:
+ * type: object
+ * properties:
+ * branches:
+ * type: list
+ * items:
+ * $ref: '#/components/schemas/Branch'
+ * notes:
+ * type: list
+ * items:
+ * $ref: '#/components/schemas/Note'
+ * attributes:
+ * type: list
+ * items:
+ * $ref: '#/components/schemas/Attribute'
+ * security:
+ * - session: []
+ * tags: ["data"]
+ */
function getTree(req: Request) {
const subTreeNoteId = typeof req.query.subTreeNoteId === "string" ? req.query.subTreeNoteId : "root";
const collectedNoteIds = new Set([subTreeNoteId]);
From 84429e6e908b0ce6111dc96241aec1b3bcca8f3a Mon Sep 17 00:00:00 2001
From: Panagiotis Papadopoulos
Date: Fri, 14 Feb 2025 17:47:24 +0100
Subject: [PATCH 28/36] test: use integration-tests/db as data dir for tests
we have an initialized DB there, so that "integration like" tests that depend on the DB are not failing
---
package.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 9829a639f..7621c6265 100644
--- a/package.json
+++ b/package.json
@@ -41,8 +41,8 @@
"build-docs": "npm run build-backend-docs && npm run build-frontend-docs",
"webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
"test-playwright": "playwright test",
- "test": "cross-env TRILIUM_DATA_DIR=./data-test vitest",
- "test-coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
+ "test": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest",
+ "test-coverage": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest --coverage",
"start-electron-forge": "npm run prepare-dist && electron-forge start",
"make-electron": "npm run webpack && npm run prepare-dist && electron-forge make",
"package-electron": "electron-forge package",
From 9d7f1a2d71565d1aef0165d7fdde6e336f76ab59 Mon Sep 17 00:00:00 2001
From: dousha
Date: Sat, 15 Feb 2025 01:52:07 +0800
Subject: [PATCH 29/36] Allow removing weak branches even if it's hoisted
---
src/becca/entities/bbranch.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/becca/entities/bbranch.ts b/src/becca/entities/bbranch.ts
index 0160ef61b..018f8f2f7 100644
--- a/src/becca/entities/bbranch.ts
+++ b/src/becca/entities/bbranch.ts
@@ -159,7 +159,7 @@ class BBranch extends AbstractBeccaEntity {
}
}
- if (this.noteId === "root" || this.noteId === cls.getHoistedNoteId()) {
+ if ((this.noteId === "root" || this.noteId === cls.getHoistedNoteId()) && !this.isWeak) {
throw new Error("Can't delete root or hoisted branch/note");
}
From 81d5d16e1aad305982f0919749e6098218350e2f Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 15 Feb 2025 00:02:00 +0200
Subject: [PATCH 30/36] chore(bin): convert generate-openapi to typescript
---
bin/{generate-openapi.js => generate-openapi.ts} | 0
package.json | 2 +-
2 files changed, 1 insertion(+), 1 deletion(-)
rename bin/{generate-openapi.js => generate-openapi.ts} (100%)
diff --git a/bin/generate-openapi.js b/bin/generate-openapi.ts
similarity index 100%
rename from bin/generate-openapi.js
rename to bin/generate-openapi.ts
diff --git a/package.json b/package.json
index 85f0d8940..7b8770288 100644
--- a/package.json
+++ b/package.json
@@ -53,7 +53,7 @@
"integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
"generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
- "generate-openapi": "node bin/generate-openapi.js",
+ "generate-openapi": "tsx bin/generate-openapi.js",
"ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts",
"prettier-check": "prettier . --check",
"prettier-fix": "prettier . --write"
From 9299f90b85a0c0f88ffcd2a0ac7e99254fa88d70 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 15 Feb 2025 00:25:23 +0200
Subject: [PATCH 31/36] feat(docs): internal API docs
---
bin/copy-dist.ts | 7 ++++++-
bin/generate-openapi.ts | 9 +++++++--
src/routes/api/openapi.json | 1 +
src/routes/api_docs.ts | 24 +++++++++++++++++-------
4 files changed, 31 insertions(+), 10 deletions(-)
create mode 100644 src/routes/api/openapi.json
diff --git a/bin/copy-dist.ts b/bin/copy-dist.ts
index 85013e992..83a31bbf7 100644
--- a/bin/copy-dist.ts
+++ b/bin/copy-dist.ts
@@ -29,7 +29,12 @@ const copy = async () => {
fs.copySync(path.join("build", srcFile), destFile, { recursive: true });
}
- const filesToCopy = ["config-sample.ini", "tsconfig.webpack.json", "./src/etapi/etapi.openapi.yaml"];
+ const filesToCopy = [
+ "config-sample.ini",
+ "tsconfig.webpack.json",
+ "./src/etapi/etapi.openapi.yaml",
+ "./src/routes/api/openapi.json"
+ ];
for (const file of filesToCopy) {
log(`Copying ${file}`);
await fs.copy(file, path.join(DEST_DIR, file));
diff --git a/bin/generate-openapi.ts b/bin/generate-openapi.ts
index 3ec26b2c3..4bd97a76f 100644
--- a/bin/generate-openapi.ts
+++ b/bin/generate-openapi.ts
@@ -1,4 +1,7 @@
+import { fileURLToPath } from "url";
+import { dirname, join } from "path";
import swaggerJsdoc from 'swagger-jsdoc';
+import fs from "fs";
/*
* Usage: npm run generate-openapi | tail -n1 > x.json
@@ -33,8 +36,10 @@ const options = {
};
const openapiSpecification = swaggerJsdoc(options);
-
-console.log(JSON.stringify(openapiSpecification));
+const scriptDir = dirname(fileURLToPath(import.meta.url));
+const outputPath = join(scriptDir, "..", "src", "routes", "api", "openapi.json");
+fs.writeFileSync(outputPath, JSON.stringify(openapiSpecification));
+console.log("Saved to ", outputPath);
/**
* @swagger
diff --git a/src/routes/api/openapi.json b/src/routes/api/openapi.json
new file mode 100644
index 000000000..3034c7e13
--- /dev/null
+++ b/src/routes/api/openapi.json
@@ -0,0 +1 @@
+{"openapi":"3.1.1","info":{"title":"Trilium Notes - Sync server API","version":"0.96.6","description":"This is the internal sync server API used by Trilium Notes / TriliumNext Notes.\n\n_If you're looking for the officially supported External Trilium API, see [here](https://triliumnext.github.io/Docs/Wiki/etapi.html)._\n\nThis page does not yet list all routes. For a full list, see the [route controller](https://github.com/TriliumNext/Notes/blob/v0.91.6/src/routes/routes.ts).","contact":{"name":"TriliumNext issue tracker","url":"https://github.com/TriliumNext/Notes/issues"},"license":{"name":"GNU Free Documentation License 1.3 (or later)","url":"https://www.gnu.org/licenses/fdl-1.3"}},"paths":{"/api/setup/sync-seed":{"get":{"tags":["auth"],"summary":"Sync documentSecret value","description":"First step to logging in.","operationId":"setup-sync-seed","responses":{"200":{"description":"Successful operation","content":{"application/json":{"schema":{"type":"object","properties":{"syncVersion":{"type":"integer","example":34},"options":{"type":"object","properties":{"documentSecret":{"type":"string"}}}}}}}}},"security":[{"user-password":[]}]}},"/api/app-info":{"get":{"summary":"Get installation info","operationId":"app-info","externalDocs":{"description":"Server implementation","url":"https://github.com/TriliumNext/Notes/blob/v0.91.6/src/services/app_info.ts"},"responses":{"200":{"description":"Installation info","content":{"application/json":{"schema":{"type":"object","properties":{"appVersion":{"type":"string","example":"0.91.6"},"dbVersion":{"type":"integer","example":228},"nodeVersion":{"type":"string","description":"value of process.version"},"syncVersion":{"type":"integer","example":34},"buildDate":{"type":"string","example":"2024-09-07T18:36:34Z"},"buildRevision":{"type":"string","example":"7c0d6930fa8f20d269dcfbcbc8f636a25f6bb9a7"},"dataDirectory":{"type":"string","example":"/var/lib/trilium"},"clipperProtocolVersion":{"type":"string","example":"1.0"},"utcDateTime":{"$ref":"#/components/schemas/UtcDateTime"}}}}}}},"security":[{"session":[]}]}},"/api/branches/{branchId}":{"delete":{"summary":"Delete branch (note clone)","operationId":"branches-delete","parameters":[{"name":"branchId","in":"path","required":true,"schema":{"$ref":"#/components/schemas/BranchId"}},{"name":"taskId","in":"query","required":true,"schema":{"type":"string"},"description":"Task group identifier"},{"name":"eraseNotes","in":"query","schema":{"type":"boolean"},"required":false,"description":"Whether to erase the note immediately"},{"name":"last","in":"query","schema":{"type":"boolean"},"required":true,"description":"Whether this is the last request of this task group"}],"responses":{"200":{"description":"Branch successfully deleted","content":{"application/json":{"schema":{"type":"object","properties":{"noteDeleted":{"type":"boolean","description":"Whether the last note clone was deleted"}}}}}}},"security":[{"session":[]}],"tags":["data"]}},"/api/login/sync":{"post":{"tags":["auth"],"summary":"Log in using documentSecret","description":"The `hash` parameter is computed using a HMAC of the `documentSecret` and `timestamp`.","operationId":"login-sync","externalDocs":{"description":"HMAC calculation","url":"https://github.com/TriliumNext/Notes/blob/v0.91.6/src/services/utils.ts#L62-L66"},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"timestamp":{"$ref":"#/components/schemas/UtcDateTime"},"hash":{"type":"string"},"syncVersion":{"type":"integer","example":34}}}}}},"responses":{"200":{"description":"Successful operation","content":{"application/json":{"schema":{"type":"object","properties":{"syncVersion":{"type":"integer","example":34},"options":{"type":"object","properties":{"documentSecret":{"type":"string"}}}}}}}},"400":{"description":"Sync version / document secret mismatch","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Non-matching sync versions, local is version ${server syncVersion}, remote is ${requested syncVersion}. It is recommended to run same version of Trilium on both sides of sync"}}}}}},"401":{"description":"Timestamp mismatch","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Auth request time is out of sync, please check that both client and server have correct time. The difference between clocks has to be smaller than 5 minutes"}}}}}}}}},"/api/notes/{noteId}":{"get":{"summary":"Retrieve note metadata","operationId":"notes-get","parameters":[{"name":"noteId","in":"path","required":true,"schema":{"$ref":"#/components/schemas/NoteId"}}],"responses":{"200":{"description":"Note metadata","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Note"},{"$ref":"#/components/schemas/Timestamps"}]}}}}},"security":[{"session":[]}],"tags":["data"]},"delete":{"summary":"Delete note","operationId":"notes-delete","parameters":[{"name":"noteId","in":"path","required":true,"schema":{"$ref":"#/components/schemas/NoteId"}},{"name":"taskId","in":"query","required":true,"schema":{"type":"string"},"description":"Task group identifier"},{"name":"eraseNotes","in":"query","schema":{"type":"boolean"},"required":false,"description":"Whether to erase the note immediately"},{"name":"last","in":"query","schema":{"type":"boolean"},"required":true,"description":"Whether this is the last request of this task group"}],"responses":{"200":{"description":"Note successfully deleted"}},"security":[{"session":[]}],"tags":["data"]}},"/api/notes/{noteId}/blob":{"get":{"summary":"Retrieve note content","operationId":"notes-blob","parameters":[{"name":"noteId","in":"path","required":true,"schema":{"$ref":"#/components/schemas/NoteId"}}],"responses":{"304":{"description":"Note content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Blob"}}}}},"security":[{"session":[]}],"tags":["data"]}},"/api/notes/{noteId}/metadata":{"get":{"summary":"Retrieve note metadata (limited to timestamps)","operationId":"notes-metadata","parameters":[{"name":"noteId","in":"path","required":true,"schema":{"$ref":"#/components/schemas/NoteId"}}],"responses":{"200":{"description":"Note metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Timestamps"}}}}},"security":[{"session":[]}],"tags":["data"]}},"/api/sync/changed":{"get":{"summary":"Pull sync changes","operationId":"sync-changed","externalDocs":{"description":"Server implementation","url":"https://github.com/TriliumNext/Notes/blob/v0.91.6/src/routes/api/sync.ts"},"parameters":[{"in":"query","name":"instanceId","required":true,"schema":{"type":"string"},"description":"Local instance ID"},{"in":"query","name":"lastEntityChangeId","required":true,"schema":{"type":"integer"},"description":"Last locally present change ID"},{"in":"query","name":"logMarkerId","required":true,"schema":{"type":"string"},"description":"Marker to identify this request in server log"}],"responses":{"200":{"description":"Sync changes, limited to approximately one megabyte.","content":{"application/json":{"schema":{"type":"object","properties":{"entityChanges":{"type":"list","items":{"$ref":"#/components/schemas/EntityChange"}},"lastEntityChangeId":{"type":"integer","description":"If `outstandingPullCount > 0`, pass this as parameter in your next request to continue."},"outstandingPullCount":{"type":"int","example":42,"description":"Number of changes not yet returned by the remote."}}}}}}},"security":[{"session":[]}],"tags":["sync"]}},"/api/sync/update":{"put":{"summary":"Push sync changes","description":"Basic usage: set `pageCount = 1`, `pageIndex = 0`, and omit `requestId`. Supply your entity changes in the request body.","operationId":"sync-update","externalDocs":{"description":"Server implementation","url":"https://github.com/TriliumNext/Notes/blob/v0.91.6/src/routes/api/sync.ts"},"parameters":[{"in":"header","name":"pageCount","required":true,"schema":{"type":"integer"}},{"in":"header","name":"pageIndex","required":true,"schema":{"type":"integer"}},{"in":"header","name":"requestId","schema":{"type":"string","description":"ID to identify paginated requests"}},{"in":"query","name":"logMarkerId","required":true,"schema":{"type":"string"},"description":"Marker to identify this request in server log"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"instanceId":{"type":"string","description":"Local instance ID"},"entities":{"type":"list","items":{"$ref":"#/components/schemas/EntityChange"}}}}}}},"responses":{"200":{"description":"Changes processed successfully"}},"security":[{"session":[]}],"tags":["sync"]}},"/api/tree":{"get":{"summary":"Retrieve tree data","operationId":"tree","externalDocs":{"description":"Server implementation","url":"https://github.com/TriliumNext/Notes/blob/v0.91.6/src/routes/api/tree.ts"},"parameters":[{"in":"query","name":"subTreeNoteId","required":false,"schema":{"type":"string"},"description":"Limit tree data to this note and descendants"}],"responses":{"200":{"description":"Notes, branches and attributes","content":{"application/json":{"schema":{"type":"object","properties":{"branches":{"type":"list","items":{"$ref":"#/components/schemas/Branch"}},"notes":{"type":"list","items":{"$ref":"#/components/schemas/Note"}},"attributes":{"type":"list","items":{"$ref":"#/components/schemas/Attribute"}}}}}}}},"security":[{"session":[]}],"tags":["data"]}}},"components":{},"tags":[]}
\ No newline at end of file
diff --git a/src/routes/api_docs.ts b/src/routes/api_docs.ts
index 1535265c3..3df230feb 100644
--- a/src/routes/api_docs.ts
+++ b/src/routes/api_docs.ts
@@ -1,4 +1,4 @@
-import type { Router } from "express";
+import type { Application, Router } from "express";
import swaggerUi from "swagger-ui-express";
import { readFile } from "fs/promises";
import { fileURLToPath } from "url";
@@ -7,19 +7,29 @@ import yaml from "js-yaml";
import type { JsonObject } from "swagger-ui-express";
const __dirname = dirname(fileURLToPath(import.meta.url));
-const swaggerDocument = yaml.load(
+const etapiDocument = yaml.load(
await readFile(join(__dirname, "../etapi/etapi.openapi.yaml"), "utf8")
) as JsonObject;
+const apiDocument = JSON.parse(await readFile(join(__dirname, "api", "openapi.json"), "utf-8"));
-function register(router: Router) {
- router.use(
- "/etapi",
- swaggerUi.serve,
- swaggerUi.setup(swaggerDocument, {
+function register(app: Application) {
+ app.use(
+ "/etapi/docs/",
+ swaggerUi.serveFiles(etapiDocument),
+ swaggerUi.setup(etapiDocument, {
explorer: true,
customSiteTitle: "TriliumNext ETAPI Documentation"
})
);
+
+ app.use(
+ "/api/docs/",
+ swaggerUi.serveFiles(apiDocument),
+ swaggerUi.setup(apiDocument, {
+ explorer: true,
+ customSiteTitle: "TriliumNext Internal API Documentation"
+ })
+ );
}
export default {
From ecb2c53c6f0af8898157004441bee9af8e71191a Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 15 Feb 2025 01:02:24 +0200
Subject: [PATCH 32/36] feat(in_app_help): support webviews
---
src/services/in_app_help.ts | 14 ++++++++++++++
src/services/meta/note_meta.ts | 3 ++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/services/in_app_help.ts b/src/services/in_app_help.ts
index 0af911684..fffbf7812 100644
--- a/src/services/in_app_help.ts
+++ b/src/services/in_app_help.ts
@@ -44,6 +44,15 @@ function parseNoteMeta(noteMeta: NoteMeta, docNameRoot: string): HiddenSubtreeIt
for (const attribute of noteMeta.attributes ?? []) {
if (attribute.name === "iconClass") {
iconClass = attribute.value;
+ continue;
+ }
+
+ if (attribute.name === "webViewSrc") {
+ item.attributes?.push({
+ type: "label",
+ name: attribute.name,
+ value: attribute.value
+ });
}
}
@@ -64,6 +73,11 @@ function parseNoteMeta(noteMeta: NoteMeta, docNameRoot: string): HiddenSubtreeIt
});
}
+ // Handle web views
+ if (noteMeta.type === "webView") {
+ item.type = "webView";
+ }
+
// Handle children
if (noteMeta.children) {
const children: HiddenSubtreeItem[] = [];
diff --git a/src/services/meta/note_meta.ts b/src/services/meta/note_meta.ts
index 0aaafb6b5..681ca4f8c 100644
--- a/src/services/meta/note_meta.ts
+++ b/src/services/meta/note_meta.ts
@@ -1,3 +1,4 @@
+import type { NoteType } from "../../becca/entities/rows.js";
import type AttachmentMeta from "./attachment_meta.js";
import type AttributeMeta from "./attribute_meta.js";
@@ -15,7 +16,7 @@ export default interface NoteMeta {
notePosition?: number;
prefix?: string | null;
isExpanded?: boolean;
- type?: string;
+ type?: NoteType;
mime?: string;
/** 'html' or 'markdown', applicable to text notes only */
format?: "html" | "markdown";
From fc77f56516bd08360ef37f515cf94b3c81e7a2a3 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 15 Feb 2025 01:05:37 +0200
Subject: [PATCH 33/36] chore(in_app_help): update docs
---
.../app/doc_notes/en/User Guide/!!!meta.json | 661 +++++++++++++++---
.../Custom resource providers.html | 56 ++
.../REST API/ETAPI/API Reference.dat | 0
.../REST API/Internal API/API Reference.dat | 0
.../1_Creating a custom theme_im.png} | Bin
.../1_Customize the Next theme_i.png} | Bin
.../2_Creating a custom theme_im.png} | Bin
.../3_Creating a custom theme_im.png} | Bin
.../4_Creating a custom theme_im.png} | Bin
.../5_Creating a custom theme_im.png} | Bin
.../Creating a custom theme.html | 14 +-
.../Creating a custom theme_im.png} | Bin
.../Customize the Next theme.html} | 8 +-
.../Customize the Next theme_i.png} | Bin
.../Theme development/Reference.html | 5 +
.../1_Export as PDF_image.png} | Bin
.../User Guide/Features/1_Zen mode_image.png | Bin 0 -> 8584 bytes
.../2_Export as PDF_image.png} | Bin
.../User Guide/Features/2_Zen mode_image.png | Bin 0 -> 16996 bytes
.../User Guide/Features/3_Zen mode_image.png | Bin 0 -> 25929 bytes
.../User Guide/Features/4_Zen mode_image.png | Bin 0 -> 127552 bytes
.../User Guide/Features/5_Zen mode_image.png | Bin 0 -> 95276 bytes
.../User Guide/Features/6_Zen mode_image.png | Bin 0 -> 1038 bytes
.../User Guide/Features/7_Zen mode_image.png | Bin 0 -> 80489 bytes
.../Export as PDF.html} | 19 +-
.../Export as PDF_image.png} | Bin
.../User Guide/Features/Zen mode.html | 73 ++
.../User Guide/Features/Zen mode_image.png | Bin 0 -> 94050 bytes
.../User Guide/User Guide/Installation.html | 38 +
.../1_On Fedora Linux_Screenshot.png | Bin 0 -> 45675 bytes
.../Installation/1_On Fedora Linux_image.png | Bin 0 -> 1199 bytes
.../2_On Fedora Linux_Screenshot.png | Bin 0 -> 11205 bytes
.../Installation/2_On Fedora Linux_image.png | Bin 0 -> 1121 bytes
.../3_On Fedora Linux_Screenshot.png | Bin 0 -> 34171 bytes
.../Installation/On Fedora Linux.html | 82 +++
.../On Fedora Linux_Screenshot.png | Bin 0 -> 13286 bytes
.../Installation/On Fedora Linux_image.png | Bin 0 -> 1123 bytes
.../User Guide/Installation_Fedora_logo.svg | 10 +
.../10_Geo map_image.png} | Bin
.../11_Geo map_image.png} | Bin
.../12_Geo map_image.png} | Bin
.../13_Geo map_image.png | Bin
.../14_Geo map_image.png} | Bin
.../15_Geo map_image.png} | Bin
.../16_Geo map_image.png} | Bin
.../17_Geo map_image.png} | Bin
.../18_Geo map_image.png} | Bin
.../19_Geo map_image.png} | Bin
.../1_Geo map_image.png} | Bin
.../2_Geo map_image.png} | Bin
.../3_Geo map_image.png} | Bin
.../4_Geo map_image.png} | Bin
.../5_Geo map_image.png} | Bin
.../6_Geo map_image.png} | Bin
.../7_Geo map_image.png} | Bin
.../8_Geo map_image.png} | Bin
.../9_Geo map_image.png} | Bin
.../Geo map.html | 74 +-
.../Geo map_image.png} | Bin
.../Note Types/Mermaid Diagram.html | 19 +
.../Downloading responses from Goo.html | 19 +
.../1_Serving directly the conte.png | Bin 0 -> 6937 bytes
.../Serving directly the conte.png | Bin 0 -> 10401 bytes
.../Serving directly the content o.html | 60 ++
.../app/doc_notes/en/User Guide/index.html | 2 +-
.../doc_notes/en/User Guide/navigation.html | 68 +-
66 files changed, 1076 insertions(+), 132 deletions(-)
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Custom resource providers.html
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/REST API/ETAPI/API Reference.dat
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/REST API/Internal API/API Reference.dat
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/2_Creating a custom theme_im.png => Advanced usage/Theme development/1_Creating a custom theme_im.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/Theme base (legacy vs. nex.png => Advanced usage/Theme development/1_Customize the Next theme_i.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/4_Creating a custom theme_im.png => Advanced usage/Theme development/2_Creating a custom theme_im.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/1_Creating a custom theme_im.png => Advanced usage/Theme development/3_Creating a custom theme_im.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/5_Creating a custom theme_im.png => Advanced usage/Theme development/4_Creating a custom theme_im.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/Creating a custom theme_im.png => Advanced usage/Theme development/5_Creating a custom theme_im.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users => Advanced usage}/Theme development/Creating a custom theme.html (87%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/3_Creating a custom theme_im.png => Advanced usage/Theme development/Creating a custom theme_im.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/Theme base (legacy vs. next).html => Advanced usage/Theme development/Customize the Next theme.html} (78%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users/Theme development/1_Theme base (legacy vs. nex.png => Advanced usage/Theme development/Customize the Next theme_i.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Power users => Advanced usage}/Theme development/Reference.html (93%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Working with notes/2_Exporting as PDF_image.png => Features/1_Export as PDF_image.png} (100%)
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/1_Zen mode_image.png
rename src/public/app/doc_notes/en/User Guide/User Guide/{Working with notes/Exporting as PDF_image.png => Features/2_Export as PDF_image.png} (100%)
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/2_Zen mode_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/3_Zen mode_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/4_Zen mode_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/5_Zen mode_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/6_Zen mode_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/7_Zen mode_image.png
rename src/public/app/doc_notes/en/User Guide/User Guide/{Working with notes/Exporting as PDF.html => Features/Export as PDF.html} (78%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Working with notes/1_Exporting as PDF_image.png => Features/Export as PDF_image.png} (100%)
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/Zen mode.html
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Features/Zen mode_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation.html
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/1_On Fedora Linux_Screenshot.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/1_On Fedora Linux_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/2_On Fedora Linux_Screenshot.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/2_On Fedora Linux_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/3_On Fedora Linux_Screenshot.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux.html
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux_Screenshot.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux_image.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation_Fedora_logo.svg
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/Geo map_image.png => Note Types/10_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/3_Geo map_image.png => Note Types/11_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/9_Geo map_image.png => Note Types/12_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes => Note Types}/13_Geo map_image.png (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/4_Geo map_image.png => Note Types/14_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/19_Geo map_image.png => Note Types/15_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/8_Geo map_image.png => Note Types/16_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/12_Geo map_image.png => Note Types/17_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/10_Geo map_image.png => Note Types/18_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/11_Geo map_image.png => Note Types/19_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/5_Geo map_image.png => Note Types/1_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/14_Geo map_image.png => Note Types/2_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/1_Geo map_image.png => Note Types/3_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/7_Geo map_image.png => Note Types/4_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/2_Geo map_image.png => Note Types/5_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/18_Geo map_image.png => Note Types/6_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/6_Geo map_image.png => Note Types/7_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/17_Geo map_image.png => Note Types/8_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/15_Geo map_image.png => Note Types/9_Geo map_image.png} (100%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes => Note Types}/Geo map.html (80%)
rename src/public/app/doc_notes/en/User Guide/User Guide/{Types of notes/16_Geo map_image.png => Note Types/Geo map_image.png} (100%)
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagram.html
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.html
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Shared notes/1_Serving directly the conte.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Shared notes/Serving directly the conte.png
create mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Shared notes/Serving directly the content o.html
diff --git a/src/public/app/doc_notes/en/User Guide/!!!meta.json b/src/public/app/doc_notes/en/User Guide/!!!meta.json
index ffee6a973..f7ee2b545 100644
--- a/src/public/app/doc_notes/en/User Guide/!!!meta.json
+++ b/src/public/app/doc_notes/en/User Guide/!!!meta.json
@@ -1,6 +1,6 @@
{
"formatVersion": 2,
- "appVersion": "0.91.5",
+ "appVersion": "0.91.6-test-250214-024424",
"files": [
{
"isClone": false,
@@ -11,7 +11,7 @@
"title": "User Guide",
"notePosition": 20,
"prefix": null,
- "isExpanded": false,
+ "isExpanded": true,
"type": "text",
"mime": "text/html",
"attributes": [
@@ -29,22 +29,326 @@
"children": [
{
"isClone": false,
- "noteId": "wmegHv51MJMd",
+ "noteId": "jrai60LsOhdk",
"notePath": [
"OkOZllzB3fqN",
- "wmegHv51MJMd"
+ "jrai60LsOhdk"
],
- "title": "Types of notes",
+ "title": "Installation",
"notePosition": 20,
"prefix": null,
"isExpanded": false,
"type": "text",
"mime": "text/html",
+ "attributes": [
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "KPeRqBU7YSAY",
+ "isInheritable": false,
+ "position": 10
+ },
+ {
+ "type": "label",
+ "name": "hideChildrenOverview",
+ "value": "",
+ "isInheritable": false,
+ "position": 10
+ }
+ ],
+ "format": "html",
+ "dataFileName": "Installation.html",
+ "attachments": [
+ {
+ "attachmentId": "Mp9RaDeLtETz",
+ "title": "Fedora_logo.svg",
+ "role": "image",
+ "mime": "image/svg+xml",
+ "position": 10,
+ "dataFileName": "Installation_Fedora_logo.svg"
+ }
+ ],
+ "dirFileName": "Installation",
+ "children": [
+ {
+ "isClone": false,
+ "noteId": "KPeRqBU7YSAY",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "jrai60LsOhdk",
+ "KPeRqBU7YSAY"
+ ],
+ "title": "On Fedora Linux",
+ "notePosition": 10,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [
+ {
+ "type": "label",
+ "name": "iconClass",
+ "value": "bx bxl-tux",
+ "isInheritable": false,
+ "position": 10
+ }
+ ],
+ "format": "html",
+ "dataFileName": "On Fedora Linux.html",
+ "attachments": [
+ {
+ "attachmentId": "YHD8kyEhgkyZ",
+ "title": "Screenshot From 2025-02-05 19-30-50.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "On Fedora Linux_Screenshot.png"
+ },
+ {
+ "attachmentId": "0CpZ5v5xUMia",
+ "title": "Screenshot From 2025-02-05 19-35-45.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "1_On Fedora Linux_Screenshot.png"
+ },
+ {
+ "attachmentId": "9u7nBYvUbXJW",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "On Fedora Linux_image.png"
+ },
+ {
+ "attachmentId": "ipGBq0moRvF3",
+ "title": "Screenshot From 2025-02-05 19-36-27.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "2_On Fedora Linux_Screenshot.png"
+ },
+ {
+ "attachmentId": "fa83WbDUIB4G",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "1_On Fedora Linux_image.png"
+ },
+ {
+ "attachmentId": "kcCWr0YXytOU",
+ "title": "Screenshot From 2025-02-05 19-30-30.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "3_On Fedora Linux_Screenshot.png"
+ },
+ {
+ "attachmentId": "YF3JZy1qz7Fq",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "2_On Fedora Linux_image.png"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "isClone": false,
+ "noteId": "yoAe4jV2yzbd",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "yoAe4jV2yzbd"
+ ],
+ "title": "Features",
+ "notePosition": 40,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
"attributes": [],
"format": "html",
"attachments": [],
- "dirFileName": "Types of notes",
+ "dirFileName": "Features",
"children": [
+ {
+ "isClone": false,
+ "noteId": "13D1lOc9sqmZ",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "yoAe4jV2yzbd",
+ "13D1lOc9sqmZ"
+ ],
+ "title": "Export as PDF",
+ "notePosition": 20,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "dataFileName": "Export as PDF.html",
+ "attachments": [
+ {
+ "attachmentId": "xsGM34t8ssKV",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "Export as PDF_image.png"
+ },
+ {
+ "attachmentId": "cvyes4f1Vhmm",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "1_Export as PDF_image.png"
+ },
+ {
+ "attachmentId": "b3v1pLE6TF1Y",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "2_Export as PDF_image.png"
+ }
+ ]
+ },
+ {
+ "isClone": false,
+ "noteId": "B3YLYM4erjnW",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "yoAe4jV2yzbd",
+ "B3YLYM4erjnW"
+ ],
+ "title": "Zen mode",
+ "notePosition": 30,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "dataFileName": "Zen mode.html",
+ "attachments": [
+ {
+ "attachmentId": "TS5MS8fQ8Rfr",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/jpg",
+ "position": 10,
+ "dataFileName": "Zen mode_image.png"
+ },
+ {
+ "attachmentId": "cswryNtIFZHy",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/jpg",
+ "position": 10,
+ "dataFileName": "1_Zen mode_image.png"
+ },
+ {
+ "attachmentId": "UDk4M7uiTE7w",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/jpg",
+ "position": 10,
+ "dataFileName": "2_Zen mode_image.png"
+ },
+ {
+ "attachmentId": "sQldbByAmE0k",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "3_Zen mode_image.png"
+ },
+ {
+ "attachmentId": "DzrJD3hXJwXJ",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "4_Zen mode_image.png"
+ },
+ {
+ "attachmentId": "HeGfp8wObFO5",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "5_Zen mode_image.png"
+ },
+ {
+ "attachmentId": "uWsrFwgfypsS",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "6_Zen mode_image.png"
+ },
+ {
+ "attachmentId": "hX8xmbxgSNFh",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "7_Zen mode_image.png"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "isClone": false,
+ "noteId": "wmegHv51MJMd",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "wmegHv51MJMd"
+ ],
+ "title": "Note Types",
+ "notePosition": 70,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "attachments": [],
+ "dirFileName": "Note Types",
+ "children": [
+ {
+ "isClone": false,
+ "noteId": "TTWESa9YFyB4",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "wmegHv51MJMd",
+ "TTWESa9YFyB4"
+ ],
+ "title": "Mermaid Diagram",
+ "notePosition": 10,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [
+ {
+ "type": "label",
+ "name": "iconClass",
+ "value": "bx bx-shape-square",
+ "isInheritable": false,
+ "position": 10
+ }
+ ],
+ "format": "html",
+ "dataFileName": "Mermaid Diagram.html",
+ "attachments": []
+ },
{
"isClone": false,
"noteId": "foPEtsL51pD2",
@@ -54,7 +358,7 @@
"foPEtsL51pD2"
],
"title": "Geo map",
- "notePosition": 10,
+ "notePosition": 20,
"prefix": null,
"isExpanded": false,
"type": "text",
@@ -72,7 +376,7 @@
"dataFileName": "Geo map.html",
"attachments": [
{
- "attachmentId": "viN50n5G4kB0",
+ "attachmentId": "J0baLTpafs7C",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -80,7 +384,7 @@
"dataFileName": "Geo map_image.png"
},
{
- "attachmentId": "eUrcqc8RRuZG",
+ "attachmentId": "kcYjOvJDFkbS",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -88,7 +392,7 @@
"dataFileName": "1_Geo map_image.png"
},
{
- "attachmentId": "1quk4yxJpeHZ",
+ "attachmentId": "FDP3JzIVSnuJ",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -96,7 +400,7 @@
"dataFileName": "2_Geo map_image.png"
},
{
- "attachmentId": "mgwGrtQZjxxb",
+ "attachmentId": "eUrcqc8RRuZG",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -104,7 +408,7 @@
"dataFileName": "3_Geo map_image.png"
},
{
- "attachmentId": "JULizn130rVI",
+ "attachmentId": "0AwaQMqt3FVA",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -112,7 +416,7 @@
"dataFileName": "4_Geo map_image.png"
},
{
- "attachmentId": "kcYjOvJDFkbS",
+ "attachmentId": "1quk4yxJpeHZ",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -120,7 +424,7 @@
"dataFileName": "5_Geo map_image.png"
},
{
- "attachmentId": "ut6vm2aXVfXI",
+ "attachmentId": "iSpyhQ5Ya6Nk",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -128,7 +432,7 @@
"dataFileName": "6_Geo map_image.png"
},
{
- "attachmentId": "0AwaQMqt3FVA",
+ "attachmentId": "ut6vm2aXVfXI",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -136,7 +440,7 @@
"dataFileName": "7_Geo map_image.png"
},
{
- "attachmentId": "gFR2Izzp18LQ",
+ "attachmentId": "uYdb9wWf5Nuv",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -144,7 +448,7 @@
"dataFileName": "8_Geo map_image.png"
},
{
- "attachmentId": "PMqmCbNLlZOG",
+ "attachmentId": "GhHYO2LteDmZ",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -152,7 +456,7 @@
"dataFileName": "9_Geo map_image.png"
},
{
- "attachmentId": "pKdtiq4r0eFY",
+ "attachmentId": "viN50n5G4kB0",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -160,7 +464,7 @@
"dataFileName": "10_Geo map_image.png"
},
{
- "attachmentId": "FXRVvYpOxWyR",
+ "attachmentId": "mgwGrtQZjxxb",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -168,7 +472,7 @@
"dataFileName": "11_Geo map_image.png"
},
{
- "attachmentId": "42AncDs7SSAf",
+ "attachmentId": "PMqmCbNLlZOG",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -184,7 +488,7 @@
"dataFileName": "13_Geo map_image.png"
},
{
- "attachmentId": "FDP3JzIVSnuJ",
+ "attachmentId": "JULizn130rVI",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -192,7 +496,7 @@
"dataFileName": "14_Geo map_image.png"
},
{
- "attachmentId": "GhHYO2LteDmZ",
+ "attachmentId": "MdC0DpifJwu4",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -200,7 +504,7 @@
"dataFileName": "15_Geo map_image.png"
},
{
- "attachmentId": "J0baLTpafs7C",
+ "attachmentId": "gFR2Izzp18LQ",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -208,7 +512,7 @@
"dataFileName": "16_Geo map_image.png"
},
{
- "attachmentId": "uYdb9wWf5Nuv",
+ "attachmentId": "42AncDs7SSAf",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -216,7 +520,7 @@
"dataFileName": "17_Geo map_image.png"
},
{
- "attachmentId": "iSpyhQ5Ya6Nk",
+ "attachmentId": "pKdtiq4r0eFY",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -224,7 +528,7 @@
"dataFileName": "18_Geo map_image.png"
},
{
- "attachmentId": "MdC0DpifJwu4",
+ "attachmentId": "FXRVvYpOxWyR",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -237,13 +541,13 @@
},
{
"isClone": false,
- "noteId": "BDEpqZHDS51s",
+ "noteId": "BhLd0mxKn0gY",
"notePath": [
"OkOZllzB3fqN",
- "BDEpqZHDS51s"
+ "BhLd0mxKn0gY"
],
- "title": "Working with notes",
- "notePosition": 30,
+ "title": "Shared notes",
+ "notePosition": 100,
"prefix": null,
"isExpanded": false,
"type": "text",
@@ -251,17 +555,17 @@
"attributes": [],
"format": "html",
"attachments": [],
- "dirFileName": "Working with notes",
+ "dirFileName": "Shared notes",
"children": [
{
"isClone": false,
- "noteId": "13D1lOc9sqmZ",
+ "noteId": "1DtQ2mHreeOI",
"notePath": [
"OkOZllzB3fqN",
- "BDEpqZHDS51s",
- "13D1lOc9sqmZ"
+ "BhLd0mxKn0gY",
+ "1DtQ2mHreeOI"
],
- "title": "Exporting as PDF",
+ "title": "Serving directly the content of a note",
"notePosition": 10,
"prefix": null,
"isExpanded": false,
@@ -269,31 +573,23 @@
"mime": "text/html",
"attributes": [],
"format": "html",
- "dataFileName": "Exporting as PDF.html",
+ "dataFileName": "Serving directly the content o.html",
"attachments": [
{
- "attachmentId": "b3v1pLE6TF1Y",
+ "attachmentId": "2zgbdi7zMieM",
"title": "image.png",
"role": "image",
- "mime": "image/png",
+ "mime": "image/jpg",
"position": 10,
- "dataFileName": "Exporting as PDF_image.png"
+ "dataFileName": "Serving directly the conte.png"
},
{
- "attachmentId": "xsGM34t8ssKV",
+ "attachmentId": "DsKDaFOcumH6",
"title": "image.png",
"role": "image",
- "mime": "image/png",
+ "mime": "image/jpg",
"position": 10,
- "dataFileName": "1_Exporting as PDF_image.png"
- },
- {
- "attachmentId": "cvyes4f1Vhmm",
- "title": "image.png",
- "role": "image",
- "mime": "image/png",
- "position": 10,
- "dataFileName": "2_Exporting as PDF_image.png"
+ "dataFileName": "1_Serving directly the conte.png"
}
]
}
@@ -301,28 +597,89 @@
},
{
"isClone": false,
- "noteId": "XUG1egT28FBk",
+ "noteId": "LTnkDnYmmZ7s",
"notePath": [
"OkOZllzB3fqN",
- "XUG1egT28FBk"
+ "LTnkDnYmmZ7s"
],
- "title": "Power users",
- "notePosition": 50,
+ "title": "Scripting",
+ "notePosition": 110,
"prefix": null,
- "isExpanded": true,
+ "isExpanded": false,
"type": "text",
"mime": "text/html",
"attributes": [],
"format": "html",
"attachments": [],
- "dirFileName": "Power users",
+ "dirFileName": "Scripting",
+ "children": [
+ {
+ "isClone": false,
+ "noteId": "cTWlUHkiv1fB",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "LTnkDnYmmZ7s",
+ "cTWlUHkiv1fB"
+ ],
+ "title": "Examples",
+ "notePosition": 10,
+ "prefix": null,
+ "isExpanded": true,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "attachments": [],
+ "dirFileName": "Examples",
+ "children": [
+ {
+ "isClone": false,
+ "noteId": "g5Vta7jt3aq3",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "LTnkDnYmmZ7s",
+ "cTWlUHkiv1fB",
+ "g5Vta7jt3aq3"
+ ],
+ "title": "Downloading responses from Google Forms",
+ "notePosition": 10,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "dataFileName": "Downloading responses from Goo.html",
+ "attachments": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "isClone": false,
+ "noteId": "m4Paddd5qnnQ",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "m4Paddd5qnnQ"
+ ],
+ "title": "Advanced usage",
+ "notePosition": 120,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "attachments": [],
+ "dirFileName": "Advanced usage",
"children": [
{
"isClone": false,
"noteId": "DtJJ20yEozPA",
"notePath": [
"OkOZllzB3fqN",
- "XUG1egT28FBk",
+ "m4Paddd5qnnQ",
"DtJJ20yEozPA"
],
"title": "Theme development",
@@ -349,7 +706,7 @@
"noteId": "5HH79ztN0fZA",
"notePath": [
"OkOZllzB3fqN",
- "XUG1egT28FBk",
+ "m4Paddd5qnnQ",
"DtJJ20yEozPA",
"5HH79ztN0fZA"
],
@@ -372,7 +729,7 @@
"dataFileName": "Creating a custom theme.html",
"attachments": [
{
- "attachmentId": "bn93hwF7C8sR",
+ "attachmentId": "AJHVfQtIQgJ7",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -380,7 +737,7 @@
"dataFileName": "Creating a custom theme_im.png"
},
{
- "attachmentId": "17p6z24yW5eP",
+ "attachmentId": "gXLyv5KXjfxg",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -388,7 +745,7 @@
"dataFileName": "1_Creating a custom theme_im.png"
},
{
- "attachmentId": "gXLyv5KXjfxg",
+ "attachmentId": "on1gD7BzCWdN",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -396,7 +753,7 @@
"dataFileName": "2_Creating a custom theme_im.png"
},
{
- "attachmentId": "AJHVfQtIQgJ7",
+ "attachmentId": "17p6z24yW5eP",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -404,7 +761,7 @@
"dataFileName": "3_Creating a custom theme_im.png"
},
{
- "attachmentId": "on1gD7BzCWdN",
+ "attachmentId": "K3cdwj8f90m0",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -412,7 +769,7 @@
"dataFileName": "4_Creating a custom theme_im.png"
},
{
- "attachmentId": "K3cdwj8f90m0",
+ "attachmentId": "bn93hwF7C8sR",
"title": "image.png",
"role": "image",
"mime": "image/png",
@@ -426,11 +783,11 @@
"noteId": "aH8Dk5aMiq7R",
"notePath": [
"OkOZllzB3fqN",
- "XUG1egT28FBk",
+ "m4Paddd5qnnQ",
"DtJJ20yEozPA",
"aH8Dk5aMiq7R"
],
- "title": "Theme base (legacy vs. next)",
+ "title": "Customize the Next theme",
"notePosition": 20,
"prefix": null,
"isExpanded": false,
@@ -438,23 +795,23 @@
"mime": "text/html",
"attributes": [],
"format": "html",
- "dataFileName": "Theme base (legacy vs. next).html",
+ "dataFileName": "Customize the Next theme.html",
"attachments": [
- {
- "attachmentId": "u0zkXkD7rGXA",
- "title": "image.png",
- "role": "image",
- "mime": "image/png",
- "position": 10,
- "dataFileName": "Theme base (legacy vs. nex.png"
- },
{
"attachmentId": "5z4bC0x0eH0P",
"title": "image.png",
"role": "image",
"mime": "image/png",
"position": 10,
- "dataFileName": "1_Theme base (legacy vs. nex.png"
+ "dataFileName": "Customize the Next theme_i.png"
+ },
+ {
+ "attachmentId": "u0zkXkD7rGXA",
+ "title": "image.png",
+ "role": "image",
+ "mime": "image/png",
+ "position": 10,
+ "dataFileName": "1_Customize the Next theme_i.png"
}
]
},
@@ -463,7 +820,7 @@
"noteId": "pMq6N1oBV9oo",
"notePath": [
"OkOZllzB3fqN",
- "XUG1egT28FBk",
+ "m4Paddd5qnnQ",
"DtJJ20yEozPA",
"pMq6N1oBV9oo"
],
@@ -473,12 +830,160 @@
"isExpanded": false,
"type": "text",
"mime": "text/html",
- "attributes": [],
+ "attributes": [
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "po38jIc0LD2H",
+ "isInheritable": false,
+ "position": 10
+ }
+ ],
"format": "html",
"dataFileName": "Reference.html",
"attachments": []
}
]
+ },
+ {
+ "isClone": false,
+ "noteId": "po38jIc0LD2H",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "m4Paddd5qnnQ",
+ "po38jIc0LD2H"
+ ],
+ "title": "Custom resource providers",
+ "notePosition": 20,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "dataFileName": "Custom resource providers.html",
+ "attachments": []
+ },
+ {
+ "isClone": false,
+ "noteId": "rGq9oI9hWwGf",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "m4Paddd5qnnQ",
+ "rGq9oI9hWwGf"
+ ],
+ "title": "REST API",
+ "notePosition": 30,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "attachments": [],
+ "dirFileName": "REST API",
+ "children": [
+ {
+ "isClone": false,
+ "noteId": "sztusxU10ADE",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "m4Paddd5qnnQ",
+ "rGq9oI9hWwGf",
+ "sztusxU10ADE"
+ ],
+ "title": "ETAPI",
+ "notePosition": 10,
+ "prefix": null,
+ "isExpanded": true,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "attachments": [],
+ "dirFileName": "ETAPI",
+ "children": [
+ {
+ "isClone": false,
+ "noteId": "f3xpgx6H01PW",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "m4Paddd5qnnQ",
+ "rGq9oI9hWwGf",
+ "sztusxU10ADE",
+ "f3xpgx6H01PW"
+ ],
+ "title": "API Reference",
+ "notePosition": 10,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "webView",
+ "mime": "",
+ "attributes": [
+ {
+ "type": "label",
+ "name": "webViewSrc",
+ "value": "/etapi/docs",
+ "isInheritable": false,
+ "position": 10
+ }
+ ],
+ "dataFileName": "API Reference.dat",
+ "attachments": []
+ }
+ ]
+ },
+ {
+ "isClone": false,
+ "noteId": "9OiEC6pf3Wfv",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "m4Paddd5qnnQ",
+ "rGq9oI9hWwGf",
+ "9OiEC6pf3Wfv"
+ ],
+ "title": "Internal API",
+ "notePosition": 20,
+ "prefix": null,
+ "isExpanded": true,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [],
+ "format": "html",
+ "attachments": [],
+ "dirFileName": "Internal API",
+ "children": [
+ {
+ "isClone": false,
+ "noteId": "7uB5k0iCmOtZ",
+ "notePath": [
+ "OkOZllzB3fqN",
+ "m4Paddd5qnnQ",
+ "rGq9oI9hWwGf",
+ "9OiEC6pf3Wfv",
+ "7uB5k0iCmOtZ"
+ ],
+ "title": "API Reference",
+ "notePosition": 10,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "webView",
+ "mime": "",
+ "attributes": [
+ {
+ "type": "label",
+ "name": "webViewSrc",
+ "value": "/api/docs",
+ "isInheritable": false,
+ "position": 10
+ }
+ ],
+ "dataFileName": "API Reference.dat",
+ "attachments": []
+ }
+ ]
+ }
+ ]
}
]
}
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Custom resource providers.html b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Custom resource providers.html
new file mode 100644
index 000000000..e847d0808
--- /dev/null
+++ b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Custom resource providers.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+ Custom resource providers
+
+
+
+
+
Custom resource providers
+
+
+
A custom resource provider allows any file imported into Trilium (images,
+ fonts, stylesheets) to be publicly accessible via a URL.
+
A potential use case for this is to add embed a custom font alongside
+ a theme.
+
Steps for creating a custom resource provider
+
+ Import a file such as an image or a font into Trilium by drag & drop.
+ Select the file and go to the Owned Attributes section.
+ Add the label #customResourceProvider=hello
.
+ To test if it is working, use a browser to navigate to <protocol>://<host>/custom/hello
(where <protocol>
is
+ either http
or https
based on your setup, and <host>
is
+ the host or IP to your Trilium server instance). If you are running the
+ TriliumNext application without a server, use http://localhost:37840
as
+ the base URL.
+ If everything went well, at the previous step the browser should have
+ downloaded the file uploaded in the first step.
+
+
Instead of hello
, the name can be:
+
+ A path, such as fonts/Roboto.ttf
, which would be accessible
+ via <host>/custom/fonts/Roboto.ttf
.
+ As a more advanced use case, a regular expression to match multiple routes,
+ such as hello/.*
which will be accessible via /custom/hello/1
, /custom/hello/2
, /custom/hello/world
,
+ etc.
+
+
Using it in a theme
+
For example, if you have a custom font to be imported by the theme, first
+ upload a font file into Trilium and assign it the #customResourceProvider=fonts/myfont.ttf
attribute.
+
Then modify the theme CSS to point to:
@font-face {
+ font-family: customFont;
+ src: url("/custom/fonts/myfont.ttf");
+}
+
+div {
+ font-family: customFont;
+}
+
+
+
+
+
\ No newline at end of file
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/REST API/ETAPI/API Reference.dat b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/REST API/ETAPI/API Reference.dat
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/REST API/Internal API/API Reference.dat b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/REST API/Internal API/API Reference.dat
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/2_Creating a custom theme_im.png b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/1_Creating a custom theme_im.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/2_Creating a custom theme_im.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/1_Creating a custom theme_im.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Theme base (legacy vs. nex.png b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/1_Customize the Next theme_i.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Theme base (legacy vs. nex.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/1_Customize the Next theme_i.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/4_Creating a custom theme_im.png b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/2_Creating a custom theme_im.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/4_Creating a custom theme_im.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/2_Creating a custom theme_im.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/1_Creating a custom theme_im.png b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/3_Creating a custom theme_im.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/1_Creating a custom theme_im.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/3_Creating a custom theme_im.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/5_Creating a custom theme_im.png b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/4_Creating a custom theme_im.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/5_Creating a custom theme_im.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/4_Creating a custom theme_im.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Creating a custom theme_im.png b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/5_Creating a custom theme_im.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Creating a custom theme_im.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/5_Creating a custom theme_im.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Creating a custom theme.html b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Creating a custom theme.html
similarity index 87%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Creating a custom theme.html
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Creating a custom theme.html
index e4d1eeda4..d2dc5fea7 100644
--- a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Creating a custom theme.html
+++ b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Creating a custom theme.html
@@ -19,7 +19,7 @@
keep them into one place.
As such, the first step is to create a new note to gather all the themes.
-
+
Step 2. Create the theme
@@ -32,7 +32,7 @@
-
@@ -42,7 +42,7 @@
-
@@ -51,7 +51,7 @@
-
@@ -72,15 +72,15 @@
Refresh the application (Ctrl+Shift+R is a good way to do so) and go to
settings. You should see the newly created theme:
-
+
Afterwards the application will refresh itself with the new theme:
-
+
Do note that the theme will be based off of the legacy theme. To override
that and base the theme on the new TriliumNext theme, see: Theme base (legacy vs. next)
+ href="Customize%20the%20Next%20theme.html">Theme base (legacy vs. next)
Step 5. Making changes
Simply go back to the note and change according to needs. To apply the
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/3_Creating a custom theme_im.png b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Creating a custom theme_im.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/3_Creating a custom theme_im.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Creating a custom theme_im.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Theme base (legacy vs. next).html b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Customize the Next theme.html
similarity index 78%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Theme base (legacy vs. next).html
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Customize the Next theme.html
index d392deed4..cd0a47f0b 100644
--- a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Theme base (legacy vs. next).html
+++ b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Customize the Next theme.html
@@ -5,20 +5,20 @@
-
Theme base (legacy vs. next)
+ Customize the Next theme
-
Theme base (legacy vs. next)
+
Customize the Next theme
By default, any custom theme will be based on the legacy light theme.
- To change the TriliumNext theme instead, add the #appThemeBase=next
attribute
+ To use the TriliumNext theme instead, add the #appThemeBase=next
attribute
onto the existing theme. The appTheme
attribute must also be
present.
-
+
When appThemeBase
is set to next
it will use the
“TriliumNext (auto)” theme. Any other value is ignored and will use the
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/1_Theme base (legacy vs. nex.png b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Customize the Next theme_i.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/1_Theme base (legacy vs. nex.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Customize the Next theme_i.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Reference.html b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Reference.html
similarity index 93%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Reference.html
rename to src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Reference.html
index 13af6494e..e858513c1 100644
--- a/src/public/app/doc_notes/en/User Guide/User Guide/Power users/Theme development/Reference.html
+++ b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Reference.html
@@ -122,6 +122,11 @@ body.electron:not(.native-titlebar) {
height: 3px;
background-color: var(--workspace-tab-background-color);
}
+
Custom fonts
+
Currently the only way to include a custom font is to use Custom resource providers .
+ Basically import a font into Trilium and assign it #customResourceProvider=fonts/myfont.ttf
and
+ then import the font in CSS via /custom/fonts/myfont.ttf
.
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Working with notes/2_Exporting as PDF_image.png b/src/public/app/doc_notes/en/User Guide/User Guide/Features/1_Export as PDF_image.png
similarity index 100%
rename from src/public/app/doc_notes/en/User Guide/User Guide/Working with notes/2_Exporting as PDF_image.png
rename to src/public/app/doc_notes/en/User Guide/User Guide/Features/1_Export as PDF_image.png
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Features/1_Zen mode_image.png b/src/public/app/doc_notes/en/User Guide/User Guide/Features/1_Zen mode_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1a3e812421f1ef2c6b2fadd76e71301dba8bc1e
GIT binary patch
literal 8584
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
wg@R*AMLUmnr~PY+e@w&s*8to25(9
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
literal 0
HcmV?d00001
diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Features/3_Zen mode_image.png b/src/public/app/doc_notes/en/User Guide/User Guide/Features/3_Zen mode_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..530d76afb9211de27de97d04f006ee9d156cdb91
GIT binary patch
literal 25929
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