From 50b0dc178e6c75ccdb84f604418dfa673a048dcd Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 09:27:56 +0200 Subject: [PATCH 01/21] chore(regroup): clean up old ETAPI tests They are already integrated in apps/server/spec/etapi. --- _regroup/spec/etapi/app_info.ts | 9 -- _regroup/spec/etapi/backup.ts | 10 --- _regroup/spec/etapi/import.ts | 26 ------ _regroup/spec/etapi/notes.ts | 103 ---------------------- _regroup/spec/support/etapi.ts | 152 -------------------------------- 5 files changed, 300 deletions(-) delete mode 100644 _regroup/spec/etapi/app_info.ts delete mode 100644 _regroup/spec/etapi/backup.ts delete mode 100644 _regroup/spec/etapi/import.ts delete mode 100644 _regroup/spec/etapi/notes.ts delete mode 100644 _regroup/spec/support/etapi.ts diff --git a/_regroup/spec/etapi/app_info.ts b/_regroup/spec/etapi/app_info.ts deleted file mode 100644 index 9c510d99b..000000000 --- a/_regroup/spec/etapi/app_info.ts +++ /dev/null @@ -1,9 +0,0 @@ -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"); - }); -}); -*/ diff --git a/_regroup/spec/etapi/backup.ts b/_regroup/spec/etapi/backup.ts deleted file mode 100644 index 924213f0e..000000000 --- a/_regroup/spec/etapi/backup.ts +++ /dev/null @@ -1,10 +0,0 @@ -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); - }); -}); -*/ diff --git a/_regroup/spec/etapi/import.ts b/_regroup/spec/etapi/import.ts deleted file mode 100644 index 36782a26a..000000000 --- a/_regroup/spec/etapi/import.ts +++ /dev/null @@ -1,26 +0,0 @@ -import etapi from "../support/etapi.js"; -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 () => { - const scriptDir = path.dirname(fileURLToPath(import.meta.url)); - - const zipFileBuffer = fs.readFileSync(path.resolve(scriptDir, "test-export.zip")); - - const response = await etapi.postEtapiContent("notes/root/import", zipFileBuffer); - expect(response.status).toEqual(201); - - const { note, branch } = await response.json(); - - expect(note.title).toEqual("test-export"); - expect(branch.parentNoteId).toEqual("root"); - - const content = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text(); - expect(content).toContain("test export content"); - }); -}); -*/ diff --git a/_regroup/spec/etapi/notes.ts b/_regroup/spec/etapi/notes.ts deleted file mode 100644 index d5c9b680c..000000000 --- a/_regroup/spec/etapi/notes.ts +++ /dev/null @@ -1,103 +0,0 @@ -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", { - parentNoteId: "root", - type: "text", - title: "Hello World!", - content: "Content", - prefix: "Custom prefix" - }); - - expect(note.title).toEqual("Hello World!"); - expect(branch.parentNoteId).toEqual("root"); - expect(branch.prefix).toEqual("Custom prefix"); - - const rNote = await etapi.getEtapi(`notes/${note.noteId}`); - expect(rNote.title).toEqual("Hello World!"); - - const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text(); - expect(rContent).toEqual("Content"); - - const rBranch = await etapi.getEtapi(`branches/${branch.branchId}`); - expect(rBranch.parentNoteId).toEqual("root"); - expect(rBranch.prefix).toEqual("Custom prefix"); - }); - - it("patch", async () => { - const { note } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "text", - title: "Hello World!", - content: "Content" - }); - - await etapi.patchEtapi(`notes/${note.noteId}`, { - title: "new title", - type: "code", - mime: "text/apl", - dateCreated: "2000-01-01 12:34:56.999+0200", - utcDateCreated: "2000-01-01 10:34:56.999Z" - }); - - const rNote = await etapi.getEtapi(`notes/${note.noteId}`); - expect(rNote.title).toEqual("new title"); - expect(rNote.type).toEqual("code"); - expect(rNote.mime).toEqual("text/apl"); - expect(rNote.dateCreated).toEqual("2000-01-01 12:34:56.999+0200"); - expect(rNote.utcDateCreated).toEqual("2000-01-01 10:34:56.999Z"); - }); - - it("update content", async () => { - const { note } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "text", - title: "Hello World!", - content: "Content" - }); - - await etapi.putEtapiContent(`notes/${note.noteId}/content`, "new content"); - - const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text(); - expect(rContent).toEqual("new content"); - }); - - it("create / update binary content", async () => { - const { note } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "file", - title: "Hello World!", - content: "ZZZ" - }); - - const updatedContent = crypto.randomBytes(16); - - await etapi.putEtapiContent(`notes/${note.noteId}/content`, updatedContent); - - const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).arrayBuffer(); - expect(Buffer.from(new Uint8Array(rContent))).toEqual(updatedContent); - }); - - it("delete note", async () => { - const { note } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "text", - title: "Hello World!", - content: "Content" - }); - - await etapi.deleteEtapi(`notes/${note.noteId}`); - - const resp = await etapi.getEtapiResponse(`notes/${note.noteId}`); - expect(resp.status).toEqual(404); - - const error = await resp.json(); - expect(error.status).toEqual(404); - expect(error.code).toEqual("NOTE_NOT_FOUND"); - expect(error.message).toEqual(`Note '${note.noteId}' not found.`); - }); -}); -*/ diff --git a/_regroup/spec/support/etapi.ts b/_regroup/spec/support/etapi.ts deleted file mode 100644 index b32ba38e7..000000000 --- a/_regroup/spec/support/etapi.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { describe, beforeAll, afterAll } from "vitest"; - -let etapiAuthToken: string | undefined; - -const getEtapiAuthorizationHeader = (): string => "Basic " + Buffer.from(`etapi:${etapiAuthToken}`).toString("base64"); - -const PORT: string = "9999"; -const HOST: string = "http://localhost:" + PORT; - -type SpecDefinitionsFunc = () => void; - -function describeEtapi(description: string, specDefinitions: SpecDefinitionsFunc): void { - describe(description, () => { - beforeAll(async () => {}); - - afterAll(() => {}); - - specDefinitions(); - }); -} - -async function getEtapiResponse(url: string): Promise { - return await fetch(`${HOST}/etapi/${url}`, { - method: "GET", - headers: { - Authorization: getEtapiAuthorizationHeader() - } - }); -} - -async function getEtapi(url: string): Promise { - const response = await getEtapiResponse(url); - return await processEtapiResponse(response); -} - -async function getEtapiContent(url: string): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "GET", - headers: { - Authorization: getEtapiAuthorizationHeader() - } - }); - - checkStatus(response); - - return response; -} - -async function postEtapi(url: string, data: Record = {}): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: getEtapiAuthorizationHeader() - }, - body: JSON.stringify(data) - }); - return await processEtapiResponse(response); -} - -async function postEtapiContent(url: string, data: BodyInit): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "POST", - headers: { - "Content-Type": "application/octet-stream", - Authorization: getEtapiAuthorizationHeader() - }, - body: data - }); - - checkStatus(response); - - return response; -} - -async function putEtapi(url: string, data: Record = {}): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "PUT", - headers: { - "Content-Type": "application/json", - Authorization: getEtapiAuthorizationHeader() - }, - body: JSON.stringify(data) - }); - return await processEtapiResponse(response); -} - -async function putEtapiContent(url: string, data?: BodyInit): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "PUT", - headers: { - "Content-Type": "application/octet-stream", - Authorization: getEtapiAuthorizationHeader() - }, - body: data - }); - - checkStatus(response); - - return response; -} - -async function patchEtapi(url: string, data: Record = {}): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - Authorization: getEtapiAuthorizationHeader() - }, - body: JSON.stringify(data) - }); - return await processEtapiResponse(response); -} - -async function deleteEtapi(url: string): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "DELETE", - headers: { - Authorization: getEtapiAuthorizationHeader() - } - }); - return await processEtapiResponse(response); -} - -async function processEtapiResponse(response: Response): Promise { - const text = await response.text(); - - if (response.status < 200 || response.status >= 300) { - throw new Error(`ETAPI error ${response.status}: ${text}`); - } - - return text?.trim() ? JSON.parse(text) : null; -} - -function checkStatus(response: Response): void { - if (response.status < 200 || response.status >= 300) { - throw new Error(`ETAPI error ${response.status}`); - } -} - -export default { - describeEtapi, - getEtapi, - getEtapiResponse, - getEtapiContent, - postEtapi, - postEtapiContent, - putEtapi, - putEtapiContent, - patchEtapi, - deleteEtapi -}; From 264b75cd68cdeaa43be5bb88fda76e4376658323 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 09:43:02 +0200 Subject: [PATCH 02/21] chore(regroup): clean up migration scripts --- scripts/repo-migration/README.md | 13 +++++++++++++ scripts/{ => repo-migration}/migrate-releases.js | 0 .../repo-migration/migrated-discussions.txt | 0 scripts/{ => repo-migration}/migrated-issues.txt | 0 scripts/{ => repo-migration}/port-discussions.ts | 0 scripts/{ => repo-migration}/port-issues.ts | 0 6 files changed, 13 insertions(+) create mode 100644 scripts/repo-migration/README.md rename scripts/{ => repo-migration}/migrate-releases.js (100%) rename port-discussions.log => scripts/repo-migration/migrated-discussions.txt (100%) rename scripts/{ => repo-migration}/migrated-issues.txt (100%) rename scripts/{ => repo-migration}/port-discussions.ts (100%) rename scripts/{ => repo-migration}/port-issues.ts (100%) diff --git a/scripts/repo-migration/README.md b/scripts/repo-migration/README.md new file mode 100644 index 000000000..3266b69dd --- /dev/null +++ b/scripts/repo-migration/README.md @@ -0,0 +1,13 @@ +# Repo migration scripts + +> [!NOTE] +> These scripts were designed to be single use only, since they took care of migrating between repos. As such, they are not actively maintained and are to be used for reference only. + +These scripts were used in the process of migrating from the forked [Notes](https://github.com/TriliumNext/Notes) repo to the original [Trilium](https://github.com/TriliumNext/Trilium) repo. +Since Git only migrates the code and not the GitHub-specific data, we had to create scripts that handle the migration of: + +* Issues, using the "Transfer" function for each issue (via `gh cli`). + * The migration logs are available in `migrated-issues.txt`. +* Discussions, which transferred each discussion from the original repo. This one is a bit more complicated (and potentially flaky) since it works via playwright, by manually selecting the "Transfer" function (no API available at the time). + * The migration logs are available in`migrated-discussions.txt`. +* Releases, by manually downloading the assets from the source repo and creating new releases into the destination repo. \ No newline at end of file diff --git a/scripts/migrate-releases.js b/scripts/repo-migration/migrate-releases.js similarity index 100% rename from scripts/migrate-releases.js rename to scripts/repo-migration/migrate-releases.js diff --git a/port-discussions.log b/scripts/repo-migration/migrated-discussions.txt similarity index 100% rename from port-discussions.log rename to scripts/repo-migration/migrated-discussions.txt diff --git a/scripts/migrated-issues.txt b/scripts/repo-migration/migrated-issues.txt similarity index 100% rename from scripts/migrated-issues.txt rename to scripts/repo-migration/migrated-issues.txt diff --git a/scripts/port-discussions.ts b/scripts/repo-migration/port-discussions.ts similarity index 100% rename from scripts/port-discussions.ts rename to scripts/repo-migration/port-discussions.ts diff --git a/scripts/port-issues.ts b/scripts/repo-migration/port-issues.ts similarity index 100% rename from scripts/port-issues.ts rename to scripts/repo-migration/port-issues.ts From 44c0028a51c3cbd736878f9b86d4ce56ad9698a3 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 09:43:54 +0200 Subject: [PATCH 03/21] chore(regroup): clean up translation scripts --- .../bin/translation.sh => scripts/translation/create-po-file.sh | 0 scripts/{ => translation}/import-translations-from-weblate-csv.ts | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename _regroup/bin/translation.sh => scripts/translation/create-po-file.sh (100%) rename scripts/{ => translation}/import-translations-from-weblate-csv.ts (100%) diff --git a/_regroup/bin/translation.sh b/scripts/translation/create-po-file.sh similarity index 100% rename from _regroup/bin/translation.sh rename to scripts/translation/create-po-file.sh diff --git a/scripts/import-translations-from-weblate-csv.ts b/scripts/translation/import-translations-from-weblate-csv.ts similarity index 100% rename from scripts/import-translations-from-weblate-csv.ts rename to scripts/translation/import-translations-from-weblate-csv.ts From 25e37ddd78e8939f5c0650ca391a4ae7a60a1901 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 10:07:23 +0200 Subject: [PATCH 04/21] chore(regroup): relocate icon scripts --- {_regroup/bin => scripts/icons}/create-icons.sh | 0 {_regroup/bin/tray-icons => scripts/icons/tray}/bookmarks.svg | 0 {_regroup/bin/tray-icons => scripts/icons/tray}/build-icons.sh | 0 {_regroup/bin/tray-icons => scripts/icons/tray}/close.svg | 0 {_regroup/bin/tray-icons => scripts/icons/tray}/new-note.svg | 0 {_regroup/bin/tray-icons => scripts/icons/tray}/recents.svg | 0 {_regroup/bin/tray-icons => scripts/icons/tray}/today.svg | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename {_regroup/bin => scripts/icons}/create-icons.sh (100%) rename {_regroup/bin/tray-icons => scripts/icons/tray}/bookmarks.svg (100%) rename {_regroup/bin/tray-icons => scripts/icons/tray}/build-icons.sh (100%) rename {_regroup/bin/tray-icons => scripts/icons/tray}/close.svg (100%) rename {_regroup/bin/tray-icons => scripts/icons/tray}/new-note.svg (100%) rename {_regroup/bin/tray-icons => scripts/icons/tray}/recents.svg (100%) rename {_regroup/bin/tray-icons => scripts/icons/tray}/today.svg (100%) diff --git a/_regroup/bin/create-icons.sh b/scripts/icons/create-icons.sh similarity index 100% rename from _regroup/bin/create-icons.sh rename to scripts/icons/create-icons.sh diff --git a/_regroup/bin/tray-icons/bookmarks.svg b/scripts/icons/tray/bookmarks.svg similarity index 100% rename from _regroup/bin/tray-icons/bookmarks.svg rename to scripts/icons/tray/bookmarks.svg diff --git a/_regroup/bin/tray-icons/build-icons.sh b/scripts/icons/tray/build-icons.sh similarity index 100% rename from _regroup/bin/tray-icons/build-icons.sh rename to scripts/icons/tray/build-icons.sh diff --git a/_regroup/bin/tray-icons/close.svg b/scripts/icons/tray/close.svg similarity index 100% rename from _regroup/bin/tray-icons/close.svg rename to scripts/icons/tray/close.svg diff --git a/_regroup/bin/tray-icons/new-note.svg b/scripts/icons/tray/new-note.svg similarity index 100% rename from _regroup/bin/tray-icons/new-note.svg rename to scripts/icons/tray/new-note.svg diff --git a/_regroup/bin/tray-icons/recents.svg b/scripts/icons/tray/recents.svg similarity index 100% rename from _regroup/bin/tray-icons/recents.svg rename to scripts/icons/tray/recents.svg diff --git a/_regroup/bin/tray-icons/today.svg b/scripts/icons/tray/today.svg similarity index 100% rename from _regroup/bin/tray-icons/today.svg rename to scripts/icons/tray/today.svg From 4a749f52e949888882ef8c515a41fbc7d93e0b0d Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 10:11:28 +0200 Subject: [PATCH 05/21] chore(regroup): remove old release scripts --- _regroup/bin/push-docker-image.sh | 16 --------- _regroup/bin/release-flatpack.sh | 57 ------------------------------- _regroup/bin/release.sh | 49 -------------------------- 3 files changed, 122 deletions(-) delete mode 100644 _regroup/bin/push-docker-image.sh delete mode 100644 _regroup/bin/release-flatpack.sh delete mode 100644 _regroup/bin/release.sh diff --git a/_regroup/bin/push-docker-image.sh b/_regroup/bin/push-docker-image.sh deleted file mode 100644 index 0372143cf..000000000 --- a/_regroup/bin/push-docker-image.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -if [[ $# -eq 0 ]] ; then - echo "Missing argument of new version" - exit 1 -fi - -VERSION=$1 -SERIES=${VERSION:0:4}-latest - -docker push zadam/trilium:$VERSION -docker push zadam/trilium:$SERIES - -if [[ $1 != *"beta"* ]]; then - docker push zadam/trilium:latest -fi diff --git a/_regroup/bin/release-flatpack.sh b/_regroup/bin/release-flatpack.sh deleted file mode 100644 index 31e42881b..000000000 --- a/_regroup/bin/release-flatpack.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash - -if [[ $# -eq 0 ]] ; then - echo "Missing argument of new version" - exit 1 -fi - -VERSION=$1 - -if ! [[ ${VERSION} =~ ^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}(-.+)?$ ]] ; -then - echo "Version ${VERSION} isn't in format X.Y.Z" - exit 1 -fi - -VERSION_DATE=$(git log -1 --format=%aI "v${VERSION}" | cut -c -10) -VERSION_COMMIT=$(git rev-list -n 1 "v${VERSION}") - -# expecting the directory at a specific path -cd ~/trilium-flathub || exit - -if ! git diff-index --quiet HEAD --; then - echo "There are uncommitted changes" - exit 1 -fi - -BASE_BRANCH=main - -if [[ "$VERSION" == *"beta"* ]]; then - BASE_BRANCH=beta -fi - -git switch "${BASE_BRANCH}" -git pull - -BRANCH=b${VERSION} - -git branch "${BRANCH}" -git switch "${BRANCH}" - -echo "Updating files with version ${VERSION}, date ${VERSION_DATE} and commit ${VERSION_COMMIT}" - -flatpak-node-generator npm ../trilium/package-lock.json - -xmlstarlet ed --inplace --update "/component/releases/release/@version" --value "${VERSION}" --update "/component/releases/release/@date" --value "${VERSION_DATE}" ./com.github.zadam.trilium.metainfo.xml - -yq --inplace "(.modules[0].sources[0].tag = \"v${VERSION}\") | (.modules[0].sources[0].commit = \"${VERSION_COMMIT}\")" ./com.github.zadam.trilium.yml - -git add ./generated-sources.json -git add ./com.github.zadam.trilium.metainfo.xml -git add ./com.github.zadam.trilium.yml - -git commit -m "release $VERSION" -git push --set-upstream origin "${BRANCH}" - -gh pr create --fill -B "${BASE_BRANCH}" -gh pr merge --auto --merge --delete-branch diff --git a/_regroup/bin/release.sh b/_regroup/bin/release.sh deleted file mode 100644 index fe9a65a36..000000000 --- a/_regroup/bin/release.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if [[ $# -eq 0 ]] ; then - echo "Missing argument of new version" - exit 1 -fi - -if ! command -v jq &> /dev/null; then - echo "Missing command: jq" - exit 1 -fi - -VERSION=$1 - -if ! [[ ${VERSION} =~ ^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}(-.+)?$ ]] ; -then - echo "Version ${VERSION} isn't in format X.Y.Z" - exit 1 -fi - -if ! git diff-index --quiet HEAD --; then - echo "There are uncommitted changes" - exit 1 -fi - -echo "Releasing Trilium $VERSION" - -jq '.version = "'$VERSION'"' package.json > package.json.tmp -mv package.json.tmp package.json - -git add package.json - -npm run chore:update-build-info - -git add src/services/build.ts - -TAG=v$VERSION - -echo "Committing package.json version change" - -git commit -m "chore(release): $VERSION" -git push - -echo "Tagging commit with $TAG" - -git tag $TAG -git push origin $TAG From 81bc85b8e42776a50c2fd02127ec7abe886d42e3 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 10:29:08 +0200 Subject: [PATCH 06/21] chore(regroup): adapt export-schema script --- _regroup/bin/export-schema.sh | 7 ------- apps/server/scripts/export-schema.sh | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 7 deletions(-) delete mode 100644 _regroup/bin/export-schema.sh create mode 100755 apps/server/scripts/export-schema.sh diff --git a/_regroup/bin/export-schema.sh b/_regroup/bin/export-schema.sh deleted file mode 100644 index ab5de1a81..000000000 --- a/_regroup/bin/export-schema.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -SCHEMA_FILE_PATH=db/schema.sql - -sqlite3 ./data/document.db .schema | grep -v "sqlite_sequence" > "$SCHEMA_FILE_PATH" - -echo "DB schema exported to $SCHEMA_FILE_PATH" \ No newline at end of file diff --git a/apps/server/scripts/export-schema.sh b/apps/server/scripts/export-schema.sh new file mode 100755 index 000000000..c93adee0c --- /dev/null +++ b/apps/server/scripts/export-schema.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(realpath $(dirname $0)) +DB_FILE_PATH="$SCRIPT_DIR/../data/document.db" +SCHEMA_FILE_PATH="$SCRIPT_DIR/../src/assets/db/schema.sql" + +if ! command -v sqlite3 &> /dev/null; then + echo "Missing command: sqlite3" + exit 1 +fi + +sqlite3 "$DB_FILE_PATH" .schema | grep -v "sqlite_sequence" > "$SCHEMA_FILE_PATH" + +echo "DB schema exported to $SCHEMA_FILE_PATH" \ No newline at end of file From ebb1a3feb22f20c43be843b14e59db04cc6fc7ab Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 10:35:57 +0200 Subject: [PATCH 07/21] chore(regroup): integrate generate_document --- apps/server/package.json | 4 +- .../server/scripts}/generate_document.ts | 6 +- pnpm-lock.yaml | 98 +++++++++++++++++-- 3 files changed, 94 insertions(+), 14 deletions(-) rename {_regroup/bin => apps/server/scripts}/generate_document.ts (93%) diff --git a/apps/server/package.json b/apps/server/package.json index 1c313248b..10705f8dd 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -22,7 +22,8 @@ "docker-start-debian": "pnpm docker-build-debian && docker run -p 8081:8080 triliumnext-debian", "docker-start-alpine": "pnpm docker-build-alpine && docker run -p 8081:8080 triliumnext-alpine", "docker-start-rootless-debian": "pnpm docker-build-rootless-debian && docker run -p 8081:8080 triliumnext-rootless-debian", - "docker-start-rootless-alpine": "pnpm docker-build-rootless-alpine && docker run -p 8081:8080 triliumnext-rootless-alpine" + "docker-start-rootless-alpine": "pnpm docker-build-rootless-alpine && docker run -p 8081:8080 triliumnext-rootless-alpine", + "generate-document": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=data TRILIUM_RESOURCE_DIR=src tsx ./scripts/generate_document.ts" }, "dependencies": { "better-sqlite3": "12.5.0", @@ -102,6 +103,7 @@ "is-animated": "2.0.2", "is-svg": "6.1.0", "jimp": "1.6.0", + "lorem-ipsum": "2.0.8", "marked": "17.0.1", "mime-types": "3.0.2", "multer": "2.0.2", diff --git a/_regroup/bin/generate_document.ts b/apps/server/scripts/generate_document.ts similarity index 93% rename from _regroup/bin/generate_document.ts rename to apps/server/scripts/generate_document.ts index 793efc105..8e4dd7227 100644 --- a/_regroup/bin/generate_document.ts +++ b/apps/server/scripts/generate_document.ts @@ -60,13 +60,13 @@ async function start() { const parentNoteId = getRandomNoteId(); const prefix = Math.random() > 0.8 ? "prefix" : ""; - const result = await cloningService.cloneNoteToBranch(noteIdToClone, parentNoteId, prefix); + const result = cloningService.cloneNoteToBranch(noteIdToClone, parentNoteId, prefix); console.log(`Cloning ${i}:`, result.success ? "succeeded" : "FAILED"); } // does not have to be for the current note - await attributeService.createAttribute({ + attributeService.createAttribute({ noteId: getRandomNoteId(), type: "label", name: "label", @@ -74,7 +74,7 @@ async function start() { isInheritable: Math.random() > 0.1 // 10% are inheritable }); - await attributeService.createAttribute({ + attributeService.createAttribute({ noteId: getRandomNoteId(), type: "relation", name: "relation", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa22a961b..a04e794e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -705,6 +705,9 @@ importers: jimp: specifier: 1.6.0 version: 1.6.0 + lorem-ipsum: + specifier: 2.0.8 + version: 2.0.8 marked: specifier: 17.0.1 version: 17.0.1 @@ -9724,6 +9727,11 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lorem-ipsum@2.0.8: + resolution: {integrity: sha512-5RIwHuCb979RASgCJH0VKERn9cQo/+NcAi2BMe9ddj+gp7hujl6BI+qdOG4nVsLDpwWEJwTVYXNKP6BGgbcoGA==} + engines: {node: '>= 8.x', npm: '>= 5.x'} + hasBin: true + lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} @@ -14997,6 +15005,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-autoformat@47.3.0': dependencies: @@ -15006,6 +15016,8 @@ snapshots: '@ckeditor/ckeditor5-typing': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-autosave@47.3.0': dependencies: @@ -15013,6 +15025,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-basic-styles@47.3.0': dependencies: @@ -15022,6 +15036,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-block-quote@47.3.0': dependencies: @@ -15032,6 +15048,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-bookmark@47.3.0': dependencies: @@ -15066,6 +15084,8 @@ snapshots: blurhash: 2.0.5 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-ckfinder@47.3.0': dependencies: @@ -15075,6 +15095,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-clipboard@47.3.0': dependencies: @@ -15090,6 +15112,8 @@ snapshots: '@ckeditor/ckeditor5-core': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-code-block@47.3.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)': dependencies: @@ -15101,6 +15125,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-collaboration-core@47.3.0': dependencies: @@ -15119,6 +15145,8 @@ snapshots: ckeditor5: 47.3.0 diff: 8.0.2 luxon: 3.6.1 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-comments@47.3.0': dependencies: @@ -15141,6 +15169,8 @@ snapshots: ckeditor5: 47.3.0 ckeditor5-collaboration: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-core@47.3.0': dependencies: @@ -15149,8 +15179,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 '@ckeditor/ckeditor5-watchdog': 47.3.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-dev-build-tools@43.1.0(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)': dependencies: @@ -15266,6 +15294,8 @@ snapshots: '@ckeditor/ckeditor5-upload': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-editor-balloon@47.3.0': dependencies: @@ -15295,8 +15325,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-editor-inline@47.3.0': dependencies: @@ -15306,6 +15334,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-editor-multi-root@47.3.0': dependencies: @@ -15328,6 +15358,8 @@ snapshots: '@ckeditor/ckeditor5-table': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-emoji@47.3.0': dependencies: @@ -15364,6 +15396,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-undo': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-export-inline-styles@47.3.0': dependencies: @@ -15382,6 +15416,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-export-word@47.3.0': dependencies: @@ -15395,6 +15431,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-find-and-replace@47.3.0': dependencies: @@ -15457,6 +15495,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-highlight@47.3.0': dependencies: @@ -15465,6 +15505,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-horizontal-line@47.3.0': dependencies: @@ -15483,6 +15525,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 '@ckeditor/ckeditor5-widget': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-html-support@47.3.0': dependencies: @@ -15498,6 +15542,8 @@ snapshots: '@ckeditor/ckeditor5-widget': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-icons@47.3.0': {} @@ -15529,6 +15575,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-indent@47.3.0': dependencies: @@ -15540,6 +15588,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-inspector@5.0.0': {} @@ -15549,6 +15599,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-line-height@47.3.0': dependencies: @@ -15637,6 +15689,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 '@ckeditor/ckeditor5-widget': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-mention@47.3.0(patch_hash=5981fb59ba35829e4dff1d39cf771000f8a8fdfa7a34b51d8af9549541f2d62d)': dependencies: @@ -15646,6 +15700,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-merge-fields@47.3.0': dependencies: @@ -15658,6 +15714,8 @@ snapshots: '@ckeditor/ckeditor5-widget': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-minimap@47.3.0': dependencies: @@ -15666,6 +15724,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-operations-compressor@47.3.0': dependencies: @@ -15720,6 +15780,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 '@ckeditor/ckeditor5-widget': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-pagination@47.3.0': dependencies: @@ -15746,8 +15808,6 @@ snapshots: '@ckeditor/ckeditor5-paste-from-office': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-paste-from-office@47.3.0': dependencies: @@ -15755,8 +15815,6 @@ snapshots: '@ckeditor/ckeditor5-core': 47.3.0 '@ckeditor/ckeditor5-engine': 47.3.0 ckeditor5: 47.3.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-real-time-collaboration@47.3.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: @@ -15787,6 +15845,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-restricted-editing@47.3.0': dependencies: @@ -15813,6 +15873,8 @@ snapshots: ckeditor5-collaboration: 47.3.0 es-toolkit: 1.39.5 luxon: 3.6.1 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-select-all@47.3.0': dependencies: @@ -15829,6 +15891,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-slash-command@47.3.0': dependencies: @@ -15841,6 +15905,8 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-source-editing-enhanced@47.3.0': dependencies: @@ -15888,6 +15954,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-table@47.3.0': dependencies: @@ -15900,6 +15968,8 @@ snapshots: '@ckeditor/ckeditor5-widget': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-template@47.3.0': dependencies: @@ -15942,6 +16012,8 @@ snapshots: ckeditor5: 47.3.0 ckeditor5-collaboration: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-typing@47.3.0': dependencies: @@ -15972,8 +16044,6 @@ snapshots: '@ckeditor/ckeditor5-icons': 47.3.0 '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-upload@47.3.0': dependencies: @@ -16031,6 +16101,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@codemirror/autocomplete@6.18.6': dependencies: @@ -21360,6 +21432,8 @@ snapshots: ckeditor5-collaboration@47.3.0: dependencies: '@ckeditor/ckeditor5-collaboration-core': 47.3.0 + transitivePeerDependencies: + - supports-color ckeditor5-premium-features@47.3.0(bufferutil@4.0.9)(ckeditor5@47.3.0)(utf-8-validate@6.0.5): dependencies: @@ -25467,6 +25541,10 @@ snapshots: dependencies: js-tokens: 4.0.0 + lorem-ipsum@2.0.8: + dependencies: + commander: 9.5.0 + lowercase-keys@2.0.0: {} lru-cache@10.4.3: {} From ff08eadb23fcfe59197da4d4a0361a06d92c78b5 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 10:49:14 +0200 Subject: [PATCH 08/21] fix(server/scripts): generate-document failing (closes #5422) --- apps/server/scripts/generate_document.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/apps/server/scripts/generate_document.ts b/apps/server/scripts/generate_document.ts index 8e4dd7227..0b041ad26 100644 --- a/apps/server/scripts/generate_document.ts +++ b/apps/server/scripts/generate_document.ts @@ -6,10 +6,11 @@ import sqlInit from "../src/services/sql_init.js"; import noteService from "../src/services/notes.js"; import attributeService from "../src/services/attributes.js"; -import cls from "../src/services/cls.js"; import cloningService from "../src/services/cloning.js"; -import loremIpsum from "lorem-ipsum"; +import * as loremIpsum from "lorem-ipsum"; import "../src/becca/entity_constructor.js"; +import { initializeTranslations } from "../src/services/i18n.js"; +import cls from "../src/services/cls.js"; const noteCount = parseInt(process.argv[2]); @@ -27,6 +28,16 @@ function getRandomNoteId() { } async function start() { + if (!sqlInit.isDbInitialized()) { + console.error("Database not initialized."); + process.exit(1); + } + + await initializeTranslations(); + + sqlInit.initializeDb(); + await sqlInit.dbReady; + for (let i = 0; i < noteCount; i++) { const title = loremIpsum.loremIpsum({ count: 1, @@ -90,6 +101,4 @@ async function start() { process.exit(0); } -// @TriliumNextTODO sqlInit.dbReady never seems to resolve so program hangs -// see https://github.com/TriliumNext/Trilium/issues/1020 -sqlInit.dbReady.then(cls.wrap(start)).catch((err) => console.error(err)); +cls.init(() => start()); From 44506057fd92e1485dbf43267657c21225ef637e Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 10:50:42 +0200 Subject: [PATCH 09/21] chore(regroup): clean bin dir --- _regroup/bin/create-anonymization-script.ts | 7 ------- {_regroup/bin => apps/server/scripts}/generate-cert.sh | 0 2 files changed, 7 deletions(-) delete mode 100644 _regroup/bin/create-anonymization-script.ts rename {_regroup/bin => apps/server/scripts}/generate-cert.sh (100%) diff --git a/_regroup/bin/create-anonymization-script.ts b/_regroup/bin/create-anonymization-script.ts deleted file mode 100644 index ff462ec5e..000000000 --- a/_regroup/bin/create-anonymization-script.ts +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node - -import anonymizationService from "../src/services/anonymization.js"; -import fs from "fs"; -import path from "path"; - -fs.writeFileSync(path.resolve(__dirname, "tpl", "anonymize-database.sql"), anonymizationService.getFullAnonymizationScript()); diff --git a/_regroup/bin/generate-cert.sh b/apps/server/scripts/generate-cert.sh similarity index 100% rename from _regroup/bin/generate-cert.sh rename to apps/server/scripts/generate-cert.sh From e87a368e87b122a2fa83eb8f8fba2f6d83725ed2 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 10:52:41 +0200 Subject: [PATCH 10/21] chore(regroup): remove some redundant files --- _regroup/entitlements.plist | 10 ---------- _regroup/tsconfig.webpack.json | 22 ---------------------- 2 files changed, 32 deletions(-) delete mode 100644 _regroup/entitlements.plist delete mode 100644 _regroup/tsconfig.webpack.json diff --git a/_regroup/entitlements.plist b/_regroup/entitlements.plist deleted file mode 100644 index 040a4c1cb..000000000 --- a/_regroup/entitlements.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.cs.allow-jit - - com.apple.security.files.user-selected.read-write - - - \ No newline at end of file diff --git a/_regroup/tsconfig.webpack.json b/_regroup/tsconfig.webpack.json deleted file mode 100644 index ed622818b..000000000 --- a/_regroup/tsconfig.webpack.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "module": "NodeNext", - "declaration": false, - "sourceMap": true, - "outDir": "./build", - "strict": true, - "noImplicitAny": true, - "resolveJsonModule": true, - "lib": ["ES2023"], - "downlevelIteration": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowJs": true - }, - "include": ["./src/public/app/**/*"], - "files": [ - "./src/public/app/types.d.ts", - "./src/public/app/types-lib.d.ts", - "./src/types.d.ts" - ] -} From dfb9ce990d6c40081ceb9c16503f19fa85e93509 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 11:05:34 +0200 Subject: [PATCH 11/21] chore(eslint): basic config --- eslint.config.mjs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 eslint.config.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..3c6b57d2d --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,15 @@ +// @ts-check + +import eslint from '@eslint/js'; +import { defineConfig, globalIgnores } from 'eslint/config'; +import tseslint from 'typescript-eslint'; + +export default defineConfig( + globalIgnores([ + ".cache", + "tmp", + "**/dist" + ]), + eslint.configs.recommended, + tseslint.configs.recommended, +); From acd60007ac3730365bda44c113412b1399c8f12e Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 14:43:08 +0200 Subject: [PATCH 12/21] chore(eslint): integrate formatter config --- _regroup/eslint.config.js | 25 ---------------- _regroup/eslint.format.config.js | 47 ----------------------------- _regroup/package.json | 6 +--- eslint.config.mjs | 20 ++++++++++++- eslint.format.config.mjs | 51 ++++++++++++++++++++++++++++++++ package.json | 4 +++ 6 files changed, 75 insertions(+), 78 deletions(-) delete mode 100644 _regroup/eslint.format.config.js create mode 100644 eslint.format.config.mjs diff --git a/_regroup/eslint.config.js b/_regroup/eslint.config.js index 7c906beb2..2162c7eb7 100644 --- a/_regroup/eslint.config.js +++ b/_regroup/eslint.config.js @@ -1,22 +1,7 @@ -import eslint from "@eslint/js"; import tseslint from "typescript-eslint"; import simpleImportSort from "eslint-plugin-simple-import-sort"; export default tseslint.config( - eslint.configs.recommended, - tseslint.configs.recommended, - // consider using rules below, once we have a full TS codebase and can be more strict - // tseslint.configs.strictTypeChecked, - // tseslint.configs.stylisticTypeChecked, - // tseslint.configs.recommendedTypeChecked, - { - languageOptions: { - parserOptions: { - projectService: true, - tsconfigRootDir: import.meta.dirname - } - } - }, { plugins: { "simple-import-sort": simpleImportSort @@ -37,15 +22,5 @@ export default tseslint.config( "simple-import-sort/imports": "error", "simple-import-sort/exports": "error" } - }, - { - ignores: [ - "build/*", - "dist/*", - "docs/*", - "demo/*", - "src/public/app-dist/*", - "src/public/app/doc_notes/*" - ] } ); diff --git a/_regroup/eslint.format.config.js b/_regroup/eslint.format.config.js deleted file mode 100644 index 9dbfd78b2..000000000 --- a/_regroup/eslint.format.config.js +++ /dev/null @@ -1,47 +0,0 @@ -import stylistic from "@stylistic/eslint-plugin"; -import tsParser from "@typescript-eslint/parser"; - -// eslint config just for formatting rules -// potentially to be merged with the linting rules into one single config, -// once we have fixed the majority of lint errors - -// Go to https://eslint.style/rules/default/${rule_without_prefix} to check the rule details -export const stylisticRules = { - "@stylistic/indent": [ "error", 4 ], - "@stylistic/quotes": [ "error", "double", { avoidEscape: true, allowTemplateLiterals: "always" } ], - "@stylistic/semi": [ "error", "always" ], - "@stylistic/quote-props": [ "error", "consistent-as-needed" ], - "@stylistic/max-len": [ "error", { code: 100 } ], - "@stylistic/comma-dangle": [ "error", "never" ], - "@stylistic/linebreak-style": [ "error", "unix" ], - "@stylistic/array-bracket-spacing": [ "error", "always" ], - "@stylistic/object-curly-spacing": [ "error", "always" ], - "@stylistic/padded-blocks": [ "error", { classes: "always" } ] -}; - -export default [ - { - files: [ "**/*.{js,ts,mjs,cjs}" ], - languageOptions: { - parser: tsParser - }, - plugins: { - "@stylistic": stylistic - }, - rules: { - ...stylisticRules - } - }, - { - ignores: [ - "build/*", - "dist/*", - "docs/*", - "demo/*", - // TriliumNextTODO: check if we want to format packages here as well - for now skipping it - "packages/*", - "src/public/app-dist/*", - "src/public/app/doc_notes/*" - ] - } -]; diff --git a/_regroup/package.json b/_regroup/package.json index d42e107f4..708c5bcc0 100644 --- a/_regroup/package.json +++ b/_regroup/package.json @@ -26,11 +26,7 @@ "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 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:format-check": "eslint -c eslint.format.config.js .", - "dev:format-fix": "eslint -c eslint.format.config.js . --fix", - "dev:linter-check": "eslint .", - "dev:linter-fix": "eslint . --fix", + "dev:watch-dist": "tsx ./bin/watch-dist.ts", "chore:generate-document": "cross-env nodemon ./bin/generate_document.ts 1000", "chore:generate-openapi": "tsx bin/generate-openapi.js" }, diff --git a/eslint.config.mjs b/eslint.config.mjs index 3c6b57d2d..082bcad22 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -8,8 +8,26 @@ export default defineConfig( globalIgnores([ ".cache", "tmp", - "**/dist" + "**/dist", + "**/out-tsc", + "apps/edit-docs/demo/*", + "docs/*", + "apps/web-clipper/lib/*", + // TODO: check if we want to format packages here as well - for now skipping it + "packages/*", ]), eslint.configs.recommended, tseslint.configs.recommended, + // consider using rules below, once we have a full TS codebase and can be more strict + // tseslint.configs.strictTypeChecked, + // tseslint.configs.stylisticTypeChecked, + // tseslint.configs.recommendedTypeChecked, + { + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname + } + } + } ); diff --git a/eslint.format.config.mjs b/eslint.format.config.mjs new file mode 100644 index 000000000..b9591c3d3 --- /dev/null +++ b/eslint.format.config.mjs @@ -0,0 +1,51 @@ +// @ts-check + +import { defineConfig, globalIgnores } from 'eslint/config'; +import tsParser from "@typescript-eslint/parser"; +import stylistic from "@stylistic/eslint-plugin"; + +// eslint config just for formatting rules +// potentially to be merged with the linting rules into one single config, +// once we have fixed the majority of lint errors + +// Go to https://eslint.style/rules/default/${rule_without_prefix} to check the rule details +export const stylisticRules = { + "@stylistic/indent": ["error", 4], + "@stylistic/quotes": ["error", "double", { avoidEscape: true, allowTemplateLiterals: "always" }], + "@stylistic/semi": ["error", "always"], + "@stylistic/quote-props": ["error", "consistent-as-needed"], + "@stylistic/max-len": ["error", { code: 100 }], + "@stylistic/comma-dangle": ["error", "never"], + "@stylistic/linebreak-style": ["error", "unix"], + "@stylistic/array-bracket-spacing": ["error", "always"], + "@stylistic/object-curly-spacing": ["error", "always"], + "@stylistic/padded-blocks": ["error", { classes: "always" }] +}; + +export default defineConfig( + globalIgnores([ + ".cache", + "tmp", + "**/dist", + "**/out-tsc", + "apps/edit-docs/demo/*", + "docs/*", + "apps/web-clipper/lib/*" + ]), + + { + files: ["**/*.{js,ts,mjs,cjs}"], + + languageOptions: { + parser: tsParser + }, + + plugins: { + "@stylistic": stylistic + }, + + rules: { + ...stylisticRules + } + } +); \ No newline at end of file diff --git a/package.json b/package.json index ac54e7bc2..35068b908 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,10 @@ "test:parallel": "pnpm --filter=!server --filter=!ckeditor5-mermaid --filter=!ckeditor5-math --parallel test", "test:sequential": "pnpm --filter=server --filter=ckeditor5-mermaid --filter=ckeditor5-math --sequential test", "typecheck": "tsc --build", + "dev:format-check": "eslint -c eslint.format.config.mjs .", + "dev:format-fix": "eslint -c eslint.format.config.mjs . --fix", + "dev:linter-check": "cross-env NODE_OPTIONS=--max_old_space_size=4096 eslint .", + "dev:linter-fix": "cross-env NODE_OPTIONS=--max_old_space_size=4096 eslint . --fix", "postinstall": "tsx scripts/electron-rebuild.mts" }, "private": true, From 3df9a87b29a5795a902656250ade1d88f0cf8aed Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 14:48:00 +0200 Subject: [PATCH 13/21] chore(eslint): clean up unnecessary dependency in client --- apps/client/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/client/package.json b/apps/client/package.json index f8f9f183b..bafe5f6d2 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -15,7 +15,6 @@ "circular-deps": "dpdm -T src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular" }, "dependencies": { - "@eslint/js": "9.39.1", "@excalidraw/excalidraw": "0.18.0", "@fullcalendar/core": "6.1.19", "@fullcalendar/daygrid": "6.1.19", From 85741240f1a21a42c2ea846b66c99c08d957c6ff Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 14:50:41 +0200 Subject: [PATCH 14/21] chore(eslint): reintegrate simple import sort --- _regroup/eslint.config.js | 26 -------------------------- eslint.config.mjs | 22 ++++++++++++++++++++++ package.json | 1 + pnpm-lock.yaml | 19 ++++++++++++------- 4 files changed, 35 insertions(+), 33 deletions(-) delete mode 100644 _regroup/eslint.config.js diff --git a/_regroup/eslint.config.js b/_regroup/eslint.config.js deleted file mode 100644 index 2162c7eb7..000000000 --- a/_regroup/eslint.config.js +++ /dev/null @@ -1,26 +0,0 @@ -import tseslint from "typescript-eslint"; -import simpleImportSort from "eslint-plugin-simple-import-sort"; - -export default tseslint.config( - { - plugins: { - "simple-import-sort": simpleImportSort - } - }, - { - rules: { - // add rule overrides here - "no-undef": "off", - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": [ - "error", - { - argsIgnorePattern: "^_", - varsIgnorePattern: "^_" - } - ], - "simple-import-sort/imports": "error", - "simple-import-sort/exports": "error" - } - } -); diff --git a/eslint.config.mjs b/eslint.config.mjs index 082bcad22..11628d8a0 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -3,6 +3,7 @@ import eslint from '@eslint/js'; import { defineConfig, globalIgnores } from 'eslint/config'; import tseslint from 'typescript-eslint'; +import simpleImportSort from "eslint-plugin-simple-import-sort"; export default defineConfig( globalIgnores([ @@ -29,5 +30,26 @@ export default defineConfig( tsconfigRootDir: import.meta.dirname } } + }, + { + plugins: { + "simple-import-sort": simpleImportSort + }, + + rules: { + "no-undef": "off", + "no-unused-vars": "off", + + "@typescript-eslint/no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_" + } + ], + + "simple-import-sort/imports": "error", + "simple-import-sort/exports": "error" + } } ); diff --git a/package.json b/package.json index 35068b908..de41a674e 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "eslint-config-prettier": "10.1.8", "eslint-plugin-playwright": "2.4.0", "eslint-plugin-react-hooks": "7.0.1", + "eslint-plugin-simple-import-sort": "12.1.1", "happy-dom": "~20.0.0", "http-server": "14.1.1", "jiti": "2.6.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a04e794e4..05e111d24 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,6 +85,9 @@ importers: eslint-plugin-react-hooks: specifier: 7.0.1 version: 7.0.1(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-simple-import-sort: + specifier: 12.1.1 + version: 12.1.1(eslint@9.39.1(jiti@2.6.1)) happy-dom: specifier: ~20.0.0 version: 20.0.11 @@ -154,9 +157,6 @@ importers: apps/client: dependencies: - '@eslint/js': - specifier: 9.39.1 - version: 9.39.1 '@excalidraw/excalidraw': specifier: 0.18.0 version: 0.18.0(@types/react-dom@19.1.6(@types/react@19.1.7))(@types/react@19.1.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -7812,6 +7812,11 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + eslint-plugin-simple-import-sort@12.1.1: + resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} + peerDependencies: + eslint: '>=5.0.0' + eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -15305,8 +15310,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-editor-classic@47.3.0': dependencies: @@ -15358,8 +15361,6 @@ snapshots: '@ckeditor/ckeditor5-table': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-emoji@47.3.0': dependencies: @@ -23278,6 +23279,10 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 + eslint-plugin-simple-import-sort@12.1.1(eslint@9.39.1(jiti@2.6.1)): + dependencies: + eslint: 9.39.1(jiti@2.6.1) + eslint-scope@5.1.1: dependencies: esrecurse: 4.3.0 From 21079335e7219547f9357357cdeb7000d3d5ca6a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 14:58:38 +0200 Subject: [PATCH 15/21] chore(eslint): remove unnecessary files --- apps/client/eslint.config.mjs | 5 ----- apps/db-compare/eslint.config.mjs | 5 ----- apps/desktop/eslint.config.mjs | 5 ----- apps/dump-db/eslint.config.mjs | 5 ----- apps/edit-docs/eslint.config.mjs | 5 ----- apps/server/eslint.config.mjs | 5 ----- 6 files changed, 30 deletions(-) delete mode 100644 apps/client/eslint.config.mjs delete mode 100644 apps/db-compare/eslint.config.mjs delete mode 100644 apps/desktop/eslint.config.mjs delete mode 100644 apps/dump-db/eslint.config.mjs delete mode 100644 apps/edit-docs/eslint.config.mjs delete mode 100644 apps/server/eslint.config.mjs diff --git a/apps/client/eslint.config.mjs b/apps/client/eslint.config.mjs deleted file mode 100644 index 724052a2e..000000000 --- a/apps/client/eslint.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import baseConfig from "../../eslint.config.mjs"; - -export default [ - ...baseConfig -]; diff --git a/apps/db-compare/eslint.config.mjs b/apps/db-compare/eslint.config.mjs deleted file mode 100644 index 724052a2e..000000000 --- a/apps/db-compare/eslint.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import baseConfig from "../../eslint.config.mjs"; - -export default [ - ...baseConfig -]; diff --git a/apps/desktop/eslint.config.mjs b/apps/desktop/eslint.config.mjs deleted file mode 100644 index 724052a2e..000000000 --- a/apps/desktop/eslint.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import baseConfig from "../../eslint.config.mjs"; - -export default [ - ...baseConfig -]; diff --git a/apps/dump-db/eslint.config.mjs b/apps/dump-db/eslint.config.mjs deleted file mode 100644 index 724052a2e..000000000 --- a/apps/dump-db/eslint.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import baseConfig from "../../eslint.config.mjs"; - -export default [ - ...baseConfig -]; diff --git a/apps/edit-docs/eslint.config.mjs b/apps/edit-docs/eslint.config.mjs deleted file mode 100644 index 724052a2e..000000000 --- a/apps/edit-docs/eslint.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import baseConfig from "../../eslint.config.mjs"; - -export default [ - ...baseConfig -]; diff --git a/apps/server/eslint.config.mjs b/apps/server/eslint.config.mjs deleted file mode 100644 index 724052a2e..000000000 --- a/apps/server/eslint.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import baseConfig from "../../eslint.config.mjs"; - -export default [ - ...baseConfig -]; From 912f14549c7f0575001b13eba73206beb57a5205 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 15:19:32 +0200 Subject: [PATCH 16/21] chore(eslint): integrate playwright e2e --- apps/server-e2e/eslint.config.mjs | 15 --------- eslint.config.mjs | 56 +++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 33 deletions(-) delete mode 100644 apps/server-e2e/eslint.config.mjs diff --git a/apps/server-e2e/eslint.config.mjs b/apps/server-e2e/eslint.config.mjs deleted file mode 100644 index 1603594d7..000000000 --- a/apps/server-e2e/eslint.config.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import playwright from "eslint-plugin-playwright"; -import baseConfig from "../../eslint.config.mjs"; - -export default [ - playwright.configs["flat/recommended"], - ...baseConfig, - { - files: [ - "**/*.ts", - "**/*.js" - ], - // Override or add rules here - rules: {} - } -]; diff --git a/eslint.config.mjs b/eslint.config.mjs index 11628d8a0..af536a18f 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,19 +4,10 @@ import eslint from '@eslint/js'; import { defineConfig, globalIgnores } from 'eslint/config'; import tseslint from 'typescript-eslint'; import simpleImportSort from "eslint-plugin-simple-import-sort"; +import playwright from "eslint-plugin-playwright"; +import tsParser from "@typescript-eslint/parser"; -export default defineConfig( - globalIgnores([ - ".cache", - "tmp", - "**/dist", - "**/out-tsc", - "apps/edit-docs/demo/*", - "docs/*", - "apps/web-clipper/lib/*", - // TODO: check if we want to format packages here as well - for now skipping it - "packages/*", - ]), +const mainConfig = defineConfig( eslint.configs.recommended, tseslint.configs.recommended, // consider using rules below, once we have a full TS codebase and can be more strict @@ -32,24 +23,53 @@ export default defineConfig( } }, { - plugins: { - "simple-import-sort": simpleImportSort - }, - rules: { "no-undef": "off", "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": [ "error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" } - ], + ] + } + }, + { + plugins: { + "simple-import-sort": simpleImportSort + }, + rules: { "simple-import-sort/imports": "error", "simple-import-sort/exports": "error" } } ); + +const playwrightConfig = { + files: [ + "apps/server-e2e/src/**/*.spec.ts", + "apps/desktop/e2e/**/*.spec.ts" + ], + plugins: { playwright }, + // Override or add rules here + rules: { ...playwright.configs["flat/recommended"].rules, }, + languageOptions: { parser: tsParser }, +}; + +export default defineConfig( + globalIgnores([ + ".cache", + "tmp", + "**/dist", + "**/out-tsc", + "apps/edit-docs/demo/*", + "docs/*", + "apps/web-clipper/lib/*", + // TODO: check if we want to format packages here as well - for now skipping it + "packages/*", + ]), + ...mainConfig, + playwrightConfig +); From f7ac465e67495a7e41a91fa515376bb1942fff09 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 15:31:38 +0200 Subject: [PATCH 17/21] chore(eslint): integrate preact config --- eslint.config.mjs | 6 ++++-- package.json | 2 +- pnpm-lock.yaml | 50 +++++------------------------------------------ 3 files changed, 10 insertions(+), 48 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index af536a18f..5ae642a87 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -6,8 +6,10 @@ import tseslint from 'typescript-eslint'; import simpleImportSort from "eslint-plugin-simple-import-sort"; import playwright from "eslint-plugin-playwright"; import tsParser from "@typescript-eslint/parser"; +import preact from "eslint-config-preact"; -const mainConfig = defineConfig( +const mainConfig = [ + ...preact, eslint.configs.recommended, tseslint.configs.recommended, // consider using rules below, once we have a full TS codebase and can be more strict @@ -45,7 +47,7 @@ const mainConfig = defineConfig( "simple-import-sort/exports": "error" } } -); +]; const playwrightConfig = { files: [ diff --git a/package.json b/package.json index de41a674e..f2deff792 100644 --- a/package.json +++ b/package.json @@ -56,9 +56,9 @@ "dpdm": "3.14.0", "esbuild": "0.27.0", "eslint": "9.39.1", + "eslint-config-preact": "2.0.0", "eslint-config-prettier": "10.1.8", "eslint-plugin-playwright": "2.4.0", - "eslint-plugin-react-hooks": "7.0.1", "eslint-plugin-simple-import-sort": "12.1.1", "happy-dom": "~20.0.0", "http-server": "14.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 05e111d24..d6e7fd902 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -76,15 +76,15 @@ importers: eslint: specifier: 9.39.1 version: 9.39.1(jiti@2.6.1) + eslint-config-preact: + specifier: 2.0.0 + version: 2.0.0(eslint@9.39.1(jiti@2.6.1)) eslint-config-prettier: specifier: 10.1.8 version: 10.1.8(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-playwright: specifier: 2.4.0 version: 2.4.0(eslint@9.39.1(jiti@2.6.1)) - eslint-plugin-react-hooks: - specifier: 7.0.1 - version: 7.0.1(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-simple-import-sort: specifier: 12.1.1 version: 12.1.1(eslint@9.39.1(jiti@2.6.1)) @@ -7800,12 +7800,6 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react-hooks@7.0.1: - resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} - engines: {node: '>=18'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react@7.37.5: resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} engines: {node: '>=4'} @@ -8597,12 +8591,6 @@ packages: resolution: {integrity: sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==} engines: {node: '>=18.0.0'} - hermes-estree@0.25.1: - resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} - - hermes-parser@0.25.1: - resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} - highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} @@ -14268,12 +14256,6 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod-validation-error@3.5.3: - resolution: {integrity: sha512-OT5Y8lbUadqVZCsnyFaTQ4/O2mys4tj7PqhdbBCp7McPwvIEKfPtdA6QfPeFQK2/Rz5LgwmAXRJTugBNBi0btw==} - engines: {node: '>=18.0.0'} - peerDependencies: - zod: ^3.25.0 || ^4.0.0 - zod@3.24.4: resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==} @@ -15846,8 +15828,6 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.3.0 '@ckeditor/ckeditor5-utils': 47.3.0 ckeditor5: 47.3.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-restricted-editing@47.3.0': dependencies: @@ -23246,17 +23226,6 @@ snapshots: dependencies: eslint: 9.39.1(jiti@2.6.1) - eslint-plugin-react-hooks@7.0.1(eslint@9.39.1(jiti@2.6.1)): - dependencies: - '@babel/core': 7.28.0 - '@babel/parser': 7.28.4 - eslint: 9.39.1(jiti@2.6.1) - hermes-parser: 0.25.1 - zod: 4.1.12 - zod-validation-error: 3.5.3(zod@4.1.12) - transitivePeerDependencies: - - supports-color - eslint-plugin-react@7.37.5(eslint@9.39.1(jiti@2.6.1)): dependencies: array-includes: 3.1.9 @@ -24318,12 +24287,6 @@ snapshots: helmet@8.1.0: {} - hermes-estree@0.25.1: {} - - hermes-parser@0.25.1: - dependencies: - hermes-estree: 0.25.1 - highlight.js@11.11.1: {} highlightjs-cobol@0.3.3: @@ -31028,13 +30991,10 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 - zod-validation-error@3.5.3(zod@4.1.12): - dependencies: - zod: 4.1.12 - zod@3.24.4: {} - zod@4.1.12: {} + zod@4.1.12: + optional: true zustand@4.5.6(@types/react@19.1.7)(react@19.2.0): dependencies: From 3dee1725b378d9b3f0f7d6a1fca3dce586678a5a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 18:54:38 +0200 Subject: [PATCH 18/21] chore(regroup): reintroduce old e2e tests --- _regroup/integration-tests/auth.setup.ts | 17 ------------- _regroup/integration-tests/duplicate.spec.ts | 9 ------- .../integration-tests/example.disabled.ts | 18 ------------- _regroup/integration-tests/settings.spec.ts | 21 ---------------- _regroup/integration-tests/tree.spec.ts | 18 ------------- .../integration-tests/update_check.spec.ts | 12 --------- apps/server-e2e/src/duplicate.spec.ts | 14 +++++++++++ apps/server-e2e/src/settings.spec.ts | 25 +++++++++++++++++++ apps/server-e2e/src/tree.spec.ts | 14 +++++++++++ 9 files changed, 53 insertions(+), 95 deletions(-) delete mode 100644 _regroup/integration-tests/auth.setup.ts delete mode 100644 _regroup/integration-tests/duplicate.spec.ts delete mode 100644 _regroup/integration-tests/example.disabled.ts delete mode 100644 _regroup/integration-tests/settings.spec.ts delete mode 100644 _regroup/integration-tests/tree.spec.ts delete mode 100644 _regroup/integration-tests/update_check.spec.ts create mode 100644 apps/server-e2e/src/duplicate.spec.ts create mode 100644 apps/server-e2e/src/settings.spec.ts create mode 100644 apps/server-e2e/src/tree.spec.ts diff --git a/_regroup/integration-tests/auth.setup.ts b/_regroup/integration-tests/auth.setup.ts deleted file mode 100644 index 9b31eec49..000000000 --- a/_regroup/integration-tests/auth.setup.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { test as setup, expect } from "@playwright/test"; - -const authFile = "playwright/.auth/user.json"; - -const ROOT_URL = "http://localhost:8082"; -const LOGIN_PASSWORD = "demo1234"; - -// Reference: https://playwright.dev/docs/auth#basic-shared-account-in-all-tests - -setup("authenticate", async ({ page }) => { - await page.goto(ROOT_URL); - await expect(page).toHaveURL(`${ROOT_URL}/login`); - - await page.getByRole("textbox", { name: "Password" }).fill(LOGIN_PASSWORD); - await page.getByRole("button", { name: "Login" }).click(); - await page.context().storageState({ path: authFile }); -}); diff --git a/_regroup/integration-tests/duplicate.spec.ts b/_regroup/integration-tests/duplicate.spec.ts deleted file mode 100644 index fe079952b..000000000 --- a/_regroup/integration-tests/duplicate.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { test, expect } from "@playwright/test"; - -test("Can duplicate note with broken links", async ({ page }) => { - await page.goto(`http://localhost:8082/#2VammGGdG6Ie`); - await page.locator(".tree-wrapper .fancytree-active").getByText("Note map").click({ button: "right" }); - await page.getByText("Duplicate subtree").click(); - await expect(page.locator(".toast-body")).toBeHidden(); - await expect(page.locator(".tree-wrapper").getByText("Note map (dup)")).toBeVisible(); -}); diff --git a/_regroup/integration-tests/example.disabled.ts b/_regroup/integration-tests/example.disabled.ts deleted file mode 100644 index a149fe328..000000000 --- a/_regroup/integration-tests/example.disabled.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { test, expect } from "@playwright/test"; - -test("has title", async ({ page }) => { - await page.goto("https://playwright.dev/"); - - // Expect a title "to contain" a substring. - await expect(page).toHaveTitle(/Playwright/); -}); - -test("get started link", async ({ page }) => { - await page.goto("https://playwright.dev/"); - - // Click the get started link. - await page.getByRole("link", { name: "Get started" }).click(); - - // Expects page to have a heading with the name of Installation. - await expect(page.getByRole("heading", { name: "Installation" })).toBeVisible(); -}); diff --git a/_regroup/integration-tests/settings.spec.ts b/_regroup/integration-tests/settings.spec.ts deleted file mode 100644 index b3fe16fda..000000000 --- a/_regroup/integration-tests/settings.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import test, { expect } from "@playwright/test"; - -test("Native Title Bar not displayed on web", async ({ page }) => { - await page.goto("http://localhost:8082/#root/_hidden/_options/_optionsAppearance"); - await expect(page.getByRole("heading", { name: "Theme" })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Native Title Bar (requires" })).toBeHidden(); -}); - -test("Tray settings not displayed on web", async ({ page }) => { - await page.goto("http://localhost:8082/#root/_hidden/_options/_optionsOther"); - await expect(page.getByRole("heading", { name: "Note Erasure Timeout" })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Tray" })).toBeHidden(); -}); - -test("Spellcheck settings not displayed on web", async ({ page }) => { - await page.goto("http://localhost:8082/#root/_hidden/_options/_optionsSpellcheck"); - await expect(page.getByRole("heading", { name: "Spell Check" })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Tray" })).toBeHidden(); - await expect(page.getByText("These options apply only for desktop builds")).toBeVisible(); - await expect(page.getByText("Enable spellcheck")).toBeHidden(); -}); diff --git a/_regroup/integration-tests/tree.spec.ts b/_regroup/integration-tests/tree.spec.ts deleted file mode 100644 index 257375fa8..000000000 --- a/_regroup/integration-tests/tree.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import test, { expect } from "@playwright/test"; - -test("Renders on desktop", async ({ page, context }) => { - await page.goto("http://localhost:8082"); - await expect(page.locator(".tree")).toContainText("Trilium Integration Test"); -}); - -test("Renders on mobile", async ({ page, context }) => { - await context.addCookies([ - { - url: "http://localhost:8082", - name: "trilium-device", - value: "mobile" - } - ]); - await page.goto("http://localhost:8082"); - await expect(page.locator(".tree")).toContainText("Trilium Integration Test"); -}); diff --git a/_regroup/integration-tests/update_check.spec.ts b/_regroup/integration-tests/update_check.spec.ts deleted file mode 100644 index 38e28bf22..000000000 --- a/_regroup/integration-tests/update_check.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { test, expect } from "@playwright/test"; - -const expectedVersion = "0.90.3"; - -test("Displays update badge when there is a version available", async ({ page }) => { - await page.goto("http://localhost:8080"); - await page.getByRole("button", { name: "" }).click(); - await page.getByText(`Version ${expectedVersion} is available,`).click(); - - const page1 = await page.waitForEvent("popup"); - expect(page1.url()).toBe(`https://github.com/TriliumNext/Trilium/releases/tag/v${expectedVersion}`); -}); diff --git a/apps/server-e2e/src/duplicate.spec.ts b/apps/server-e2e/src/duplicate.spec.ts new file mode 100644 index 000000000..56c170960 --- /dev/null +++ b/apps/server-e2e/src/duplicate.spec.ts @@ -0,0 +1,14 @@ +import { test, expect } from "@playwright/test"; +import App from "./support/app"; + +test("Can duplicate note with broken links", async ({ page, context }) => { + const app = new App(page, context); + await app.goto({ + url: "http://localhost:8082/#root/Q5abPvymDH6C/2VammGGdG6Ie" + }); + + await app.noteTree.getByText("Note map").first().click({ button: "right" }); + await page.locator("#context-menu-container").getByText("Duplicate").click(); + await expect(page.locator(".toast-body")).toBeHidden(); + await expect(app.noteTree.getByText("Note map (dup)")).toBeVisible(); +}); diff --git a/apps/server-e2e/src/settings.spec.ts b/apps/server-e2e/src/settings.spec.ts new file mode 100644 index 000000000..28210e57c --- /dev/null +++ b/apps/server-e2e/src/settings.spec.ts @@ -0,0 +1,25 @@ +import test, { expect } from "@playwright/test"; +import App from "./support/app"; + +test("Native Title Bar not displayed on web", async ({ page, context }) => { + const app = new App(page, context); + await app.goto({ url: "http://localhost:8082/#root/_hidden/_options/_optionsAppearance" }); + await expect(app.currentNoteSplitContent.getByRole("heading", { name: "Theme" })).toBeVisible(); + await expect(app.currentNoteSplitContent.getByRole("heading", { name: "Native Title Bar (requires" })).toBeHidden(); +}); + +test("Tray settings not displayed on web", async ({ page, context }) => { + const app = new App(page, context); + await app.goto({ url: "http://localhost:8082/#root/_hidden/_options/_optionsOther" }); + await expect(app.currentNoteSplitContent.getByRole("heading", { name: "Note Erasure Timeout" })).toBeVisible(); + await expect(app.currentNoteSplitContent.getByRole("heading", { name: "Tray" })).toBeHidden(); +}); + +test("Spellcheck settings not displayed on web", async ({ page, context }) => { + const app = new App(page, context); + await app.goto({ url: "http://localhost:8082/#root/_hidden/_options/_optionsSpellcheck" }); + await expect(app.currentNoteSplitContent.getByRole("heading", { name: "Spell Check" })).toBeVisible(); + await expect(app.currentNoteSplitContent.getByRole("heading", { name: "Tray" })).toBeHidden(); + await expect(app.currentNoteSplitContent.getByText("These options apply only for desktop builds")).toBeVisible(); + await expect(app.currentNoteSplitContent.getByText("Enable spellcheck")).toBeHidden(); +}); diff --git a/apps/server-e2e/src/tree.spec.ts b/apps/server-e2e/src/tree.spec.ts new file mode 100644 index 000000000..f1ca8f88f --- /dev/null +++ b/apps/server-e2e/src/tree.spec.ts @@ -0,0 +1,14 @@ +import test, { expect } from "@playwright/test"; +import App from "./support/app"; + +test("Renders on desktop", async ({ page, context }) => { + const app = new App(page, context); + await app.goto(); + await expect(app.noteTree).toContainText("Trilium Integration Test"); +}); + +test("Renders on mobile", async ({ page, context }) => { + const app = new App(page, context); + await app.goto({ isMobile: true }); + await expect(app.noteTree).toContainText("Trilium Integration Test"); +}); From 2a6b91dd04d371109043a0c997be74ab39969ad1 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 19:08:03 +0200 Subject: [PATCH 19/21] chore(regroup): reintroduce code coverage --- .gitignore | 1 + _regroup/package.json | 52 ---------------------------------------- apps/client/package.json | 1 + apps/server/package.json | 1 + 4 files changed, 3 insertions(+), 52 deletions(-) delete mode 100644 _regroup/package.json diff --git a/.gitignore b/.gitignore index b2c4e3c46..d10c0ec0d 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ upload # docs site/ +apps/*/coverage \ No newline at end of file diff --git a/_regroup/package.json b/_regroup/package.json deleted file mode 100644 index 708c5bcc0..000000000 --- a/_regroup/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "main": "./electron-main.js", - "bin": { - "trilium": "src/main.js" - }, - "type": "module", - "scripts": { - "server:start-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev nodemon src/main.ts", - "server:start-no-dir": "cross-env TRILIUM_ENV=dev nodemon src/main.ts", - "server:start-test": "npm run server:switch && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test 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-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev TRILIUM_PORT=37742 electron --inspect=5858 .", - "electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data 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 TRILIUM_PORT=37742 nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"", - "electron:start-prod-no-dir": "npm run build:prepare-dist && cross-env TRILIUM_ENV=prod 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_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": "typedoc", - "test": "npm run client:test && npm run server:test", - "client:test": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app", - "client:coverage": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app --coverage", - "test:playwright": "playwright test --workers 1", - "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 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", - "chore:generate-document": "cross-env nodemon ./bin/generate_document.ts 1000", - "chore:generate-openapi": "tsx bin/generate-openapi.js" - }, - "devDependencies": { - "@playwright/test": "1.57.0", - "@stylistic/eslint-plugin": "5.6.1", - "@types/express": "5.0.5", - "@types/node": "24.10.1", - "@types/yargs": "17.0.35", - "@vitest/coverage-v8": "4.0.14", - "eslint": "9.39.1", - "eslint-plugin-simple-import-sort": "12.1.1", - "esm": "3.2.25", - "jsdoc": "4.0.5", - "lorem-ipsum": "2.0.8", - "rcedit": "5.0.2", - "rimraf": "6.1.2", - "tslib": "2.8.1" - }, - "optionalDependencies": { - "appdmg": "0.6.6" - } -} diff --git a/apps/client/package.json b/apps/client/package.json index bafe5f6d2..61cd4b377 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -12,6 +12,7 @@ "scripts": { "build": "cross-env NODE_OPTIONS=--max-old-space-size=4096 vite build", "test": "vitest", + "coverage": "vitest --coverage", "circular-deps": "dpdm -T src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular" }, "dependencies": { diff --git a/apps/server/package.json b/apps/server/package.json index 10705f8dd..e39ed317e 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -11,6 +11,7 @@ "build": "tsx scripts/build.ts", "package": "pnpm build && bash scripts/build-server.sh", "test": "vitest", + "coverage": "vitest --coverage", "test-build": "vitest --config vitest.build.config.mts", "start-prod": "cross-env TRILIUM_DATA_DIR=data pnpm start-prod-no-dir", "start-prod-no-dir": "pnpm build && cross-env TRILIUM_ENV=production TRILIUM_PORT=8082 node dist/main.cjs", From d30d207ab5c913785e7d218214156f76ec1f23c6 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 19:08:19 +0200 Subject: [PATCH 20/21] test(server): solve some local timeouts --- apps/server/src/services/import/single.spec.ts | 2 +- apps/server/src/services/import/zip.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/server/src/services/import/single.spec.ts b/apps/server/src/services/import/single.spec.ts index 0d0af35f7..e8a341a6b 100644 --- a/apps/server/src/services/import/single.spec.ts +++ b/apps/server/src/services/import/single.spec.ts @@ -112,4 +112,4 @@ describe("processNoteContent", () => { title: "New note" }); }); -}); +}, 60_000); diff --git a/apps/server/src/services/import/zip.spec.ts b/apps/server/src/services/import/zip.spec.ts index a74c243c4..ecc070c6a 100644 --- a/apps/server/src/services/import/zip.spec.ts +++ b/apps/server/src/services/import/zip.spec.ts @@ -83,7 +83,7 @@ describe("processNoteContent", () => { const content = attachment.getContent(); expect(content).toStrictEqual(`{"view":{"center":{"lat":49.19598332223546,"lng":-2.1414576506668808},"zoom":12}}`); }); -}); +}, 60_000); function getNoteByTitlePath(parentNote: BNote, ...titlePath: string[]) { let cursor = parentNote; From 572feed918500da7e868e5aed0248c00cb81a385 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 6 Dec 2025 19:17:56 +0200 Subject: [PATCH 21/21] chore(regroup): address requested changes --- apps/server/scripts/generate_document.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/server/scripts/generate_document.ts b/apps/server/scripts/generate_document.ts index 0b041ad26..acfd9d512 100644 --- a/apps/server/scripts/generate_document.ts +++ b/apps/server/scripts/generate_document.ts @@ -7,7 +7,7 @@ import sqlInit from "../src/services/sql_init.js"; import noteService from "../src/services/notes.js"; import attributeService from "../src/services/attributes.js"; import cloningService from "../src/services/cloning.js"; -import * as loremIpsum from "lorem-ipsum"; +import { loremIpsum } from "lorem-ipsum"; import "../src/becca/entity_constructor.js"; import { initializeTranslations } from "../src/services/i18n.js"; import cls from "../src/services/cls.js"; @@ -39,7 +39,7 @@ async function start() { await sqlInit.dbReady; for (let i = 0; i < noteCount; i++) { - const title = loremIpsum.loremIpsum({ + const title = loremIpsum({ count: 1, units: "sentences", sentenceLowerBound: 1, @@ -47,7 +47,7 @@ async function start() { }); const paragraphCount = Math.floor(Math.random() * Math.random() * 100); - const content = loremIpsum.loremIpsum({ + const content = loremIpsum({ count: paragraphCount, units: "paragraphs", sentenceLowerBound: 1,