From 1893686e664074331ac057aabe2a6053dc97488d Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 27 May 2025 23:21:26 +0300 Subject: [PATCH 01/19] feat(ci): run typecheck --- .github/workflows/dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 6497ebb96..7d895104d 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -39,7 +39,7 @@ jobs: - uses: nrwl/nx-set-shas@v4 - name: Check affected - run: pnpm nx affected -t build rebuild-deps + run: pnpm nx affected -t typecheck build rebuild-deps report-electron-size: name: Report Electron size From 114607f7621fd051b59442dec8856a9ad5630c3b Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 27 May 2025 23:28:01 +0300 Subject: [PATCH 02/19] refactor(commons): switch to esbuild --- packages/commons/package.json | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/commons/package.json b/packages/commons/package.json index 09312903b..045e8902e 100644 --- a/packages/commons/package.json +++ b/packages/commons/package.json @@ -27,21 +27,31 @@ "sourceRoot": "packages/commons/src", "targets": { "build": { - "executor": "@nx/js:swc", + "executor": "@nx/esbuild:esbuild", "outputs": [ "{options.outputPath}" ], + "defaultConfiguration": "production", "options": { - "outputPath": "packages/commons/dist", "main": "packages/commons/src/index.ts", + "outputPath": "packages/commons/dist", + "outputFileName": "main.js", "tsConfig": "packages/commons/tsconfig.lib.json", - "skipTypeCheck": true, - "stripLeadingPaths": true + "platform": "node", + "format": [ + "esm" + ], + "declarationRootDir": "packages/commons/src" + }, + "configurations": { + "development": { + "minify": false + }, + "production": { + "minify": true + } } } } - }, - "dependencies": { - "@swc/helpers": "~0.5.11" } -} \ No newline at end of file +} From d81ab9ea1d58262590d6c9173102f583aa773f8d Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 27 May 2025 23:28:09 +0300 Subject: [PATCH 03/19] fix(commons): type errors --- packages/commons/src/lib/test-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/commons/src/lib/test-utils.ts b/packages/commons/src/lib/test-utils.ts index 8c796a3d3..edfe90ef0 100644 --- a/packages/commons/src/lib/test-utils.ts +++ b/packages/commons/src/lib/test-utils.ts @@ -44,7 +44,7 @@ export function trimIndentation(strings: TemplateStringsArray, ...values: any[]) // Trim the indentation of the first line in all the lines. const lines = str.split("\n"); - const output = []; + const output: string[] = []; for (let i = 0; i < lines.length; i++) { let numSpacesLine = 0; while (str.charAt(numSpacesLine) == " " && numSpacesLine < str.length) { From 44c502f9cc3267d0cca3fcb6ca994fb66c51aaef Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 27 May 2025 23:29:48 +0300 Subject: [PATCH 04/19] chore(deps): remove dependencies on swc --- nx.json | 10 - package.json | 5 - packages/commons/.swcrc | 22 - packages/turndown-plugin-gfm/package.json | 3 - pnpm-lock.yaml | 637 +--------------------- pnpm-workspace.yaml | 1 - 6 files changed, 5 insertions(+), 673 deletions(-) delete mode 100644 packages/commons/.swcrc diff --git a/nx.json b/nx.json index b83107856..c457d117b 100644 --- a/nx.json +++ b/nx.json @@ -62,16 +62,6 @@ } ], "targetDefaults": { - "@nx/js:swc": { - "cache": true, - "dependsOn": [ - "^build" - ], - "inputs": [ - "production", - "^production" - ] - }, "test": { "dependsOn": [ "^build" diff --git a/package.json b/package.json index 02ab16693..f363208c1 100644 --- a/package.json +++ b/package.json @@ -38,10 +38,6 @@ "@nx/vite": "21.1.2", "@nx/web": "21.1.2", "@playwright/test": "^1.36.0", - "@swc-node/register": "~1.10.0", - "@swc/cli": "~0.7.0", - "@swc/core": "~1.11.0", - "@swc/helpers": "~0.5.11", "@triliumnext/server": "workspace:*", "@types/express": "^4.17.21", "@types/node": "22.15.21", @@ -59,7 +55,6 @@ "jsonc-eslint-parser": "^2.1.0", "nx": "21.1.2", "react-refresh": "^0.17.0", - "swc-loader": "0.2.6", "tslib": "^2.3.0", "tsx": "4.19.4", "typescript": "~5.8.0", diff --git a/packages/commons/.swcrc b/packages/commons/.swcrc deleted file mode 100644 index bc22f28ee..000000000 --- a/packages/commons/.swcrc +++ /dev/null @@ -1,22 +0,0 @@ -{ - "jsc": { - "target": "es2017", - "parser": { - "syntax": "typescript", - "decorators": true, - "dynamicImport": true - }, - "transform": { - "decoratorMetadata": true, - "legacyDecorator": true - }, - "keepClassNames": true, - "externalHelpers": true, - "loose": true - }, - "module": { - "type": "es6" - }, - "sourceMaps": true, - "exclude": ["jest.config.ts",".*\\.spec.tsx?$",".*\\.test.tsx?$","./src/jest-setup.ts$","./**/jest-setup.ts$"] -} diff --git a/packages/turndown-plugin-gfm/package.json b/packages/turndown-plugin-gfm/package.json index 6834788b2..733e8d92f 100644 --- a/packages/turndown-plugin-gfm/package.json +++ b/packages/turndown-plugin-gfm/package.json @@ -56,9 +56,6 @@ } } }, - "dependencies": { - "@swc/helpers": "~0.5.11" - }, "devDependencies": { "turndown": "7.2.0", "turndown-attendant": "0.0.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a99738c1..cc0a5a9ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -73,18 +73,6 @@ importers: '@playwright/test': specifier: ^1.36.0 version: 1.52.0 - '@swc-node/register': - specifier: ~1.10.0 - version: 1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3) - '@swc/cli': - specifier: ~0.7.0 - version: 0.7.7(@swc/core@1.11.29(@swc/helpers@0.5.17))(chokidar@4.0.3) - '@swc/core': - specifier: ~1.11.0 - version: 1.11.29(@swc/helpers@0.5.17) - '@swc/helpers': - specifier: ~0.5.11 - version: 0.5.17 '@triliumnext/server': specifier: workspace:* version: link:apps/server @@ -136,9 +124,6 @@ importers: react-refresh: specifier: ^0.17.0 version: 0.17.0 - swc-loader: - specifier: 0.2.6 - version: 0.2.6(@swc/core@1.11.29(@swc/helpers@0.5.17))(webpack@5.99.9(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.25.4)) tslib: specifier: ^2.3.0 version: 2.8.1 @@ -1261,11 +1246,7 @@ importers: specifier: 9.27.0 version: 9.27.0 - packages/commons: - dependencies: - '@swc/helpers': - specifier: ~0.5.11 - version: 0.5.17 + packages/commons: {} packages/express-partial-content: dependencies: @@ -1292,10 +1273,6 @@ importers: version: 1.2.0 packages/turndown-plugin-gfm: - dependencies: - '@swc/helpers': - specifier: ~0.5.11 - version: 0.5.17 devDependencies: turndown: specifier: 7.2.0 @@ -3285,106 +3262,6 @@ packages: resolution: {integrity: sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==} engines: {node: '>=18'} - '@napi-rs/nice-android-arm-eabi@1.0.1': - resolution: {integrity: sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==} - engines: {node: '>= 10'} - cpu: [arm] - os: [android] - - '@napi-rs/nice-android-arm64@1.0.1': - resolution: {integrity: sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [android] - - '@napi-rs/nice-darwin-arm64@1.0.1': - resolution: {integrity: sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@napi-rs/nice-darwin-x64@1.0.1': - resolution: {integrity: sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@napi-rs/nice-freebsd-x64@1.0.1': - resolution: {integrity: sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [freebsd] - - '@napi-rs/nice-linux-arm-gnueabihf@1.0.1': - resolution: {integrity: sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@napi-rs/nice-linux-arm64-gnu@1.0.1': - resolution: {integrity: sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/nice-linux-arm64-musl@1.0.1': - resolution: {integrity: sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/nice-linux-ppc64-gnu@1.0.1': - resolution: {integrity: sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==} - engines: {node: '>= 10'} - cpu: [ppc64] - os: [linux] - - '@napi-rs/nice-linux-riscv64-gnu@1.0.1': - resolution: {integrity: sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==} - engines: {node: '>= 10'} - cpu: [riscv64] - os: [linux] - - '@napi-rs/nice-linux-s390x-gnu@1.0.1': - resolution: {integrity: sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==} - engines: {node: '>= 10'} - cpu: [s390x] - os: [linux] - - '@napi-rs/nice-linux-x64-gnu@1.0.1': - resolution: {integrity: sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/nice-linux-x64-musl@1.0.1': - resolution: {integrity: sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/nice-win32-arm64-msvc@1.0.1': - resolution: {integrity: sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@napi-rs/nice-win32-ia32-msvc@1.0.1': - resolution: {integrity: sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@napi-rs/nice-win32-x64-msvc@1.0.1': - resolution: {integrity: sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@napi-rs/nice@1.0.1': - resolution: {integrity: sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==} - engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} @@ -4252,9 +4129,6 @@ packages: '@scarf/scarf@1.4.0': resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@sideway/address@4.1.5': resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} @@ -4271,10 +4145,6 @@ packages: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} - '@sindresorhus/is@5.6.0': - resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} - engines: {node: '>=14.16'} - '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} @@ -4303,17 +4173,6 @@ packages: '@swc-node/sourcemap-support@0.5.1': resolution: {integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==} - '@swc/cli@0.7.7': - resolution: {integrity: sha512-j4yYm9bx3pxWofaJKX1BFwj/3ngUDynN4UIQ2Xd2h0h/7Gt7zkReBTpDN7g5S13mgAYxacaTHTOUsz18097E8w==} - engines: {node: '>= 16.14.0'} - hasBin: true - peerDependencies: - '@swc/core': ^1.2.66 - chokidar: ^4.0.1 - peerDependenciesMeta: - chokidar: - optional: true - '@swc/core-darwin-arm64@1.11.29': resolution: {integrity: sha512-whsCX7URzbuS5aET58c75Dloby3Gtj/ITk2vc4WW6pSDQKSPDuONsIcZ7B2ng8oz0K6ttbi4p3H/PNPQLJ4maQ==} engines: {node: '>=10'} @@ -4396,10 +4255,6 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@szmarczak/http-timer@5.0.1': - resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} - engines: {node: '>=14.16'} - '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} @@ -5152,46 +5007,6 @@ packages: '@webcomponents/webcomponentsjs@2.8.0': resolution: {integrity: sha512-loGD63sacRzOzSJgQnB9ZAhaQGkN7wl2Zuw7tsphI5Isa0irijrRo6EnJii/GgjGefIFO8AIO7UivzRhFaEk9w==} - '@xhmikosr/archive-type@7.0.0': - resolution: {integrity: sha512-sIm84ZneCOJuiy3PpWR5bxkx3HaNt1pqaN+vncUBZIlPZCq8ASZH+hBVdu5H8znR7qYC6sKwx+ie2Q7qztJTxA==} - engines: {node: ^14.14.0 || >=16.0.0} - - '@xhmikosr/bin-check@7.0.3': - resolution: {integrity: sha512-4UnCLCs8DB+itHJVkqFp9Zjg+w/205/J2j2wNBsCEAm/BuBmtua2hhUOdAMQE47b1c7P9Xmddj0p+X1XVsfHsA==} - engines: {node: '>=18'} - - '@xhmikosr/bin-wrapper@13.0.5': - resolution: {integrity: sha512-DT2SAuHDeOw0G5bs7wZbQTbf4hd8pJ14tO0i4cWhRkIJfgRdKmMfkDilpaJ8uZyPA0NVRwasCNAmMJcWA67osw==} - engines: {node: '>=18'} - - '@xhmikosr/decompress-tar@8.0.1': - resolution: {integrity: sha512-dpEgs0cQKJ2xpIaGSO0hrzz3Kt8TQHYdizHsgDtLorWajuHJqxzot9Hbi0huRxJuAGG2qiHSQkwyvHHQtlE+fg==} - engines: {node: '>=18'} - - '@xhmikosr/decompress-tarbz2@8.0.2': - resolution: {integrity: sha512-p5A2r/AVynTQSsF34Pig6olt9CvRj6J5ikIhzUd3b57pUXyFDGtmBstcw+xXza0QFUh93zJsmY3zGeNDlR2AQQ==} - engines: {node: '>=18'} - - '@xhmikosr/decompress-targz@8.0.1': - resolution: {integrity: sha512-mvy5AIDIZjQ2IagMI/wvauEiSNHhu/g65qpdM4EVoYHUJBAmkQWqcPJa8Xzi1aKVTmOA5xLJeDk7dqSjlHq8Mg==} - engines: {node: '>=18'} - - '@xhmikosr/decompress-unzip@7.0.0': - resolution: {integrity: sha512-GQMpzIpWTsNr6UZbISawsGI0hJ4KA/mz5nFq+cEoPs12UybAqZWKbyIaZZyLbJebKl5FkLpsGBkrplJdjvUoSQ==} - engines: {node: '>=18'} - - '@xhmikosr/decompress@10.0.1': - resolution: {integrity: sha512-6uHnEEt5jv9ro0CDzqWlFgPycdE+H+kbJnwyxgZregIMLQ7unQSCNVsYG255FoqU8cP46DyggI7F7LohzEl8Ag==} - engines: {node: '>=18'} - - '@xhmikosr/downloader@15.0.1': - resolution: {integrity: sha512-fiuFHf3Dt6pkX8HQrVBsK0uXtkgkVlhrZEh8b7VgoDqFf+zrgFBPyrwCqE/3nDwn3hLeNz+BsrS7q3mu13Lp1g==} - engines: {node: '>=18'} - - '@xhmikosr/os-filter-obj@3.0.0': - resolution: {integrity: sha512-siPY6BD5dQ2SZPl3I0OZBHL27ZqZvLEosObsZRQ1NUB8qcxegwt0T9eKtV96JMFQpIz1elhkzqOg4c/Ri6Dp9A==} - engines: {node: ^14.14.0 || >=16.0.0} - '@xmldom/xmldom@0.8.10': resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} engines: {node: '>=10.0.0'} @@ -5414,9 +5229,6 @@ packages: aproba@1.2.0: resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} - arch@3.0.0: - resolution: {integrity: sha512-AmIAC+Wtm2AU8lGfTtHsw0Y9Qtftx2YXEEtiBP10xFUtMOA+sHHx6OAddyL52mUKh1vsXQ6/w1mVDptZCyUt4Q==} - archiver-utils@5.0.2: resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} engines: {node: '>= 14'} @@ -5656,14 +5468,6 @@ packages: big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - bin-version-check@5.1.0: - resolution: {integrity: sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==} - engines: {node: '>=12'} - - bin-version@6.0.0: - resolution: {integrity: sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==} - engines: {node: '>=12'} - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -5799,14 +5603,6 @@ packages: resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} engines: {node: '>=10.6.0'} - cacheable-lookup@7.0.0: - resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} - engines: {node: '>=14.16'} - - cacheable-request@10.2.14: - resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} - engines: {node: '>=14.16'} - cacheable-request@7.0.4: resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} engines: {node: '>=8'} @@ -6100,10 +5896,6 @@ packages: resolution: {integrity: sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==} engines: {node: '>= 6'} - commander@6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} - commander@7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} @@ -6751,10 +6543,6 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - defaults@3.0.0: - resolution: {integrity: sha512-RsqXDEAALjfRTro+IFNKpcPCt0/Cy2FqHSIlnomiJp9YGadpQnrtbRpSgN2+np21qHcIKiva4fiOQGjS9/qR/A==} - engines: {node: '>=18'} - defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} @@ -7329,10 +7117,6 @@ packages: resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} engines: {node: '>=6'} - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - exif-parser@0.1.12: resolution: {integrity: sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==} @@ -7475,10 +7259,6 @@ packages: resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} engines: {node: '>=10'} - file-type@19.6.0: - resolution: {integrity: sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==} - engines: {node: '>=18'} - file-type@20.5.0: resolution: {integrity: sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==} engines: {node: '>=18'} @@ -7497,18 +7277,10 @@ packages: resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} engines: {node: '>=4'} - filename-reserved-regex@3.0.0: - resolution: {integrity: sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - filenamify@4.3.0: resolution: {integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==} engines: {node: '>=8'} - filenamify@6.0.0: - resolution: {integrity: sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==} - engines: {node: '>=16'} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -7541,10 +7313,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - find-versions@5.1.0: - resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} - engines: {node: '>=12'} - flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -7594,10 +7362,6 @@ packages: form-data-encoder@1.7.2: resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} - form-data-encoder@2.1.4: - resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} - engines: {node: '>= 14.17'} - form-data@3.0.3: resolution: {integrity: sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==} engines: {node: '>= 6'} @@ -7786,14 +7550,6 @@ packages: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - get-stream@9.0.1: - resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} - engines: {node: '>=18'} - get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} @@ -7908,10 +7664,6 @@ packages: resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} engines: {node: '>=10.19.0'} - got@13.0.0: - resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} - engines: {node: '>=16'} - graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -8116,10 +7868,6 @@ packages: resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} engines: {node: '>=10.19.0'} - http2-wrapper@2.2.1: - resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} - engines: {node: '>=10.19.0'} - https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -8128,10 +7876,6 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} @@ -8265,9 +8009,6 @@ packages: resolution: {integrity: sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==} engines: {node: ^18.17.0 || >=20.5.0} - inspect-with-kind@1.0.5: - resolution: {integrity: sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g==} - internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -8507,10 +8248,6 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-stream@4.0.1: - resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} - engines: {node: '>=18'} - is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -9111,10 +8848,6 @@ packages: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} - lowercase-keys@3.0.0: - resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -9369,10 +9102,6 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - mimic-response@4.0.0: - resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - mind-elixir@4.5.2: resolution: {integrity: sha512-PWPxspV56kdnR4PZ90QdCIPn4ckfHx/o6LTvtlHtlZNVhod5nCjFFFTp+28+wclmf2fg0+gOWU+bCGjrD6vv2Q==} @@ -9698,10 +9427,6 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} - normalize-url@8.0.1: - resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} - engines: {node: '>=14.16'} - normalize.css@8.0.1: resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==} @@ -9867,10 +9592,6 @@ packages: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} - p-cancelable@3.0.0: - resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} - engines: {node: '>=12.20'} - p-defer@1.0.0: resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} engines: {node: '>=4'} @@ -10089,10 +9810,6 @@ packages: resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} engines: {node: '>=8'} - peek-readable@5.4.2: - resolution: {integrity: sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==} - engines: {node: '>=14.16'} - peek-readable@7.0.0: resolution: {integrity: sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==} engines: {node: '>=18'} @@ -10134,9 +9851,6 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} - piscina@4.9.2: - resolution: {integrity: sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ==} - pixelmatch@5.3.0: resolution: {integrity: sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==} hasBin: true @@ -11182,10 +10896,6 @@ packages: responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} - responselike@3.0.0: - resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} - engines: {node: '>=14.16'} - resq@1.11.0: resolution: {integrity: sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==} @@ -11486,10 +11196,6 @@ packages: secure-compare@3.0.1: resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==} - seek-bzip@2.0.0: - resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==} - hasBin: true - select-hose@2.0.0: resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} @@ -11500,14 +11206,6 @@ packages: semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} - semver-regex@4.0.5: - resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} - engines: {node: '>=12'} - - semver-truncate@3.0.0: - resolution: {integrity: sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==} - engines: {node: '>=12'} - semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -11912,17 +11610,10 @@ packages: resolution: {integrity: sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A==} engines: {node: '>=12'} - strip-dirs@3.0.0: - resolution: {integrity: sha512-I0sdgcFTfKQlUPZyAqPJmSG3HLO9rWDFnxonnIbskYNM3DwFOeTNB5KzVq3dA1GdRAc/25b5Y7UO2TQfKWw4aQ==} - strip-eof@1.0.0: resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} engines: {node: '>=0.10.0'} - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -11949,10 +11640,6 @@ packages: resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} engines: {node: '>=10'} - strtok3@9.1.1: - resolution: {integrity: sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==} - engines: {node: '>=16'} - style-loader@2.0.0: resolution: {integrity: sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==} engines: {node: '>= 10.13.0'} @@ -12099,12 +11786,6 @@ packages: peerDependencies: express: '>=4.0.0 || >=5.0.0-beta' - swc-loader@0.2.6: - resolution: {integrity: sha512-9Zi9UP2YmDpgmQVbyOPJClY0dwf58JDyDMQ7uRc4krmc72twNI2fvlBWHLqVekBpPc7h5NJkGVT1zNDxFrqhvg==} - peerDependencies: - '@swc/core': ^1.2.147 - webpack: '>=2' - symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -12206,9 +11887,6 @@ packages: through2@4.0.2: resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - thunky@1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} @@ -12502,9 +12180,6 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - unbzip2-stream@1.4.3: - resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} - undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -16387,74 +16062,6 @@ snapshots: strict-event-emitter: 0.5.1 optional: true - '@napi-rs/nice-android-arm-eabi@1.0.1': - optional: true - - '@napi-rs/nice-android-arm64@1.0.1': - optional: true - - '@napi-rs/nice-darwin-arm64@1.0.1': - optional: true - - '@napi-rs/nice-darwin-x64@1.0.1': - optional: true - - '@napi-rs/nice-freebsd-x64@1.0.1': - optional: true - - '@napi-rs/nice-linux-arm-gnueabihf@1.0.1': - optional: true - - '@napi-rs/nice-linux-arm64-gnu@1.0.1': - optional: true - - '@napi-rs/nice-linux-arm64-musl@1.0.1': - optional: true - - '@napi-rs/nice-linux-ppc64-gnu@1.0.1': - optional: true - - '@napi-rs/nice-linux-riscv64-gnu@1.0.1': - optional: true - - '@napi-rs/nice-linux-s390x-gnu@1.0.1': - optional: true - - '@napi-rs/nice-linux-x64-gnu@1.0.1': - optional: true - - '@napi-rs/nice-linux-x64-musl@1.0.1': - optional: true - - '@napi-rs/nice-win32-arm64-msvc@1.0.1': - optional: true - - '@napi-rs/nice-win32-ia32-msvc@1.0.1': - optional: true - - '@napi-rs/nice-win32-x64-msvc@1.0.1': - optional: true - - '@napi-rs/nice@1.0.1': - optionalDependencies: - '@napi-rs/nice-android-arm-eabi': 1.0.1 - '@napi-rs/nice-android-arm64': 1.0.1 - '@napi-rs/nice-darwin-arm64': 1.0.1 - '@napi-rs/nice-darwin-x64': 1.0.1 - '@napi-rs/nice-freebsd-x64': 1.0.1 - '@napi-rs/nice-linux-arm-gnueabihf': 1.0.1 - '@napi-rs/nice-linux-arm64-gnu': 1.0.1 - '@napi-rs/nice-linux-arm64-musl': 1.0.1 - '@napi-rs/nice-linux-ppc64-gnu': 1.0.1 - '@napi-rs/nice-linux-riscv64-gnu': 1.0.1 - '@napi-rs/nice-linux-s390x-gnu': 1.0.1 - '@napi-rs/nice-linux-x64-gnu': 1.0.1 - '@napi-rs/nice-linux-x64-musl': 1.0.1 - '@napi-rs/nice-win32-arm64-msvc': 1.0.1 - '@napi-rs/nice-win32-ia32-msvc': 1.0.1 - '@napi-rs/nice-win32-x64-msvc': 1.0.1 - optional: true - '@napi-rs/wasm-runtime@0.2.4': dependencies: '@emnapi/core': 1.4.3 @@ -17436,8 +17043,6 @@ snapshots: '@scarf/scarf@1.4.0': {} - '@sec-ant/readable-stream@0.4.1': {} - '@sideway/address@4.1.5': dependencies: '@hapi/hoek': 9.3.0 @@ -17450,8 +17055,6 @@ snapshots: '@sindresorhus/is@4.6.0': {} - '@sindresorhus/is@5.6.0': {} - '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 @@ -17472,6 +17075,7 @@ snapshots: dependencies: '@swc/core': 1.11.29(@swc/helpers@0.5.17) '@swc/types': 0.1.21 + optional: true '@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3)': dependencies: @@ -17487,26 +17091,13 @@ snapshots: transitivePeerDependencies: - '@swc/types' - supports-color + optional: true '@swc-node/sourcemap-support@0.5.1': dependencies: source-map-support: 0.5.21 tslib: 2.8.1 - - '@swc/cli@0.7.7(@swc/core@1.11.29(@swc/helpers@0.5.17))(chokidar@4.0.3)': - dependencies: - '@swc/core': 1.11.29(@swc/helpers@0.5.17) - '@swc/counter': 0.1.3 - '@xhmikosr/bin-wrapper': 13.0.5 - commander: 8.3.0 - fast-glob: 3.3.3 - minimatch: 9.0.5 - piscina: 4.9.2 - semver: 7.7.1 - slash: 3.0.0 - source-map: 0.7.4 - optionalDependencies: - chokidar: 4.0.3 + optional: true '@swc/core-darwin-arm64@1.11.29': optional: true @@ -17569,10 +17160,6 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@szmarczak/http-timer@5.0.1': - dependencies: - defer-to-connect: 2.0.1 - '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.26.2 @@ -18578,74 +18165,6 @@ snapshots: '@webcomponents/webcomponentsjs@2.8.0': {} - '@xhmikosr/archive-type@7.0.0': - dependencies: - file-type: 19.6.0 - - '@xhmikosr/bin-check@7.0.3': - dependencies: - execa: 5.1.1 - isexe: 2.0.0 - - '@xhmikosr/bin-wrapper@13.0.5': - dependencies: - '@xhmikosr/bin-check': 7.0.3 - '@xhmikosr/downloader': 15.0.1 - '@xhmikosr/os-filter-obj': 3.0.0 - bin-version-check: 5.1.0 - - '@xhmikosr/decompress-tar@8.0.1': - dependencies: - file-type: 19.6.0 - is-stream: 2.0.1 - tar-stream: 3.1.7 - - '@xhmikosr/decompress-tarbz2@8.0.2': - dependencies: - '@xhmikosr/decompress-tar': 8.0.1 - file-type: 19.6.0 - is-stream: 2.0.1 - seek-bzip: 2.0.0 - unbzip2-stream: 1.4.3 - - '@xhmikosr/decompress-targz@8.0.1': - dependencies: - '@xhmikosr/decompress-tar': 8.0.1 - file-type: 19.6.0 - is-stream: 2.0.1 - - '@xhmikosr/decompress-unzip@7.0.0': - dependencies: - file-type: 19.6.0 - get-stream: 6.0.1 - yauzl: 3.2.0 - - '@xhmikosr/decompress@10.0.1': - dependencies: - '@xhmikosr/decompress-tar': 8.0.1 - '@xhmikosr/decompress-tarbz2': 8.0.2 - '@xhmikosr/decompress-targz': 8.0.1 - '@xhmikosr/decompress-unzip': 7.0.0 - graceful-fs: 4.2.11 - make-dir: 4.0.0 - strip-dirs: 3.0.0 - - '@xhmikosr/downloader@15.0.1': - dependencies: - '@xhmikosr/archive-type': 7.0.0 - '@xhmikosr/decompress': 10.0.1 - content-disposition: 0.5.4 - defaults: 3.0.0 - ext-name: 5.0.0 - file-type: 19.6.0 - filenamify: 6.0.0 - get-stream: 6.0.1 - got: 13.0.0 - - '@xhmikosr/os-filter-obj@3.0.0': - dependencies: - arch: 3.0.0 - '@xmldom/xmldom@0.8.10': {} '@xtuc/ieee754@1.2.0': {} @@ -18840,8 +18359,6 @@ snapshots: aproba@1.2.0: optional: true - arch@3.0.0: {} - archiver-utils@5.0.2: dependencies: glob: 10.4.5 @@ -19125,17 +18642,6 @@ snapshots: big.js@5.2.2: {} - bin-version-check@5.1.0: - dependencies: - bin-version: 6.0.0 - semver: 7.7.2 - semver-truncate: 3.0.0 - - bin-version@6.0.0: - dependencies: - execa: 5.1.1 - find-versions: 5.1.0 - binary-extensions@2.3.0: {} bindings@1.5.0: @@ -19337,18 +18843,6 @@ snapshots: cacheable-lookup@5.0.4: {} - cacheable-lookup@7.0.0: {} - - cacheable-request@10.2.14: - dependencies: - '@types/http-cache-semantics': 4.0.4 - get-stream: 6.0.1 - http-cache-semantics: 4.1.1 - keyv: 4.5.4 - mimic-response: 4.0.0 - normalize-url: 8.0.1 - responselike: 3.0.0 - cacheable-request@7.0.4: dependencies: clone-response: 1.0.3 @@ -19734,8 +19228,6 @@ snapshots: commander@6.2.0: {} - commander@6.2.1: {} - commander@7.2.0: {} commander@8.3.0: {} @@ -20482,8 +19974,6 @@ snapshots: dependencies: clone: 1.0.4 - defaults@3.0.0: {} - defer-to-connect@2.0.1: {} define-data-property@1.1.4: @@ -21202,18 +20692,6 @@ snapshots: signal-exit: 3.0.7 strip-eof: 1.0.0 - execa@5.1.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - exif-parser@0.1.12: {} exit@0.1.2: {} @@ -21408,13 +20886,6 @@ snapshots: strtok3: 6.3.0 token-types: 4.2.1 - file-type@19.6.0: - dependencies: - get-stream: 9.0.1 - strtok3: 9.1.1 - token-types: 6.0.0 - uint8array-extras: 1.4.0 - file-type@20.5.0: dependencies: '@tokenizer/inflate': 0.2.7 @@ -21434,18 +20905,12 @@ snapshots: filename-reserved-regex@2.0.0: {} - filename-reserved-regex@3.0.0: {} - filenamify@4.3.0: dependencies: filename-reserved-regex: 2.0.0 strip-outer: 1.0.1 trim-repeated: 1.0.0 - filenamify@6.0.0: - dependencies: - filename-reserved-regex: 3.0.0 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -21488,10 +20953,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - find-versions@5.1.0: - dependencies: - semver-regex: 4.0.5 - flat-cache@4.0.1: dependencies: flatted: 3.3.3 @@ -21558,8 +21019,6 @@ snapshots: form-data-encoder@1.7.2: {} - form-data-encoder@2.1.4: {} - form-data@3.0.3: dependencies: asynckit: 0.4.0 @@ -21781,13 +21240,6 @@ snapshots: dependencies: pump: 3.0.2 - get-stream@6.0.1: {} - - get-stream@9.0.1: - dependencies: - '@sec-ant/readable-stream': 0.4.1 - is-stream: 4.0.1 - get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 @@ -21950,20 +21402,6 @@ snapshots: p-cancelable: 2.1.1 responselike: 2.0.1 - got@13.0.0: - dependencies: - '@sindresorhus/is': 5.6.0 - '@szmarczak/http-timer': 5.0.1 - cacheable-lookup: 7.0.0 - cacheable-request: 10.2.14 - decompress-response: 6.0.0 - form-data-encoder: 2.1.4 - get-stream: 6.0.1 - http2-wrapper: 2.2.1 - lowercase-keys: 3.0.0 - p-cancelable: 3.0.0 - responselike: 3.0.0 - graceful-fs@4.2.11: {} grapheme-splitter@1.0.4: {} @@ -22207,11 +21645,6 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - http2-wrapper@2.2.1: - dependencies: - quick-lru: 5.1.1 - resolve-alpn: 1.2.1 - https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -22226,8 +21659,6 @@ snapshots: transitivePeerDependencies: - supports-color - human-signals@2.1.0: {} - humanize-ms@1.2.1: dependencies: ms: 2.1.3 @@ -22334,10 +21765,6 @@ snapshots: ini@5.0.0: {} - inspect-with-kind@1.0.5: - dependencies: - kind-of: 6.0.3 - internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -22538,8 +21965,6 @@ snapshots: is-stream@2.0.1: {} - is-stream@4.0.1: {} - is-string@1.1.1: dependencies: call-bound: 1.0.4 @@ -23386,8 +22811,6 @@ snapshots: lowercase-keys@2.0.0: {} - lowercase-keys@3.0.0: {} - lru-cache@10.4.3: {} lru-cache@5.1.1: @@ -23785,8 +23208,6 @@ snapshots: mimic-response@3.1.0: {} - mimic-response@4.0.0: {} - mind-elixir@4.5.2: {} mini-css-extract-plugin@2.4.7(webpack@5.99.9(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.25.4)): @@ -24167,8 +23588,6 @@ snapshots: normalize-url@6.1.0: {} - normalize-url@8.0.1: {} - normalize.css@8.0.1: {} npm-package-arg@11.0.1: @@ -24422,11 +23841,10 @@ snapshots: '@oxc-resolver/binding-wasm32-wasi': 5.3.0 '@oxc-resolver/binding-win32-arm64-msvc': 5.3.0 '@oxc-resolver/binding-win32-x64-msvc': 5.3.0 + optional: true p-cancelable@2.1.1: {} - p-cancelable@3.0.0: {} - p-defer@1.0.0: {} p-finally@1.0.0: {} @@ -24629,8 +24047,6 @@ snapshots: peek-readable@4.1.0: {} - peek-readable@5.4.2: {} - peek-readable@7.0.0: {} pend@1.2.0: {} @@ -24660,10 +24076,6 @@ snapshots: pirates@4.0.7: {} - piscina@4.9.2: - optionalDependencies: - '@napi-rs/nice': 1.0.1 - pixelmatch@5.3.0: dependencies: pngjs: 6.0.0 @@ -25706,10 +25118,6 @@ snapshots: dependencies: lowercase-keys: 2.0.0 - responselike@3.0.0: - dependencies: - lowercase-keys: 3.0.0 - resq@1.11.0: dependencies: fast-deep-equal: 2.0.1 @@ -26040,10 +25448,6 @@ snapshots: secure-compare@3.0.1: {} - seek-bzip@2.0.0: - dependencies: - commander: 6.2.1 - select-hose@2.0.0: {} selfsigned@2.4.1: @@ -26054,12 +25458,6 @@ snapshots: semver-compare@1.0.0: optional: true - semver-regex@4.0.5: {} - - semver-truncate@3.0.0: - dependencies: - semver: 7.7.2 - semver@5.7.2: {} semver@6.3.1: {} @@ -26531,15 +25929,8 @@ snapshots: strip-bom@5.0.0: {} - strip-dirs@3.0.0: - dependencies: - inspect-with-kind: 1.0.5 - is-plain-obj: 1.1.0 - strip-eof@1.0.0: {} - strip-final-newline@2.0.0: {} - strip-json-comments@2.0.1: {} strip-json-comments@3.1.1: {} @@ -26562,11 +25953,6 @@ snapshots: '@tokenizer/token': 0.3.0 peek-readable: 4.1.0 - strtok3@9.1.1: - dependencies: - '@tokenizer/token': 0.3.0 - peek-readable: 5.4.2 - style-loader@2.0.0(webpack@5.99.9(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.25.4)): dependencies: loader-utils: 2.0.4 @@ -26823,12 +26209,6 @@ snapshots: express: 4.21.2 swagger-ui-dist: 5.21.0 - swc-loader@0.2.6(@swc/core@1.11.29(@swc/helpers@0.5.17))(webpack@5.99.9(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.25.4)): - dependencies: - '@swc/core': 1.11.29(@swc/helpers@0.5.17) - '@swc/counter': 0.1.3 - webpack: 5.99.9(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.25.4) - symbol-tree@3.2.4: {} sync-child-process@1.0.2: @@ -26993,8 +26373,6 @@ snapshots: dependencies: readable-stream: 3.6.2 - through@2.3.8: {} - thunky@1.1.0: {} time2fa@1.4.2: {} @@ -27302,11 +26680,6 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - unbzip2-stream@1.4.3: - dependencies: - buffer: 5.7.1 - through: 2.3.8 - undici-types@6.19.8: {} undici-types@6.21.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index eb7c37832..f7e733b59 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,7 +8,6 @@ ignoredBuiltDependencies: onlyBuiltDependencies: - '@parcel/watcher' - '@scarf/scarf' -- '@swc/core' - bufferutil - core-js-pure - esbuild From fe8e090b1b26774ab28a2bffff4568b1405538f9 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 27 May 2025 23:33:45 +0300 Subject: [PATCH 05/19] chore(codemirror): fix type errors --- packages/codemirror/src/extensions/custom_tab.ts | 6 +++--- packages/codemirror/tsconfig.spec.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/codemirror/src/extensions/custom_tab.ts b/packages/codemirror/src/extensions/custom_tab.ts index 2355ce90f..c8ced1df2 100644 --- a/packages/codemirror/src/extensions/custom_tab.ts +++ b/packages/codemirror/src/extensions/custom_tab.ts @@ -1,5 +1,5 @@ import { indentLess, indentMore } from "@codemirror/commands"; -import { EditorSelection, EditorState, type ChangeSpec } from "@codemirror/state"; +import { EditorSelection, EditorState, SelectionRange, type ChangeSpec } from "@codemirror/state"; import type { KeyBinding } from "@codemirror/view"; /** @@ -19,8 +19,8 @@ const smartIndentWithTab: KeyBinding[] = [ } const { selection } = state; - const changes = []; - const newSelections = []; + const changes: ChangeSpec[] = []; + const newSelections: SelectionRange[] = []; // Step 1: Handle non-empty selections → replace with tab if (selection.ranges.some(range => !range.empty)) { diff --git a/packages/codemirror/tsconfig.spec.json b/packages/codemirror/tsconfig.spec.json index fbd68ed60..f7f4942ed 100644 --- a/packages/codemirror/tsconfig.spec.json +++ b/packages/codemirror/tsconfig.spec.json @@ -23,6 +23,6 @@ "src/**/*.spec.js", "src/**/*.test.jsx", "src/**/*.spec.jsx", - "src/**/*.d.ts" + "src/**/*.ts" ] } From 7972d3f31bc06639c4903a39f33c17d0aac588bd Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 27 May 2025 23:36:41 +0300 Subject: [PATCH 06/19] chore(ckeditor5): fix type errors --- .../src/plugins/syntax_highlighting/index.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/ckeditor5/src/plugins/syntax_highlighting/index.ts b/packages/ckeditor5/src/plugins/syntax_highlighting/index.ts index 894939374..ef6430331 100644 --- a/packages/ckeditor5/src/plugins/syntax_highlighting/index.ts +++ b/packages/ckeditor5/src/plugins/syntax_highlighting/index.ts @@ -1,7 +1,12 @@ -import type { Element, Writer } from "ckeditor5"; +import type { Element, Position, Writer } from "ckeditor5"; import type { Node, Editor } from "ckeditor5"; import { Plugin } from "ckeditor5"; +interface SpanStackEntry { + className: string; + posStart: Position; +} + /* * This code is an adaptation of https://github.com/antoniotejada/Trilium-SyntaxHighlightWidget with additional improvements, such as: * @@ -234,10 +239,10 @@ export default class SyntaxHighlighting extends Plugin { let iHtml = 0; let html = highlightRes.value; - let spanStack = []; + let spanStack: SpanStackEntry[] = []; let iChild = -1; let childText = ""; - let child = null; + let child: Node | null = null; let iChildText = 0; while (iHtml < html.length) { From 8578aa26c16515787af3a531e15f8ec22026d066 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 27 May 2025 23:43:28 +0300 Subject: [PATCH 07/19] chore(types): disable verbatim module syntax for now --- apps/db-compare/tsconfig.app.json | 3 +-- apps/server-e2e/tsconfig.json | 3 +-- tsconfig.base.json | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/db-compare/tsconfig.app.json b/apps/db-compare/tsconfig.app.json index c5944cc79..bdf9ba861 100644 --- a/apps/db-compare/tsconfig.app.json +++ b/apps/db-compare/tsconfig.app.json @@ -6,8 +6,7 @@ "node" ], "rootDir": "src", - "tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo", - "verbatimModuleSyntax": false + "tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo" }, "include": [ "src/**/*.ts" diff --git a/apps/server-e2e/tsconfig.json b/apps/server-e2e/tsconfig.json index 5e023db98..1df867f3a 100644 --- a/apps/server-e2e/tsconfig.json +++ b/apps/server-e2e/tsconfig.json @@ -3,8 +3,7 @@ "compilerOptions": { "allowJs": true, "outDir": "out-tsc/playwright", - "sourceMap": false, - "verbatimModuleSyntax": false + "sourceMap": false }, "include": [ "**/*.ts", diff --git a/tsconfig.base.json b/tsconfig.base.json index 87eba8adc..76d2e73fc 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -18,7 +18,7 @@ "strict": true, "target": "es2022", "customConditions": ["development"], - "verbatimModuleSyntax": true, + "verbatimModuleSyntax": false, // TODO: Re-enable it when migrating back to ESM. "resolveJsonModule": true, "downlevelIteration": true, "esModuleInterop": true, From c4e10b6eba922295d4a6ae04952732cb8fc5c3ac Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 27 May 2025 23:49:33 +0300 Subject: [PATCH 08/19] fix(commons): not importable due to wrong meta --- packages/commons/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/commons/package.json b/packages/commons/package.json index 045e8902e..116d182e9 100644 --- a/packages/commons/package.json +++ b/packages/commons/package.json @@ -4,16 +4,16 @@ "description": "Shared library between the clients (e.g. browser, Electron) and the server, mostly for type definitions and utility methods.", "private": true, "type": "module", - "main": "./dist/index.js", - "module": "./dist/index.js", + "main": "./dist/main.js", + "module": "./dist/main.js", "types": "./dist/index.d.ts", "exports": { "./package.json": "./package.json", ".": { "development": "./src/index.ts", "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "default": "./dist/index.js" + "import": "./dist/main.js", + "default": "./dist/main.js" } }, "license": "AGPL-3.0-only", From 811f0ea2bfea560094879decc8b3f5c0fb34eb07 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 28 May 2025 00:00:59 +0300 Subject: [PATCH 09/19] chore(server,desktop): re-enable strict mode --- apps/desktop/tsconfig.app.json | 1 - apps/server/tsconfig.app.json | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/desktop/tsconfig.app.json b/apps/desktop/tsconfig.app.json index 1c37e3a04..24b95c5ed 100644 --- a/apps/desktop/tsconfig.app.json +++ b/apps/desktop/tsconfig.app.json @@ -5,7 +5,6 @@ "moduleResolution": "bundler", "target": "ES2020", "outDir": "dist", - "strict": false, "types": [ "node", "express" diff --git a/apps/server/tsconfig.app.json b/apps/server/tsconfig.app.json index e5ff1c88f..591b4a5db 100644 --- a/apps/server/tsconfig.app.json +++ b/apps/server/tsconfig.app.json @@ -5,7 +5,6 @@ "moduleResolution": "bundler", "target": "ES2020", "outDir": "dist", - "strict": false, "types": [ "node", "express" From 05c4721bd5082ae938f64913dbe78e9dec3e105d Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 28 May 2025 00:05:16 +0300 Subject: [PATCH 10/19] chore(server): type error due to ESM vs CJS --- apps/server/{vite.config.ts => vite.config.mts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/server/{vite.config.ts => vite.config.mts} (100%) diff --git a/apps/server/vite.config.ts b/apps/server/vite.config.mts similarity index 100% rename from apps/server/vite.config.ts rename to apps/server/vite.config.mts From ba7c93967ee4d3436db01ae72c1b1600fc371061 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 28 May 2025 19:03:53 +0300 Subject: [PATCH 11/19] chore(server): fix some type errors --- apps/server/src/becca/becca-interface.ts | 2 +- apps/server/src/becca/becca_service.ts | 2 +- apps/server/src/becca/entities/bnote.ts | 2 +- apps/server/src/becca/similarity.ts | 2 +- apps/server/src/routes/api/note_map.ts | 11 +++++++--- apps/server/src/routes/api/options.ts | 8 ++++++- apps/server/src/routes/api/recent_changes.ts | 2 +- apps/server/src/routes/api/script.ts | 6 ++--- apps/server/src/routes/api/sql.ts | 11 +++++++--- apps/server/src/routes/api/tree.ts | 7 +++--- apps/server/src/services/content_hash.ts | 7 +++++- .../src/services/llm/context/code_handlers.ts | 22 +++++++++---------- .../services/llm/context/content_chunking.ts | 2 +- .../query_decomposition_tool.ts | 2 +- .../llm/embeddings/base_embeddings.ts | 2 +- .../src/services/llm/embeddings/queue.ts | 21 +++++++++++++++--- .../pipeline/stages/model_selection_stage.ts | 2 +- .../search/expressions/note_flat_text.ts | 8 +++---- packages/commons/src/lib/rows.ts | 16 +++++++------- 19 files changed, 86 insertions(+), 49 deletions(-) diff --git a/apps/server/src/becca/becca-interface.ts b/apps/server/src/becca/becca-interface.ts index 7620ef3f5..005a5cc52 100644 --- a/apps/server/src/becca/becca-interface.ts +++ b/apps/server/src/becca/becca-interface.ts @@ -251,7 +251,7 @@ export default class Becca { getAllNoteSet() { // caching this since it takes 10s of milliseconds to fill this initial NoteSet for many notes if (!this.allNoteSetCache) { - const allNotes = []; + const allNotes: BNote[] = []; for (const noteId in this.notes) { const note = this.notes[noteId]; diff --git a/apps/server/src/becca/becca_service.ts b/apps/server/src/becca/becca_service.ts index 8f54728ca..92967da34 100644 --- a/apps/server/src/becca/becca_service.ts +++ b/apps/server/src/becca/becca_service.ts @@ -76,7 +76,7 @@ function getNoteTitleArrayForPath(notePathArray: string[]) { return [getNoteTitle(notePathArray[0])]; } - const titles = []; + const titles: string[] = []; let parentNoteId = "root"; let hoistedNotePassed = false; diff --git a/apps/server/src/becca/entities/bnote.ts b/apps/server/src/becca/entities/bnote.ts index 3813b5bbc..570d1b7b7 100644 --- a/apps/server/src/becca/entities/bnote.ts +++ b/apps/server/src/becca/entities/bnote.ts @@ -388,7 +388,7 @@ class BNote extends AbstractBeccaEntity { } } - const templateAttributes = []; + const templateAttributes: BAttribute[] = []; for (const ownedAttr of parentAttributes) { // parentAttributes so we process also inherited templates diff --git a/apps/server/src/becca/similarity.ts b/apps/server/src/becca/similarity.ts index 8f4bdf0ff..fe7ecda21 100644 --- a/apps/server/src/becca/similarity.ts +++ b/apps/server/src/becca/similarity.ts @@ -254,7 +254,7 @@ function hasConnectingRelation(sourceNote: BNote, targetNote: BNote) { } async function findSimilarNotes(noteId: string): Promise { - const results = []; + const results: SimilarNote[] = []; let i = 0; const baseNote = becca.notes[noteId]; diff --git a/apps/server/src/routes/api/note_map.ts b/apps/server/src/routes/api/note_map.ts index f621c7b2f..470152bd6 100644 --- a/apps/server/src/routes/api/note_map.ts +++ b/apps/server/src/routes/api/note_map.ts @@ -12,6 +12,11 @@ interface Backlink { excerpts?: string[]; } +interface TreeLink { + sourceNoteId: string; + targetNoteId: string; +} + function buildDescendantCountMap(noteIdsToCount: string[]) { if (!Array.isArray(noteIdsToCount)) { throw new Error("noteIdsToCount: type error"); @@ -50,7 +55,7 @@ function getNeighbors(note: BNote, depth: number): string[] { return []; } - const retNoteIds = []; + const retNoteIds: string[] = []; function isIgnoredRelation(relation: BAttribute) { return ["relationMapLink", "template", "inherit", "image", "ancestor"].includes(relation.name); @@ -196,7 +201,7 @@ function getTreeMap(req: Request) { const noteIds = new Set(); notes.forEach(([noteId]) => noteId && noteIds.add(noteId)); - const links = []; + const links: TreeLink[] = []; for (const { parentNoteId, childNoteId } of subtree.relationships) { if (!noteIds.has(parentNoteId) || !noteIds.has(childNoteId)) { @@ -246,7 +251,7 @@ function findExcerpts(sourceNote: BNote, referencedNoteId: string) { const html = sourceNote.getContent(); const document = new JSDOM(html).window.document; - const excerpts = []; + const excerpts: string[] = []; removeImages(document); diff --git a/apps/server/src/routes/api/options.ts b/apps/server/src/routes/api/options.ts index 3a0a9b06b..c69f7568f 100644 --- a/apps/server/src/routes/api/options.ts +++ b/apps/server/src/routes/api/options.ts @@ -9,6 +9,12 @@ import { changeLanguage, getLocales } from "../../services/i18n.js"; import type { OptionNames } from "@triliumnext/commons"; import config from "../../services/config.js"; +interface UserTheme { + val: string; // value of the theme, used in the URL + title: string; // title of the theme, displayed in the UI + noteId: string; // ID of the note containing the theme +} + // options allowed to be updated directly in the Options dialog const ALLOWED_OPTIONS = new Set([ "eraseEntitiesAfterTimeInSeconds", @@ -177,7 +183,7 @@ function update(name: string, value: string) { function getUserThemes() { const notes = searchService.searchNotes("#appTheme", { ignoreHoistedNote: true }); - const ret = []; + const ret: UserTheme[] = []; for (const note of notes) { let value = note.getOwnedLabelValue("appTheme"); diff --git a/apps/server/src/routes/api/recent_changes.ts b/apps/server/src/routes/api/recent_changes.ts index 67b7436a0..1e539710e 100644 --- a/apps/server/src/routes/api/recent_changes.ts +++ b/apps/server/src/routes/api/recent_changes.ts @@ -21,7 +21,7 @@ interface RecentChangeRow { function getRecentChanges(req: Request) { const { ancestorNoteId } = req.params; - let recentChanges = []; + let recentChanges: RecentChangeRow[] = []; const revisionRows = sql.getRows(` SELECT diff --git a/apps/server/src/routes/api/script.ts b/apps/server/src/routes/api/script.ts index c702a82d8..d9d2fac8f 100644 --- a/apps/server/src/routes/api/script.ts +++ b/apps/server/src/routes/api/script.ts @@ -1,6 +1,6 @@ "use strict"; -import scriptService from "../../services/script.js"; +import scriptService, { type Bundle } from "../../services/script.js"; import attributeService from "../../services/attributes.js"; import becca from "../../becca/becca.js"; import syncService from "../../services/sync.js"; @@ -54,7 +54,7 @@ function run(req: Request) { function getBundlesWithLabel(label: string, value?: string) { const notes = attributeService.getNotesWithLabel(label, value); - const bundles = []; + const bundles: Bundle[] = []; for (const note of notes) { const bundle = scriptService.getScriptBundleForFrontend(note); @@ -97,7 +97,7 @@ function getRelationBundles(req: Request) { const targetNoteIds = filtered.map((relation) => relation.value); const uniqueNoteIds = Array.from(new Set(targetNoteIds)); - const bundles = []; + const bundles: Bundle[] = []; for (const noteId of uniqueNoteIds) { const note = becca.getNoteOrThrow(noteId); diff --git a/apps/server/src/routes/api/sql.ts b/apps/server/src/routes/api/sql.ts index ce2fc5127..0a1fbb28d 100644 --- a/apps/server/src/routes/api/sql.ts +++ b/apps/server/src/routes/api/sql.ts @@ -6,9 +6,14 @@ import type { Request } from "express"; import ValidationError from "../../errors/validation_error.js"; import { safeExtractMessageAndStackFromError } from "../../services/utils.js"; +interface Table { + name: string; + columns: unknown[]; +} + function getSchema() { - const tableNames = sql.getColumn(/*sql*/`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`); - const tables = []; + const tableNames = sql.getColumn(/*sql*/`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`); + const tables: Table[] = []; for (const tableName of tableNames) { tables.push({ @@ -31,7 +36,7 @@ function execute(req: Request) { const queries = content.split("\n---"); try { - const results = []; + const results: unknown[] = []; for (let query of queries) { query = query.trim(); diff --git a/apps/server/src/routes/api/tree.ts b/apps/server/src/routes/api/tree.ts index 885529c93..bd6c9bb61 100644 --- a/apps/server/src/routes/api/tree.ts +++ b/apps/server/src/routes/api/tree.ts @@ -5,6 +5,7 @@ import log from "../../services/log.js"; import NotFoundError from "../../errors/not_found_error.js"; import type { Request } from "express"; import type BNote from "../../becca/entities/bnote.js"; +import type { AttributeRow, BranchRow, NoteRow } from "@triliumnext/commons"; function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set) { const noteIds = new Set(_noteIds); @@ -53,7 +54,7 @@ function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set) { collectEntityIds(note); } - const notes = []; + const notes: NoteRow[] = []; for (const noteId of collectedNoteIds) { const note = becca.notes[noteId]; @@ -68,7 +69,7 @@ function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set) { }); } - const branches = []; + const branches: BranchRow[] = []; if (noteIds.has("root")) { branches.push({ @@ -99,7 +100,7 @@ function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set) { }); } - const attributes = []; + const attributes: AttributeRow[] = []; for (const attributeId of collectedAttributeIds) { const attribute = becca.attributes[attributeId]; diff --git a/apps/server/src/services/content_hash.ts b/apps/server/src/services/content_hash.ts index 0247bd335..6c8365e2b 100644 --- a/apps/server/src/services/content_hash.ts +++ b/apps/server/src/services/content_hash.ts @@ -7,6 +7,11 @@ import eraseService from "./erase.js"; type SectorHash = Record; +interface FailedCheck { + entityName: string; + sector: string[1]; +} + function getEntityHashes() { // blob erasure is not synced, we should check before each sync if there's some blob to erase eraseService.eraseUnusedBlobs(); @@ -56,7 +61,7 @@ function getEntityHashes() { function checkContentHashes(otherHashes: Record) { const entityHashes = getEntityHashes(); - const failedChecks = []; + const failedChecks: FailedCheck[] = []; for (const entityName in entityHashes) { const thisSectorHashes: SectorHash = entityHashes[entityName] || {}; diff --git a/apps/server/src/services/llm/context/code_handlers.ts b/apps/server/src/services/llm/context/code_handlers.ts index f4b1fca97..6a7d0f7af 100644 --- a/apps/server/src/services/llm/context/code_handlers.ts +++ b/apps/server/src/services/llm/context/code_handlers.ts @@ -160,7 +160,7 @@ function extractJsStructure(content: string): string { } // Look for class declarations - const classes = []; + const classes: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.startsWith('class ') || line.includes(' class ')) { @@ -173,7 +173,7 @@ function extractJsStructure(content: string): string { } // Look for function declarations - const functions = []; + const functions: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.startsWith('function ') || @@ -212,7 +212,7 @@ function extractPythonStructure(content: string): string { } // Look for class declarations - const classes = []; + const classes: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.startsWith('class ')) { @@ -225,7 +225,7 @@ function extractPythonStructure(content: string): string { } // Look for function declarations - const functions = []; + const functions: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.startsWith('def ')) { @@ -263,7 +263,7 @@ function extractClassBasedStructure(content: string): string { } // Look for class declarations - const classes = []; + const classes: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.match(/^(public|private|protected)?\s*(class|interface|enum)\s+\w+/)) { @@ -276,7 +276,7 @@ function extractClassBasedStructure(content: string): string { } // Look for method declarations - const methods = []; + const methods: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.match(/^(public|private|protected)?\s*(static)?\s*[\w<>[\]]+\s+\w+\s*\(/)) { @@ -319,7 +319,7 @@ function extractGoStructure(content: string): string { } // Look for type declarations (structs, interfaces) - const types = []; + const types: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.startsWith('type ') && (line.includes(' struct ') || line.includes(' interface '))) { @@ -332,7 +332,7 @@ function extractGoStructure(content: string): string { } // Look for function declarations - const functions = []; + const functions: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.startsWith('func ')) { @@ -366,7 +366,7 @@ function extractRustStructure(content: string): string { } // Look for struct/enum/trait declarations - const types = []; + const types: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.startsWith('struct ') || line.startsWith('enum ') || line.startsWith('trait ')) { @@ -379,8 +379,8 @@ function extractRustStructure(content: string): string { } // Look for function/impl declarations - const functions = []; - const impls = []; + const functions: string[] = []; + const impls: string[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); diff --git a/apps/server/src/services/llm/context/content_chunking.ts b/apps/server/src/services/llm/context/content_chunking.ts index a9f032684..0e57da515 100644 --- a/apps/server/src/services/llm/context/content_chunking.ts +++ b/apps/server/src/services/llm/context/content_chunking.ts @@ -198,7 +198,7 @@ export async function semanticChunking( // Try to split on headers first const headerPattern = /#{1,6}\s+.+|]*>.*?<\/h[1-6]>/g; - const sections = []; + const sections: string[] = []; let lastIndex = 0; let match; diff --git a/apps/server/src/services/llm/context_extractors/query_decomposition_tool.ts b/apps/server/src/services/llm/context_extractors/query_decomposition_tool.ts index 2e65ada76..917403abb 100644 --- a/apps/server/src/services/llm/context_extractors/query_decomposition_tool.ts +++ b/apps/server/src/services/llm/context_extractors/query_decomposition_tool.ts @@ -439,7 +439,7 @@ export class QueryDecompositionTool { // If no pattern match, try to extract noun phrases const words = query.split(/\s+/); - const potentialEntities = []; + const potentialEntities: string[] = []; let currentPhrase = ''; for (const word of words) { diff --git a/apps/server/src/services/llm/embeddings/base_embeddings.ts b/apps/server/src/services/llm/embeddings/base_embeddings.ts index ffc57174c..0332bbf51 100644 --- a/apps/server/src/services/llm/embeddings/base_embeddings.ts +++ b/apps/server/src/services/llm/embeddings/base_embeddings.ts @@ -246,7 +246,7 @@ export abstract class BaseEmbeddingProvider { */ protected generateNoteContextText(context: NoteEmbeddingContext): string { // Build a relationship-focused summary first - const relationshipSummary = []; + const relationshipSummary: string[] = []; // Summarize the note's place in the hierarchy if (context.parentTitles.length > 0) { diff --git a/apps/server/src/services/llm/embeddings/queue.ts b/apps/server/src/services/llm/embeddings/queue.ts index 1b27559d1..6b3b5e415 100644 --- a/apps/server/src/services/llm/embeddings/queue.ts +++ b/apps/server/src/services/llm/embeddings/queue.ts @@ -13,6 +13,21 @@ import indexService from '../index_service.js'; // Track which notes are currently being processed const notesInProcess = new Set(); +interface FailedItemRow { + noteId: string; + operation: string; + attempts: number; + lastAttempt: string; + error: string | null; + failed: number; +} + +interface FailedItemWithTitle extends FailedItemRow { + title?: string; + failureType: 'chunks' | 'full'; + isPermanent: boolean; +} + /** * Queues a note for embedding update */ @@ -77,17 +92,17 @@ export async function queueNoteForEmbedding(noteId: string, operation = 'UPDATE' */ export async function getFailedEmbeddingNotes(limit: number = 100): Promise { // Get notes with failed embedding attempts or permanently failed flag - const failedQueueItems = await sql.getRows(` + const failedQueueItems = sql.getRows(` SELECT noteId, operation, attempts, lastAttempt, error, failed FROM embedding_queue WHERE attempts > 0 OR failed = 1 ORDER BY failed DESC, attempts DESC, lastAttempt DESC LIMIT ?`, [limit] - ) as {noteId: string, operation: string, attempts: number, lastAttempt: string, error: string, failed: number}[]; + ); // Add titles to the failed notes - const failedNotesWithTitles = []; + const failedNotesWithTitles: FailedItemWithTitle[] = []; for (const item of failedQueueItems) { const note = becca.getNote(item.noteId); if (note) { diff --git a/apps/server/src/services/llm/pipeline/stages/model_selection_stage.ts b/apps/server/src/services/llm/pipeline/stages/model_selection_stage.ts index 35634c210..e5406997d 100644 --- a/apps/server/src/services/llm/pipeline/stages/model_selection_stage.ts +++ b/apps/server/src/services/llm/pipeline/stages/model_selection_stage.ts @@ -95,7 +95,7 @@ export class ModelSelectionStage extends BasePipelineStage p.trim()); } else if (providerPrecedence.startsWith('[') && providerPrecedence.endsWith(']')) { diff --git a/apps/server/src/services/search/expressions/note_flat_text.ts b/apps/server/src/services/search/expressions/note_flat_text.ts index 163dd38a0..1f4d4d87a 100644 --- a/apps/server/src/services/search/expressions/note_flat_text.ts +++ b/apps/server/src/services/search/expressions/note_flat_text.ts @@ -52,7 +52,7 @@ class NoteFlatTextExp extends Expression { return; } - const foundAttrTokens = []; + const foundAttrTokens: string[] = []; for (const token of remainingTokens) { if (note.type.includes(token) || note.mime.includes(token)) { @@ -73,7 +73,7 @@ class NoteFlatTextExp extends Expression { for (const parentNote of note.parents) { const title = normalize(beccaService.getNoteTitle(note.noteId, parentNote.noteId)); - const foundTokens = foundAttrTokens.slice(); + const foundTokens: string[] = foundAttrTokens.slice(); for (const token of remainingTokens) { if (title.includes(token)) { @@ -100,7 +100,7 @@ class NoteFlatTextExp extends Expression { continue; } - const foundAttrTokens = []; + const foundAttrTokens: string[] = []; for (const token of this.tokens) { if (note.type.includes(token) || note.mime.includes(token)) { @@ -153,7 +153,7 @@ class NoteFlatTextExp extends Expression { * Returns noteIds which have at least one matching tokens */ getCandidateNotes(noteSet: NoteSet): BNote[] { - const candidateNotes = []; + const candidateNotes: BNote[] = []; for (const note of noteSet.notes) { for (const token of this.tokens) { diff --git a/packages/commons/src/lib/rows.ts b/packages/commons/src/lib/rows.ts index 6b7d73a7e..735146eeb 100644 --- a/packages/commons/src/lib/rows.ts +++ b/packages/commons/src/lib/rows.ts @@ -126,17 +126,17 @@ export type NoteType = (typeof ALLOWED_NOTE_TYPES)[number]; export interface NoteRow { noteId: string; - deleteId: string; + deleteId?: string; title: string; type: NoteType; mime: string; - isProtected: boolean; - isDeleted: boolean; - blobId: string; - dateCreated: string; - dateModified: string; - utcDateCreated: string; - utcDateModified: string; + isProtected?: boolean; + isDeleted?: boolean; + blobId?: string; + dateCreated?: string; + dateModified?: string; + utcDateCreated?: string; + utcDateModified?: string; content?: string | Buffer; } From ff106e21cfc37fad6d1a97c924096737f151a0a2 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 28 May 2025 19:57:55 +0300 Subject: [PATCH 12/19] chore(server): fix more type errors --- apps/server/src/services/i18n.ts | 2 +- apps/server/src/services/import/opml.ts | 2 +- apps/server/src/services/llm/ai_interface.ts | 4 +- .../llm/embeddings/embeddings_interface.ts | 24 ++++++----- .../src/services/llm/embeddings/storage.ts | 10 ++++- .../llm/providers/anthropic_service.ts | 25 ++++++++--- .../src/services/llm/providers/providers.ts | 2 +- .../llm/tools/content_extraction_tool.ts | 42 ++++++++++++++----- .../services/llm/tools/note_creation_tool.ts | 3 +- .../services/llm/tools/relationship_tool.ts | 14 +++++-- apps/server/src/services/notes.ts | 2 +- apps/server/src/services/script.ts | 4 +- .../src/services/search/services/parse.ts | 4 +- .../src/services/search/services/search.ts | 2 +- .../server/src/share/shaca/shaca-interface.ts | 2 +- 15 files changed, 99 insertions(+), 43 deletions(-) diff --git a/apps/server/src/services/i18n.ts b/apps/server/src/services/i18n.ts index 3bdf6f9cd..3e1f4d1a6 100644 --- a/apps/server/src/services/i18n.ts +++ b/apps/server/src/services/i18n.ts @@ -51,7 +51,7 @@ export function getLocales(): Locale[] { } function getCurrentLanguage(): LOCALE_IDS { - let language: string; + let language: string | null = null; if (sql_init.isDbInitialized()) { language = options.getOptionOrNull("locale"); } diff --git a/apps/server/src/services/import/opml.ts b/apps/server/src/services/import/opml.ts index cdc01011f..934578c70 100644 --- a/apps/server/src/services/import/opml.ts +++ b/apps/server/src/services/import/opml.ts @@ -84,7 +84,7 @@ async function importOpml(taskContext: TaskContext, fileBuffer: string | Buffer, } const outlines = xml.opml.body[0].outline || []; - let returnNote = null; + let returnNote: BNote | null = null; for (const outline of outlines) { const note = importOutline(outline, parentNote.noteId); diff --git a/apps/server/src/services/llm/ai_interface.ts b/apps/server/src/services/llm/ai_interface.ts index b8349b5b2..df8cc6914 100644 --- a/apps/server/src/services/llm/ai_interface.ts +++ b/apps/server/src/services/llm/ai_interface.ts @@ -9,7 +9,7 @@ export interface Message { content: string; name?: string; tool_call_id?: string; - tool_calls?: ToolCall[]; + tool_calls?: ToolCall[] | null; sessionId?: string; // Optional session ID for WebSocket communication } @@ -210,7 +210,7 @@ export interface ChatResponse { stream?: (callback: (chunk: StreamChunk) => Promise | void) => Promise; /** Tool calls from the LLM (if tools were used and the model supports them) */ - tool_calls?: ToolCall[]; + tool_calls?: ToolCall[] | null; } export interface AIService { diff --git a/apps/server/src/services/llm/embeddings/embeddings_interface.ts b/apps/server/src/services/llm/embeddings/embeddings_interface.ts index b1fa333bf..1db6c5099 100644 --- a/apps/server/src/services/llm/embeddings/embeddings_interface.ts +++ b/apps/server/src/services/llm/embeddings/embeddings_interface.ts @@ -22,20 +22,24 @@ export interface NoteEmbeddingContext { title: string; mime: string; }[]; - backlinks?: { - sourceNoteId: string; - sourceTitle: string; - relationName: string; - }[]; - relatedNotes?: { - targetNoteId: string; - targetTitle: string; - relationName: string; - }[]; + backlinks?: Backlink[]; + relatedNotes?: RelatedNote[]; labelValues?: Record; templateTitles?: string[]; } +export interface Backlink { + sourceNoteId: string; + sourceTitle: string; + relationName: string; +} + +export interface RelatedNote { + targetNoteId: string; + targetTitle: string; + relationName: string; +} + /** * Information about an embedding model's capabilities */ diff --git a/apps/server/src/services/llm/embeddings/storage.ts b/apps/server/src/services/llm/embeddings/storage.ts index 67063e63b..675047a76 100644 --- a/apps/server/src/services/llm/embeddings/storage.ts +++ b/apps/server/src/services/llm/embeddings/storage.ts @@ -8,6 +8,14 @@ import entityChangesService from "../../../services/entity_changes.js"; import type { EntityChange } from "../../../services/entity_changes_interface.js"; import { EMBEDDING_CONSTANTS } from "../constants/embedding_constants.js"; import { SEARCH_CONSTANTS } from '../constants/search_constants.js'; + +interface Similarity { + noteId: string; + similarity: number; + contentType: string; + bonuses?: Record; // Optional for debugging +} + /** * Creates or updates an embedding for a note */ @@ -434,7 +442,7 @@ async function processEmbeddings(queryEmbedding: Float32Array, embeddings: any[] return { bonuses, totalBonus }; } - const similarities = []; + const similarities: Similarity[] = []; try { // Try to extract the original query text if it was added to the metadata diff --git a/apps/server/src/services/llm/providers/anthropic_service.ts b/apps/server/src/services/llm/providers/anthropic_service.ts index 955ef494a..cbdbb6814 100644 --- a/apps/server/src/services/llm/providers/anthropic_service.ts +++ b/apps/server/src/services/llm/providers/anthropic_service.ts @@ -7,6 +7,21 @@ import { getAnthropicOptions } from './providers.js'; import log from '../../log.js'; import Anthropic from '@anthropic-ai/sdk'; import { SEARCH_CONSTANTS } from '../constants/search_constants.js'; +import type { ToolCall } from '../tools/tool_interfaces.js'; + +interface AnthropicMessage extends Omit { + content: MessageContent[] | string; +} + +interface MessageContent { + type: "text" | "tool_use" | "tool_result"; + text?: string; + id?: string; + name?: string; + content?: string; + tool_use_id?: string; + input?: string | Record; +} export class AnthropicService extends BaseAIService { private client: any = null; @@ -130,7 +145,7 @@ export class AnthropicService extends BaseAIService { .join(''); // Process tool calls if any are present in the response - let toolCalls = null; + let toolCalls: ToolCall[] | null = null; if (response.content) { const toolBlocks = response.content.filter((block: any) => block.type === 'tool_use' || @@ -157,7 +172,7 @@ export class AnthropicService extends BaseAIService { return null; }).filter(Boolean); - log.info(`Extracted ${toolCalls.length} tool calls from Anthropic response`); + log.info(`Extracted ${toolCalls?.length} tool calls from Anthropic response`); } } @@ -406,8 +421,8 @@ export class AnthropicService extends BaseAIService { /** * Format messages for the Anthropic API */ - private formatMessages(messages: Message[]): any[] { - const anthropicMessages: any[] = []; + private formatMessages(messages: Message[]): AnthropicMessage[] { + const anthropicMessages: AnthropicMessage[] = []; // Process each message for (const msg of messages) { @@ -424,7 +439,7 @@ export class AnthropicService extends BaseAIService { // Assistant messages need special handling for tool_calls if (msg.tool_calls && msg.tool_calls.length > 0) { // Create content blocks array for tool calls - const content = []; + const content: MessageContent[] = []; // Add text content if present if (msg.content) { diff --git a/apps/server/src/services/llm/providers/providers.ts b/apps/server/src/services/llm/providers/providers.ts index 5fcd4286a..91295ffe0 100644 --- a/apps/server/src/services/llm/providers/providers.ts +++ b/apps/server/src/services/llm/providers/providers.ts @@ -181,7 +181,7 @@ export async function updateEmbeddingProviderConfig( } // Build update query parts - const updates = []; + const updates: string[] = []; const params: any[] = []; if (priority !== undefined) { diff --git a/apps/server/src/services/llm/tools/content_extraction_tool.ts b/apps/server/src/services/llm/tools/content_extraction_tool.ts index 0a1a18cd7..52c1409e9 100644 --- a/apps/server/src/services/llm/tools/content_extraction_tool.ts +++ b/apps/server/src/services/llm/tools/content_extraction_tool.ts @@ -8,6 +8,26 @@ import type { Tool, ToolHandler } from './tool_interfaces.js'; import log from '../../log.js'; import becca from '../../../becca/becca.js'; +interface CodeBlock { + code: string; + language?: string; +} + +interface Heading { + text: string; + level: number; // 1 for H1, 2 for H2, etc. +} + +interface List { + type: "unordered" | "ordered"; + items: string[]; +} + +interface Table { + headers: string[]; + rows: string[][]; +} + /** * Definition of the content extraction tool */ @@ -137,8 +157,8 @@ export class ContentExtractionTool implements ToolHandler { /** * Extract lists from HTML content */ - private extractLists(content: string): Array<{ type: string, items: string[] }> { - const lists = []; + private extractLists(content: string): List[] { + const lists: List[] = []; // Extract unordered lists const ulRegex = /]*>([\s\S]*?)<\/ul>/gi; @@ -179,7 +199,7 @@ export class ContentExtractionTool implements ToolHandler { * Extract list items from list content */ private extractListItems(listContent: string): string[] { - const items = []; + const items: string[] = []; const itemRegex = /]*>([\s\S]*?)<\/li>/gi; let itemMatch; @@ -196,15 +216,15 @@ export class ContentExtractionTool implements ToolHandler { /** * Extract tables from HTML content */ - private extractTables(content: string): Array<{ headers: string[], rows: string[][] }> { - const tables = []; + private extractTables(content: string): Table[] { + const tables: Table[] = []; const tableRegex = /]*>([\s\S]*?)<\/table>/gi; - let tableMatch; + let tableMatch: RegExpExecArray | null; while ((tableMatch = tableRegex.exec(content)) !== null) { const tableContent = tableMatch[1]; - const headers = []; - const rows = []; + const headers: string[] = []; + const rows: string[][] = []; // Extract table headers const headerRegex = /]*>([\s\S]*?)<\/th>/gi; @@ -218,7 +238,7 @@ export class ContentExtractionTool implements ToolHandler { let rowMatch; while ((rowMatch = rowRegex.exec(tableContent)) !== null) { const rowContent = rowMatch[1]; - const cells = []; + const cells: string[] = []; const cellRegex = /]*>([\s\S]*?)<\/td>/gi; let cellMatch; @@ -246,7 +266,7 @@ export class ContentExtractionTool implements ToolHandler { * Extract headings from HTML content */ private extractHeadings(content: string): Array<{ level: number, text: string }> { - const headings = []; + const headings: Heading[] = []; for (let i = 1; i <= 6; i++) { const headingRegex = new RegExp(`]*>([\\s\\S]*?)<\/h${i}>`, 'gi'); @@ -270,7 +290,7 @@ export class ContentExtractionTool implements ToolHandler { * Extract code blocks from HTML content */ private extractCodeBlocks(content: string): Array<{ language?: string, code: string }> { - const codeBlocks = []; + const codeBlocks: CodeBlock[] = []; // Look for
 and  blocks
         const preRegex = /]*>([\s\S]*?)<\/pre>/gi;
diff --git a/apps/server/src/services/llm/tools/note_creation_tool.ts b/apps/server/src/services/llm/tools/note_creation_tool.ts
index 9633880e4..41e608029 100644
--- a/apps/server/src/services/llm/tools/note_creation_tool.ts
+++ b/apps/server/src/services/llm/tools/note_creation_tool.ts
@@ -9,6 +9,7 @@ import log from '../../log.js';
 import becca from '../../../becca/becca.js';
 import notes from '../../notes.js';
 import attributes from '../../attributes.js';
+import type { BNote } from '../../backend_script_entrypoint.js';
 
 /**
  * Definition of the note creation tool
@@ -89,7 +90,7 @@ export class NoteCreationTool implements ToolHandler {
             log.info(`Executing create_note tool - Title: "${title}", Type: ${type}, ParentNoteId: ${parentNoteId || 'root'}`);
 
             // Validate parent note exists if specified
-            let parent = null;
+            let parent: BNote | null = null;
             if (parentNoteId) {
                 parent = becca.notes[parentNoteId];
                 if (!parent) {
diff --git a/apps/server/src/services/llm/tools/relationship_tool.ts b/apps/server/src/services/llm/tools/relationship_tool.ts
index 09e16f72c..a7023981d 100644
--- a/apps/server/src/services/llm/tools/relationship_tool.ts
+++ b/apps/server/src/services/llm/tools/relationship_tool.ts
@@ -10,6 +10,14 @@ import becca from '../../../becca/becca.js';
 import attributes from '../../attributes.js';
 import aiServiceManager from '../ai_service_manager.js';
 import { SEARCH_CONSTANTS } from '../constants/search_constants.js';
+import type { Backlink, RelatedNote } from '../embeddings/embeddings_interface.js';
+
+interface Suggestion {
+    targetNoteId: string;
+    targetTitle: string;
+    similarity: number;
+    suggestedRelation: string;
+}
 
 /**
  * Definition of the relationship tool
@@ -180,7 +188,7 @@ export class RelationshipTool implements ToolHandler {
                 .filter((attr: any) => attr.type === 'relation')
                 .slice(0, limit);
 
-            const outgoingRelations = [];
+            const outgoingRelations: RelatedNote[] = [];
 
             for (const attr of outgoingAttributes) {
                 const targetNote = becca.notes[attr.value];
@@ -196,7 +204,7 @@ export class RelationshipTool implements ToolHandler {
 
             // Get incoming relationships (where this note is the target)
             // Since becca.findNotesWithRelation doesn't exist, use attributes to find notes with relation
-            const incomingRelations = [];
+            const incomingRelations: Backlink[] = [];
 
             // Find all attributes of type relation that point to this note
             const relationAttributes = sourceNote.getTargetRelations();
@@ -321,7 +329,7 @@ export class RelationshipTool implements ToolHandler {
             const sourceContent = await sourceNote.getContent();
 
             // Prepare suggestions
-            const suggestions = [];
+            const suggestions: Suggestion[] = [];
 
             for (const relatedNote of relatedResult.relatedNotes) {
                 try {
diff --git a/apps/server/src/services/notes.ts b/apps/server/src/services/notes.ts
index cbb3c90c1..f06e07ed8 100644
--- a/apps/server/src/services/notes.ts
+++ b/apps/server/src/services/notes.ts
@@ -755,7 +755,7 @@ function updateNoteData(noteId: string, content: string, attachments: Attachment
 function undeleteNote(noteId: string, taskContext: TaskContext) {
     const noteRow = sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
 
-    if (!noteRow.isDeleted) {
+    if (!noteRow.isDeleted || !noteRow.deleteId) {
         log.error(`Note '${noteId}' is not deleted and thus cannot be undeleted.`);
         return;
     }
diff --git a/apps/server/src/services/script.ts b/apps/server/src/services/script.ts
index aedab83bf..1afc3b763 100644
--- a/apps/server/src/services/script.ts
+++ b/apps/server/src/services/script.ts
@@ -118,7 +118,7 @@ function getParams(params?: ScriptParams) {
 }
 
 function getScriptBundleForFrontend(note: BNote, script?: string, params?: ScriptParams) {
-    let overrideContent = null;
+    let overrideContent: string | null = null;
 
     if (script) {
         overrideContent = `return (${script}\r\n)(${getParams(params)})`;
@@ -170,7 +170,7 @@ function getScriptBundle(note: BNote, root: boolean = true, scriptEnv: string |
 
     includedNoteIds.push(note.noteId);
 
-    const modules = [];
+    const modules: BNote[] = [];
 
     for (const child of note.getChildNotes()) {
         const childBundle = getScriptBundle(child, false, scriptEnv, includedNoteIds);
diff --git a/apps/server/src/services/search/services/parse.ts b/apps/server/src/services/search/services/parse.ts
index c454aef7e..6cfaad6e6 100644
--- a/apps/server/src/services/search/services/parse.ts
+++ b/apps/server/src/services/search/services/parse.ts
@@ -294,11 +294,11 @@ function getExpression(tokens: TokenData[], searchContext: SearchContext, level
             valueExtractor: ValueExtractor;
             direction: string;
         }[] = [];
-        let limit;
+        let limit: number | undefined = undefined;
 
         if (tokens[i].token === "orderby") {
             do {
-                const propertyPath = [];
+                const propertyPath: string[] = [];
                 let direction = "asc";
 
                 do {
diff --git a/apps/server/src/services/search/services/search.ts b/apps/server/src/services/search/services/search.ts
index 3e1020e7a..7c53546e7 100644
--- a/apps/server/src/services/search/services/search.ts
+++ b/apps/server/src/services/search/services/search.ts
@@ -36,7 +36,7 @@ function searchFromNote(note: BNote): SearchNoteResult {
 
     const searchScript = note.getRelationValue("searchScript");
     const searchString = note.getLabelValue("searchString") || "";
-    let error = null;
+    let error: string | null = null;
 
     if (searchScript) {
         searchResultNoteIds = searchFromRelation(note, "searchScript");
diff --git a/apps/server/src/share/shaca/shaca-interface.ts b/apps/server/src/share/shaca/shaca-interface.ts
index 65b0585b7..1d796b302 100644
--- a/apps/server/src/share/shaca/shaca-interface.ts
+++ b/apps/server/src/share/shaca/shaca-interface.ts
@@ -43,7 +43,7 @@ export default class Shaca {
     }
 
     getNotes(noteIds: string[], ignoreMissing = false) {
-        const filteredNotes = [];
+        const filteredNotes: SNote[] = [];
 
         for (const noteId of noteIds) {
             const note = this.notes[noteId];

From 52a082d0e213bac27f5588a0c78928fc1cc9dccc Mon Sep 17 00:00:00 2001
From: Elian Doran 
Date: Wed, 28 May 2025 20:09:56 +0300
Subject: [PATCH 13/19] chore(server): align test configuration

---
 apps/server/tsconfig.app.json  | 3 ++-
 apps/server/tsconfig.spec.json | 6 +++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/apps/server/tsconfig.app.json b/apps/server/tsconfig.app.json
index 591b4a5db..eb7f102aa 100644
--- a/apps/server/tsconfig.app.json
+++ b/apps/server/tsconfig.app.json
@@ -13,7 +13,8 @@
     "tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo"
   },
   "include": [
-    "src/**/*.ts"
+    "src/**/*.ts",
+    "package.json"
   ],
   "exclude": [
     "eslint.config.js",
diff --git a/apps/server/tsconfig.spec.json b/apps/server/tsconfig.spec.json
index 51c5a98fc..4f8607e4b 100644
--- a/apps/server/tsconfig.spec.json
+++ b/apps/server/tsconfig.spec.json
@@ -1,6 +1,9 @@
 {
   "extends": "../../tsconfig.base.json",
   "compilerOptions": {
+    "module": "ESNext",
+    "moduleResolution": "bundler",
+    "target": "ES2020",
     "outDir": "./out-tsc/vitest",
     "types": [
       "vitest/globals",
@@ -24,6 +27,7 @@
     "src/**/*.test.jsx",
     "src/**/*.spec.jsx",
     "src/**/*.d.ts",
-    "src/**/*.ts"
+    "src/**/*.ts",
+    "package.json"
   ]
 }

From cb7aee742e3c28ffeb7c01aa186772583863d520 Mon Sep 17 00:00:00 2001
From: Elian Doran 
Date: Wed, 28 May 2025 20:10:14 +0300
Subject: [PATCH 14/19] chore(vscode): configure TypeScript SDK

---
 .vscode/settings.json | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index 86eca8e3a..5a2764983 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -26,5 +26,7 @@
         ".github/workflows/nightly.yml"
     ],
     "typescript.validate.enable": true,
-    "typescript.tsserver.experimental.enableProjectDiagnostics": true
+    "typescript.tsserver.experimental.enableProjectDiagnostics": true,
+    "typescript.tsdk": "node_modules/typescript/lib",
+    "typescript.enablePromptUseWorkspaceTsdk": true
 }
\ No newline at end of file

From 26c1cbeff164325f085a37fc984e1e0b8daa92b7 Mon Sep 17 00:00:00 2001
From: Elian Doran 
Date: Wed, 28 May 2025 20:42:21 +0300
Subject: [PATCH 15/19] chore(client): fix most type errors

---
 apps/client/src/components/app_context.ts     |  3 ++-
 apps/client/src/components/touch_bar.ts       |  2 +-
 apps/client/src/entities/fnote.ts             |  2 +-
 apps/client/src/services/clipboard.ts         |  2 +-
 apps/client/src/services/froca_updater.ts     |  2 +-
 apps/client/src/services/link.ts              |  6 ++---
 .../promoted_attribute_definition_parser.ts   |  2 +-
 apps/client/src/services/tree.ts              |  8 +++----
 apps/client/src/services/utils.ts             |  6 ++---
 apps/client/src/test/easy-froca.ts            |  2 +-
 .../attribute_widgets/attribute_detail.ts     |  6 ++---
 .../widgets/containers/launcher_container.ts  |  2 +-
 .../containers/split_note_container.ts        |  2 +-
 apps/client/src/widgets/find_in_text.ts       | 12 +---------
 apps/client/src/widgets/highlights_list.ts    |  7 +++---
 apps/client/src/widgets/note_tree.ts          | 10 ++++----
 .../src/widgets/ribbon_widgets/note_paths.ts  |  8 +++----
 .../ribbon_widgets/promoted_attributes.ts     |  2 +-
 apps/client/src/widgets/tab_row.ts            | 10 ++++----
 apps/client/src/widgets/toc.ts                | 12 ++++++----
 .../abstract_svg_split_type_widget.ts         |  4 ++--
 .../widgets/type_widgets/ckeditor/config.ts   |  2 +-
 .../src/widgets/type_widgets/editable_text.ts |  2 +-
 .../src/widgets/type_widgets/mind_map.ts      |  6 ++---
 .../options/ai_settings/ai_settings_widget.ts | 10 ++++----
 .../src/widgets/view_widgets/calendar_view.ts | 24 ++++++++++---------
 26 files changed, 75 insertions(+), 79 deletions(-)

diff --git a/apps/client/src/components/app_context.ts b/apps/client/src/components/app_context.ts
index b64678011..f7a5dfb1e 100644
--- a/apps/client/src/components/app_context.ts
+++ b/apps/client/src/components/app_context.ts
@@ -27,6 +27,7 @@ import type EditableTextTypeWidget from "../widgets/type_widgets/editable_text.j
 import type { NativeImage, TouchBar } from "electron";
 import TouchBarComponent from "./touch_bar.js";
 import type { CKTextEditor } from "@triliumnext/ckeditor5";
+import type CodeMirror from "@triliumnext/codemirror";
 
 interface Layout {
     getRootWidget: (appContext: AppContext) => RootWidget;
@@ -191,7 +192,7 @@ export type CommandMappings = {
     ExecuteCommandData & {
         callback?: GetTextEditorCallback;
     };
-    executeWithCodeEditor: CommandData & ExecuteCommandData;
+    executeWithCodeEditor: CommandData & ExecuteCommandData;
     /**
      * Called upon when attempting to retrieve the content element of a {@link NoteContext}.
      * Generally should not be invoked manually, as it is used by {@link NoteContext.getContentElement}.
diff --git a/apps/client/src/components/touch_bar.ts b/apps/client/src/components/touch_bar.ts
index 4afe65151..7bf10d7f1 100644
--- a/apps/client/src/components/touch_bar.ts
+++ b/apps/client/src/components/touch_bar.ts
@@ -54,7 +54,7 @@ export default class TouchBarComponent extends Component {
     #refreshTouchBar() {
         const { TouchBar } = this.remote;
         const parentComponent = this.lastFocusedComponent;
-        let touchBar = null;
+        let touchBar: Electron.CrossProcessExports.TouchBar | null = null;
 
         if (this.$activeModal?.length) {
             touchBar = this.#buildModalTouchBar();
diff --git a/apps/client/src/entities/fnote.ts b/apps/client/src/entities/fnote.ts
index e968dcae9..9e215821d 100644
--- a/apps/client/src/entities/fnote.ts
+++ b/apps/client/src/entities/fnote.ts
@@ -789,7 +789,7 @@ class FNote {
      */
     async getRelationTargets(name: string) {
         const relations = this.getRelations(name);
-        const targets = [];
+        const targets: (FNote | null)[] = [];
 
         for (const relation of relations) {
             targets.push(await this.froca.getNote(relation.value));
diff --git a/apps/client/src/services/clipboard.ts b/apps/client/src/services/clipboard.ts
index 2da2d1cf3..002309586 100644
--- a/apps/client/src/services/clipboard.ts
+++ b/apps/client/src/services/clipboard.ts
@@ -80,7 +80,7 @@ async function copy(branchIds: string[]) {
     if (utils.isElectron()) {
         // https://github.com/zadam/trilium/issues/2401
         const { clipboard } = require("electron");
-        const links = [];
+        const links: string[] = [];
 
         for (const branch of froca.getBranches(clipboardBranchIds)) {
             const $link = await linkService.createLink(`${branch.parentNoteId}/${branch.noteId}`, { referenceLink: true });
diff --git a/apps/client/src/services/froca_updater.ts b/apps/client/src/services/froca_updater.ts
index 37f9d2814..1f8eaa541 100644
--- a/apps/client/src/services/froca_updater.ts
+++ b/apps/client/src/services/froca_updater.ts
@@ -50,7 +50,7 @@ async function processEntityChanges(entityChanges: EntityChange[]) {
     // To this we count: standard parent-child relationships and template/inherit relations (attribute inheritance follows them).
     // Here we watch for changes which might violate this principle - e.g., an introduction of a new "inherit" relation might
     // mean we need to load the target of the relation (and then perhaps transitively the whole note path of this target).
-    const missingNoteIds = [];
+    const missingNoteIds: string[] = [];
 
     for (const { entityName, entity } of entityChanges) {
         if (!entity) {
diff --git a/apps/client/src/services/link.ts b/apps/client/src/services/link.ts
index 3dac7688f..0425652f6 100644
--- a/apps/client/src/services/link.ts
+++ b/apps/client/src/services/link.ts
@@ -215,9 +215,9 @@ export function parseNavigationStateFromUrl(url: string | undefined) {
     const viewScope: ViewScope = {
         viewMode: "default"
     };
-    let ntxId = null;
-    let hoistedNoteId = null;
-    let searchString = null;
+    let ntxId: string | null = null;
+    let hoistedNoteId: string | null = null;
+    let searchString: string | null = null;
 
     if (paramString) {
         for (const pair of paramString.split("&")) {
diff --git a/apps/client/src/services/promoted_attribute_definition_parser.ts b/apps/client/src/services/promoted_attribute_definition_parser.ts
index e40c24bbc..f46040e2a 100644
--- a/apps/client/src/services/promoted_attribute_definition_parser.ts
+++ b/apps/client/src/services/promoted_attribute_definition_parser.ts
@@ -1,7 +1,7 @@
 type LabelType = "text" | "number" | "boolean" | "date" | "datetime" | "time" | "url";
 type Multiplicity = "single" | "multi";
 
-interface DefinitionObject {
+export interface DefinitionObject {
     isPromoted?: boolean;
     labelType?: LabelType;
     multiplicity?: Multiplicity;
diff --git a/apps/client/src/services/tree.ts b/apps/client/src/services/tree.ts
index 485447214..c508654f5 100644
--- a/apps/client/src/services/tree.ts
+++ b/apps/client/src/services/tree.ts
@@ -34,8 +34,8 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
         path.push("root");
     }
 
-    const effectivePathSegments = [];
-    let childNoteId = null;
+    const effectivePathSegments: string[] = [];
+    let childNoteId: string | null = null;
     let i = 0;
 
     while (true) {
@@ -197,7 +197,7 @@ function getNotePath(node: Fancytree.FancytreeNode) {
         return "";
     }
 
-    const path = [];
+    const path: string[] = [];
 
     while (node) {
         if (node.data.noteId) {
@@ -236,7 +236,7 @@ async function getNoteTitle(noteId: string, parentNoteId: string | null = null)
 }
 
 async function getNotePathTitleComponents(notePath: string) {
-    const titleComponents = [];
+    const titleComponents: string[] = [];
 
     if (notePath.startsWith("root/")) {
         notePath = notePath.substr(5);
diff --git a/apps/client/src/services/utils.ts b/apps/client/src/services/utils.ts
index a52b7443a..ab6e45847 100644
--- a/apps/client/src/services/utils.ts
+++ b/apps/client/src/services/utils.ts
@@ -51,7 +51,7 @@ function getMonthsInDateRange(startDate: string, endDate: string) {
     const end = endDate.split("-");
     const startYear = parseInt(start[0]);
     const endYear = parseInt(end[0]);
-    const dates = [];
+    const dates: string[] = [];
 
     for (let i = startYear; i <= endYear; i++) {
         const endMonth = i != endYear ? 11 : parseInt(end[1]) - 1;
@@ -84,7 +84,7 @@ function formatTimeInterval(ms: number) {
     const hours = Math.floor(minutes / 60);
     const days = Math.floor(hours / 24);
     const plural = (count: number, name: string) => `${count} ${name}${count > 1 ? "s" : ""}`;
-    const segments = [];
+    const segments: string[] = [];
 
     if (days > 0) {
         segments.push(plural(days, "day"));
@@ -149,7 +149,7 @@ function isMac() {
 
 export const hasTouchBar = (isMac() && isElectron());
 
-function isCtrlKey(evt: KeyboardEvent | MouseEvent | JQuery.ClickEvent | JQuery.ContextMenuEvent | JQuery.TriggeredEvent | React.PointerEvent) {
+function isCtrlKey(evt: KeyboardEvent | MouseEvent | JQuery.ClickEvent | JQuery.ContextMenuEvent | JQuery.TriggeredEvent | React.PointerEvent | JQueryEventObject) {
     return (!isMac() && evt.ctrlKey) || (isMac() && evt.metaKey);
 }
 
diff --git a/apps/client/src/test/easy-froca.ts b/apps/client/src/test/easy-froca.ts
index 0ccb768fd..045819ab5 100644
--- a/apps/client/src/test/easy-froca.ts
+++ b/apps/client/src/test/easy-froca.ts
@@ -28,7 +28,7 @@ interface NoteDefinition extends AttributeDefinitions, RelationDefinitions {
  * ]);
  */
 export function buildNotes(notes: NoteDefinition[]) {
-    const ids = [];
+    const ids: string[] = [];
 
     for (const noteDef of notes) {
         ids.push(buildNote(noteDef).noteId);
diff --git a/apps/client/src/widgets/attribute_widgets/attribute_detail.ts b/apps/client/src/widgets/attribute_widgets/attribute_detail.ts
index 94d2bfa29..08bb764fc 100644
--- a/apps/client/src/widgets/attribute_widgets/attribute_detail.ts
+++ b/apps/client/src/widgets/attribute_widgets/attribute_detail.ts
@@ -718,7 +718,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
     }
 
     buildDefinitionValue() {
-        const props = [];
+        const props: string[] = [];
 
         if (this.$inputPromoted.is(":checked")) {
             props.push("promoted");
@@ -728,10 +728,10 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
             }
         }
 
-        props.push(this.$inputMultiplicity.val());
+        props.push(this.$inputMultiplicity.val() as string);
 
         if (this.attrType === "label-definition") {
-            props.push(this.$inputLabelType.val());
+            props.push(this.$inputLabelType.val() as string);
 
             if (this.$inputLabelType.val() === "number" && this.$inputNumberPrecision.val() !== "") {
                 props.push(`precision=${this.$inputNumberPrecision.val()}`);
diff --git a/apps/client/src/widgets/containers/launcher_container.ts b/apps/client/src/widgets/containers/launcher_container.ts
index 5a814d1fa..f684d4e6b 100644
--- a/apps/client/src/widgets/containers/launcher_container.ts
+++ b/apps/client/src/widgets/containers/launcher_container.ts
@@ -29,7 +29,7 @@ export default class LauncherContainer extends FlexContainer {
             return;
         }
 
-        const newChildren = [];
+        const newChildren: LauncherWidget[] = [];
 
         for (const launcherNote of await visibleLaunchersRoot.getChildNotes()) {
             try {
diff --git a/apps/client/src/widgets/containers/split_note_container.ts b/apps/client/src/widgets/containers/split_note_container.ts
index 9bd5c04b5..99165437c 100644
--- a/apps/client/src/widgets/containers/split_note_container.ts
+++ b/apps/client/src/widgets/containers/split_note_container.ts
@@ -217,7 +217,7 @@ export default class SplitNoteContainer extends FlexContainer {
     }
 
     refreshNotShown(data: NoteSwitchedContext | EventData<"activeContextChanged">) {
-        const promises = [];
+        const promises: (Promise | null | undefined)[] = [];
 
         for (const subContext of data.noteContext.getMainContext().getSubContexts()) {
             if (!subContext.ntxId) {
diff --git a/apps/client/src/widgets/find_in_text.ts b/apps/client/src/widgets/find_in_text.ts
index 959fcdf34..e97a7a8df 100644
--- a/apps/client/src/widgets/find_in_text.ts
+++ b/apps/client/src/widgets/find_in_text.ts
@@ -2,16 +2,6 @@ import type { FindAndReplaceState, FindCommandResult } from "@triliumnext/ckedit
 import type { FindResult } from "./find.js";
 import type FindWidget from "./find.js";
 
-// TODO: Deduplicate.
-interface Match {
-    className: string;
-    clear(): void;
-    find(): {
-        from: number;
-        to: number;
-    };
-}
-
 export default class FindInText {
 
     private parent: FindWidget;
@@ -35,7 +25,7 @@ export default class FindInText {
         }
 
         const model = textEditor.model;
-        let findResult = null;
+        let findResult: FindCommandResult | null = null;
         let totalFound = 0;
         let currentFound = -1;
 
diff --git a/apps/client/src/widgets/highlights_list.ts b/apps/client/src/widgets/highlights_list.ts
index f37b82955..38a736f7e 100644
--- a/apps/client/src/widgets/highlights_list.ts
+++ b/apps/client/src/widgets/highlights_list.ts
@@ -243,7 +243,7 @@ export default class HighlightsListWidget extends RightPanelWidget {
         // Used to determine if a string is only a formula
         const onlyMathRegex = /^\\\([^\)]*?\)<\/span>(?:\\\([^\)]*?\)<\/span>)*$/;
 
-        for (let match = null, hltIndex = 0; (match = combinedRegex.exec(content)) !== null; hltIndex++) {
+        for (let match: RegExpMatchArray | null = null, hltIndex = 0; (match = combinedRegex.exec(content)) !== null; hltIndex++) {
             const subHtml = match[0];
             const startIndex = match.index;
             const endIndex = combinedRegex.lastIndex;
@@ -324,8 +324,9 @@ export default class HighlightsListWidget extends RightPanelWidget {
                 });
         } else {
             const textEditor = await this.noteContext.getTextEditor();
-            if (textEditor) {
-                targetElement = $(textEditor.editing.view.domRoots.values().next().value)
+            const el = textEditor?.editing.view.domRoots.values().next().value;
+            if (el) {
+                targetElement = $(el)
                     .find(findSubStr)
                     .filter(function () {
                         // When finding span[style*="color"] but not looking for span[style*="background-color"],
diff --git a/apps/client/src/widgets/note_tree.ts b/apps/client/src/widgets/note_tree.ts
index 825e6d8f8..662562f42 100644
--- a/apps/client/src/widgets/note_tree.ts
+++ b/apps/client/src/widgets/note_tree.ts
@@ -350,7 +350,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
             },
             scrollParent: this.$tree,
             minExpandLevel: 2, // root can't be collapsed
-            click: (event: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent, data): boolean => {
+            click: (event, data): boolean => {
                 this.activityDetected();
 
                 const targetType = data.targetType;
@@ -745,7 +745,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
     prepareChildren(parentNote: FNote) {
         utils.assertArguments(parentNote);
 
-        const noteList = [];
+        const noteList: Node[] = [];
 
         const hideArchivedNotes = this.hideArchivedNotes;
 
@@ -839,7 +839,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
     getExtraClasses(note: FNote) {
         utils.assertArguments(note);
 
-        const extraClasses = [];
+        const extraClasses: string[] = [];
 
         if (note.isProtected) {
             extraClasses.push("protected");
@@ -1265,8 +1265,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
         const allBranchesDeleted = branchRows.every((branchRow) => !!branchRow.isDeleted);
 
         // activeNode is supposed to be moved when we find out activeNode is deleted but not all branches are deleted. save it for fixing activeNodePath after all nodes loaded.
-        let movedActiveNode = null;
-        let parentsOfAddedNodes = [];
+        let movedActiveNode: Fancytree.FancytreeNode | null = null;
+        let parentsOfAddedNodes: Fancytree.FancytreeNode[] = [];
 
         for (const branchRow of branchRows) {
             if (branchRow.noteId) {
diff --git a/apps/client/src/widgets/ribbon_widgets/note_paths.ts b/apps/client/src/widgets/ribbon_widgets/note_paths.ts
index 131fed2a4..8681bfd21 100644
--- a/apps/client/src/widgets/ribbon_widgets/note_paths.ts
+++ b/apps/client/src/widgets/ribbon_widgets/note_paths.ts
@@ -85,7 +85,7 @@ export default class NotePathsWidget extends NoteContextAwareWidget {
             this.$notePathIntro.text(t("note_paths.intro_not_placed"));
         }
 
-        const renderedPaths = [];
+        const renderedPaths: JQuery[] = [];
 
         for (const notePathRecord of sortedNotePaths) {
             const notePath = notePathRecord.notePath;
@@ -100,7 +100,7 @@ export default class NotePathsWidget extends NoteContextAwareWidget {
         const $pathItem = $("
  • "); const pathSegments: string[] = []; const lastIndex = notePath.length - 1; - + for (let i = 0; i < notePath.length; i++) { const noteId = notePath[i]; pathSegments.push(noteId); @@ -109,13 +109,13 @@ export default class NotePathsWidget extends NoteContextAwareWidget { $noteLink.find("a").addClass("no-tooltip-preview tn-link"); $pathItem.append($noteLink); - + if (i != lastIndex) { $pathItem.append(" / "); } } - const icons = []; + const icons: string[] = []; if (this.notePath === notePath.join("/")) { $pathItem.addClass("path-current"); diff --git a/apps/client/src/widgets/ribbon_widgets/promoted_attributes.ts b/apps/client/src/widgets/ribbon_widgets/promoted_attributes.ts index 861fef657..d94cfdbd1 100644 --- a/apps/client/src/widgets/ribbon_widgets/promoted_attributes.ts +++ b/apps/client/src/widgets/ribbon_widgets/promoted_attributes.ts @@ -122,7 +122,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget { return; } - const $cells = []; + const $cells: JQuery[] = []; for (const definitionAttr of promotedDefAttrs) { const valueType = definitionAttr.name.startsWith("label:") ? "label" : "relation"; diff --git a/apps/client/src/widgets/tab_row.ts b/apps/client/src/widgets/tab_row.ts index c5fb4e582..c846a20a6 100644 --- a/apps/client/src/widgets/tab_row.ts +++ b/apps/client/src/widgets/tab_row.ts @@ -208,7 +208,7 @@ const TAB_ROW_TPL = ` color: var(--active-tab-text-color); box-shadow: inset -1px 0 0 0 var(--main-border-color); } - + .tab-scroll-button-right { color: var(--active-tab-text-color); box-shadow: inset 1px 0 0 0 var(--main-border-color); @@ -279,7 +279,7 @@ const TAB_ROW_TPL = ` width: 100%; height: 100%; } - + .tab-row-widget-scrolling-container { overflow-x: auto; overflow-y: hidden; @@ -287,9 +287,9 @@ const TAB_ROW_TPL = ` } /* Chrome/Safari */ .tab-row-widget-scrolling-container::-webkit-scrollbar { - display: none; + display: none; } - +
    @@ -480,7 +480,7 @@ export default class TabRowWidget extends BasicWidget { const totalTabsWidthUsingTarget = flooredClampedTargetWidth * numberOfTabs + marginWidth; const totalExtraWidthDueToFlooring = tabsContainerWidth - totalTabsWidthUsingTarget; - const widths = []; + const widths: number[] = []; let extraWidthRemaining = totalExtraWidthDueToFlooring; for (let i = 0; i < numberOfTabs; i += 1) { diff --git a/apps/client/src/widgets/toc.ts b/apps/client/src/widgets/toc.ts index c5fda409c..a5db7ff1b 100644 --- a/apps/client/src/widgets/toc.ts +++ b/apps/client/src/widgets/toc.ts @@ -64,7 +64,7 @@ const TPL = /*html*/`
    } .toc > ol { - --toc-depth-level: 1; + --toc-depth-level: 1; } .toc > ol > ol { --toc-depth-level: 2; @@ -84,7 +84,7 @@ const TPL = /*html*/`
    } .toc li { - padding-left: calc((var(--toc-depth-level) - 1) * 20px + 4px); + padding-left: calc((var(--toc-depth-level) - 1) * 20px + 4px); } .toc li .collapse-button { @@ -304,7 +304,7 @@ export default class TocWidget extends RightPanelWidget { const validHeadingKeys = new Set(); // Used to clean up obsolete entries in tocCollapsedHeadings let headingCount = 0; - for (let m = null, headingIndex = 0; (m = headingTagsRegex.exec(html)) !== null; headingIndex++) { + for (let m: RegExpMatchArray | null = null, headingIndex = 0; (m = headingTagsRegex.exec(html)) !== null; headingIndex++) { // // Nest/unnest whatever necessary number of ordered lists // @@ -394,12 +394,14 @@ export default class TocWidget extends RightPanelWidget { const isDocNote = this.note.type === "doc"; const isReadOnly = await this.noteContext.isReadOnly(); - let $container; + let $container: JQuery | null = null; if (isReadOnly || isDocNote) { $container = await this.noteContext.getContentElement(); } else { const textEditor = await this.noteContext.getTextEditor(); - $container = $(textEditor.sourceElement); + if (textEditor?.sourceElement) { + $container = $(textEditor.sourceElement); + } } const headingElement = $container?.find(":header:not(section.include-note :header)")?.[headingIndex]; diff --git a/apps/client/src/widgets/type_widgets/abstract_svg_split_type_widget.ts b/apps/client/src/widgets/type_widgets/abstract_svg_split_type_widget.ts index 24c2c1ae4..45eba8890 100644 --- a/apps/client/src/widgets/type_widgets/abstract_svg_split_type_widget.ts +++ b/apps/client/src/widgets/type_widgets/abstract_svg_split_type_widget.ts @@ -138,8 +138,8 @@ export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTy */ async #setupPanZoom(preservePanZoom: boolean) { // Clean up - let pan = null; - let zoom = null; + let pan: SvgPanZoom.Point | null = null; + let zoom: number | null = null; if (preservePanZoom && this.zoomInstance) { // Store pan and zoom for same note, when the user is editing the note. pan = this.zoomInstance.getPan(); diff --git a/apps/client/src/widgets/type_widgets/ckeditor/config.ts b/apps/client/src/widgets/type_widgets/ckeditor/config.ts index 8cd2ba66d..93eea459d 100644 --- a/apps/client/src/widgets/type_widgets/ckeditor/config.ts +++ b/apps/client/src/widgets/type_widgets/ckeditor/config.ts @@ -134,7 +134,7 @@ export function buildToolbarConfig(isClassicToolbar: boolean) { export function buildMobileToolbar() { const classicConfig = buildClassicToolbar(false); - const items = []; + const items: string[] = []; for (const item of classicConfig.toolbar.items) { if (typeof item === "object" && "items" in item) { diff --git a/apps/client/src/widgets/type_widgets/editable_text.ts b/apps/client/src/widgets/type_widgets/editable_text.ts index a50b7a638..ca4ea98b2 100644 --- a/apps/client/src/widgets/type_widgets/editable_text.ts +++ b/apps/client/src/widgets/type_widgets/editable_text.ts @@ -589,7 +589,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { backgroundColor: buildSelectedBackgroundColor(editor.commands.get(command)?.value as boolean) }); - let headingSelectedIndex = undefined; + let headingSelectedIndex: number | undefined = undefined; const headingCommand = editor.commands.get("heading"); const paragraphCommand = editor.commands.get("paragraph"); if (paragraphCommand?.value) { diff --git a/apps/client/src/widgets/type_widgets/mind_map.ts b/apps/client/src/widgets/type_widgets/mind_map.ts index 83d2e0e96..18867bc83 100644 --- a/apps/client/src/widgets/type_widgets/mind_map.ts +++ b/apps/client/src/widgets/type_widgets/mind_map.ts @@ -207,8 +207,8 @@ export default class MindMapWidget extends TypeWidget { await this.#initLibrary(content?.direction); } - this.mind.refresh(content ?? this.MindElixir.new(NEW_TOPIC_NAME)); - this.mind.toCenter(); + this.mind!.refresh(content ?? this.MindElixir.new(NEW_TOPIC_NAME)); + this.mind!.toCenter(); } async #initLibrary(direction?: number) { @@ -259,7 +259,7 @@ export default class MindMapWidget extends TypeWidget { } async renderSvg() { - return await this.mind.exportSvg().text(); + return await this.mind!.exportSvg().text(); } async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { diff --git a/apps/client/src/widgets/type_widgets/options/ai_settings/ai_settings_widget.ts b/apps/client/src/widgets/type_widgets/options/ai_settings/ai_settings_widget.ts index 8f76eac4b..da7321d18 100644 --- a/apps/client/src/widgets/type_widgets/options/ai_settings/ai_settings_widget.ts +++ b/apps/client/src/widgets/type_widgets/options/ai_settings/ai_settings_widget.ts @@ -198,7 +198,7 @@ export default class AiSettingsWidget extends OptionsWidget { const providerPrecedence = (this.$widget.find('.ai-provider-precedence').val() as string || '').split(','); // Check for OpenAI configuration if it's in the precedence list - const openaiWarnings = []; + const openaiWarnings: string[] = []; if (providerPrecedence.includes('openai')) { const openaiApiKey = this.$widget.find('.openai-api-key').val(); if (!openaiApiKey) { @@ -207,7 +207,7 @@ export default class AiSettingsWidget extends OptionsWidget { } // Check for Anthropic configuration if it's in the precedence list - const anthropicWarnings = []; + const anthropicWarnings: string[] = []; if (providerPrecedence.includes('anthropic')) { const anthropicApiKey = this.$widget.find('.anthropic-api-key').val(); if (!anthropicApiKey) { @@ -216,7 +216,7 @@ export default class AiSettingsWidget extends OptionsWidget { } // Check for Voyage configuration if it's in the precedence list - const voyageWarnings = []; + const voyageWarnings: string[] = []; if (providerPrecedence.includes('voyage')) { const voyageApiKey = this.$widget.find('.voyage-api-key').val(); if (!voyageApiKey) { @@ -225,7 +225,7 @@ export default class AiSettingsWidget extends OptionsWidget { } // Check for Ollama configuration if it's in the precedence list - const ollamaWarnings = []; + const ollamaWarnings: string[] = []; if (providerPrecedence.includes('ollama')) { const ollamaBaseUrl = this.$widget.find('.ollama-base-url').val(); if (!ollamaBaseUrl) { @@ -234,7 +234,7 @@ export default class AiSettingsWidget extends OptionsWidget { } // Similar checks for embeddings - const embeddingWarnings = []; + const embeddingWarnings: string[] = []; const embeddingsEnabled = this.$widget.find('.enable-automatic-indexing').prop('checked'); if (embeddingsEnabled) { diff --git a/apps/client/src/widgets/view_widgets/calendar_view.ts b/apps/client/src/widgets/view_widgets/calendar_view.ts index fdc693dc1..d6eafa791 100644 --- a/apps/client/src/widgets/view_widgets/calendar_view.ts +++ b/apps/client/src/widgets/view_widgets/calendar_view.ts @@ -83,6 +83,13 @@ interface CreateChildResponse { }; } +interface Event { + startDate: string, + endDate?: string | null, + startTime?: string | null, + endTime?: string | null +} + const CALENDAR_VIEWS = [ "timeGridWeek", "dayGridMonth", @@ -325,8 +332,8 @@ export default class CalendarView extends ViewMode { } #parseStartEndTimeFromEvent(e: DateSelectArg | EventImpl) { - let startTime = null; - let endTime = null; + let startTime: string | undefined | null = null; + let endTime: string | undefined | null = null; if (!e.allDay) { startTime = CalendarView.#formatTimeToLocalISO(e.start); endTime = CalendarView.#formatTimeToLocalISO(e.end); @@ -391,7 +398,7 @@ export default class CalendarView extends ViewMode { } async #buildEventsForCalendar(e: EventSourceFuncArg) { - const events = []; + const events: EventInput[] = []; // Gather all the required date note IDs. const dateRange = utils.getMonthsInDateRange(e.startStr, e.endStr); @@ -483,12 +490,7 @@ export default class CalendarView extends ViewMode { return note.getLabelValue(defaultLabelName); } - static async buildEvent(note: FNote, { startDate, endDate, startTime, endTime }: { - startDate: string, - endDate?: string | null, - startTime?: string | null, - endTime?: string | null - }) { + static async buildEvent(note: FNote, { startDate, endDate, startTime, endTime }: Event) { const customTitleAttributeName = note.getLabelValue("calendar:title"); const titles = await CalendarView.#parseCustomTitle(customTitleAttributeName, note); const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color"); @@ -553,7 +555,7 @@ export default class CalendarView extends ViewMode { if (relations.length > 0) { const noteIds = relations.map((r) => r.targetNoteId); const notesFromRelation = await froca.getNotes(noteIds); - const titles = []; + const titles: string[][] = []; for (const targetNote of notesFromRelation) { const targetCustomTitleValue = targetNote.getAttributeValue("label", "calendar:title"); @@ -631,7 +633,7 @@ export default class CalendarView extends ViewMode { // Icon button. const iconEl = subItem.querySelector("span.fc-icon"); - let icon = null; + let icon: string | null = null; if (iconEl?.classList.contains("fc-icon-chevron-left")) { icon = "NSImageNameTouchBarGoBackTemplate"; mode = "buttons"; From 395bc372ce3c4a4b6594d2223243c56b56ec86c3 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 28 May 2025 20:46:33 +0300 Subject: [PATCH 16/19] chore(ckeditor5): type errors due to augmentation --- apps/client/src/services/syntax_highlight.ts | 2 +- .../widgets/type_widgets/ckeditor/config.ts | 2 +- packages/ckeditor5/src/augmentation.ts | 25 ------------------- packages/ckeditor5/src/index.ts | 25 +++++++++++++++++++ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/apps/client/src/services/syntax_highlight.ts b/apps/client/src/services/syntax_highlight.ts index bfe887b9d..cb2d4d873 100644 --- a/apps/client/src/services/syntax_highlight.ts +++ b/apps/client/src/services/syntax_highlight.ts @@ -97,7 +97,7 @@ export function loadHighlightingTheme(themeName: string) { */ export function isSyntaxHighlightEnabled() { const theme = options.get("codeBlockTheme"); - return theme && theme !== "none"; + return !!theme && theme !== "none"; } /** diff --git a/apps/client/src/widgets/type_widgets/ckeditor/config.ts b/apps/client/src/widgets/type_widgets/ckeditor/config.ts index 93eea459d..5a3262a1c 100644 --- a/apps/client/src/widgets/type_widgets/ckeditor/config.ts +++ b/apps/client/src/widgets/type_widgets/ckeditor/config.ts @@ -111,7 +111,7 @@ export function buildConfig(): EditorConfig { }, mapLanguageName: getHighlightJsNameForMime, defaultMimeType: MIME_TYPE_AUTO, - enabled: isSyntaxHighlightEnabled + enabled: isSyntaxHighlightEnabled() }, clipboard: { copy: copyText diff --git a/packages/ckeditor5/src/augmentation.ts b/packages/ckeditor5/src/augmentation.ts index da5e1c915..c1018db37 100644 --- a/packages/ckeditor5/src/augmentation.ts +++ b/packages/ckeditor5/src/augmentation.ts @@ -22,28 +22,3 @@ declare global { importMarkdownInline(): void; } } - -declare module "ckeditor5" { - interface Editor { - getSelectedHtml(): string; - removeSelection(): Promise; - } - - interface EditorConfig { - syntaxHighlighting?: { - loadHighlightJs: () => Promise; - mapLanguageName(mimeType: string): string; - defaultMimeType: string; - enabled: boolean; - }, - moveBlockUp?: { - keystroke: string[]; - }, - moveBlockDown?: { - keystroke: string[]; - }, - clipboard?: { - copy(text: string): void; - } - } -} diff --git a/packages/ckeditor5/src/index.ts b/packages/ckeditor5/src/index.ts index 8dc0e3611..58e72ca6d 100644 --- a/packages/ckeditor5/src/index.ts +++ b/packages/ckeditor5/src/index.ts @@ -43,3 +43,28 @@ export class PopupEditor extends BalloonEditor { return POPUP_EDITOR_PLUGINS; } } + +declare module "ckeditor5" { + interface Editor { + getSelectedHtml(): string; + removeSelection(): Promise; + } + + interface EditorConfig { + syntaxHighlighting?: { + loadHighlightJs: () => Promise; + mapLanguageName(mimeType: string): string; + defaultMimeType: string; + enabled: boolean; + }, + moveBlockUp?: { + keystroke: string[]; + }, + moveBlockDown?: { + keystroke: string[]; + }, + clipboard?: { + copy(text: string): void; + } + } +} From c597ad7694bc2f6e2be37332729ab89b267301fd Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 28 May 2025 21:15:55 +0300 Subject: [PATCH 17/19] chore(client): remove unused linter for now --- .../type_widgets/linters/mermaid.spec.ts | 43 -------------- .../widgets/type_widgets/linters/mermaid.ts | 58 ------------------- 2 files changed, 101 deletions(-) delete mode 100644 apps/client/src/widgets/type_widgets/linters/mermaid.spec.ts delete mode 100644 apps/client/src/widgets/type_widgets/linters/mermaid.ts diff --git a/apps/client/src/widgets/type_widgets/linters/mermaid.spec.ts b/apps/client/src/widgets/type_widgets/linters/mermaid.spec.ts deleted file mode 100644 index 638892d71..000000000 --- a/apps/client/src/widgets/type_widgets/linters/mermaid.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { trimIndentation } from "@triliumnext/commons"; -import { validateMermaid } from "./mermaid.js"; - -describe("Mermaid linter", () => { - - (global as any).CodeMirror = { - Pos(line: number, col: number) { - return { line, col }; - } - }; - - it("reports correctly bad diagram type", async () => { - const input = trimIndentation`\ - stateDiagram-v23 - [*] -> Still - `; - - const result = await validateMermaid(input); - expect(result).toMatchObject([{ - message: "Expecting 'SPACE', 'NL', 'SD', got 'ID'", - from: { line: 0, col: 0 }, - to: { line: 0, col: 1 } - }]); - }); - - it("reports correctly basic arrow missing in diagram", async () => { - const input = trimIndentation`\ - xychart-beta horizontal - title "Percentage usge" - x-axis [data, sys, usr, var] - y-axis 0--->100 - bar [20, 70, 0, 0] - `; - - const result = await validateMermaid(input); - expect(result).toMatchObject([{ - message: "Expecting 'ARROW_DELIMITER', got 'MINUS'", - from: { line: 3, col: 8 }, - to: { line: 3, col: 9 } - }]); - }); -}); diff --git a/apps/client/src/widgets/type_widgets/linters/mermaid.ts b/apps/client/src/widgets/type_widgets/linters/mermaid.ts deleted file mode 100644 index e0773e652..000000000 --- a/apps/client/src/widgets/type_widgets/linters/mermaid.ts +++ /dev/null @@ -1,58 +0,0 @@ -import mermaid from "mermaid"; - -interface MermaidParseError extends Error { - hash: { - text: string; - token: string; - line: number; - loc: { - first_line: number; - first_column: number; - last_line: number; - last_column: number; - }; - expected: string[] - } -} - -export default function registerErrorReporter() { - CodeMirror.registerHelper("lint", null, validateMermaid); -} - -export async function validateMermaid(text: string) { - if (!text.trim()) { - return []; - } - - try { - await mermaid.parse(text); - } catch (e: unknown) { - console.warn("Got validation error", JSON.stringify(e)); - - const mermaidError = (e as MermaidParseError); - const loc = mermaidError.hash.loc; - - let firstCol = loc.first_column + 1; - let lastCol = loc.last_column + 1; - - if (firstCol === 1 && lastCol === 1) { - firstCol = 0; - } - - let messageLines = mermaidError.message.split("\n"); - if (messageLines.length >= 4) { - messageLines = messageLines.slice(3); - } - - return [ - { - message: messageLines.join("\n"), - severity: "error", - from: CodeMirror.Pos(loc.first_line - 1, firstCol), - to: CodeMirror.Pos(loc.last_line - 1, lastCol) - } - ]; - } - - return []; -} From 7af44f609d934ad7d5e3afaa3d84b47de21159e8 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 28 May 2025 21:36:00 +0300 Subject: [PATCH 18/19] chore(client): fix a type error in tests --- apps/client/src/widgets/type_widgets/ckeditor/config.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/src/widgets/type_widgets/ckeditor/config.spec.ts b/apps/client/src/widgets/type_widgets/ckeditor/config.spec.ts index 8c96629b9..3bce30d9b 100644 --- a/apps/client/src/widgets/type_widgets/ckeditor/config.spec.ts +++ b/apps/client/src/widgets/type_widgets/ckeditor/config.spec.ts @@ -6,7 +6,7 @@ type ToolbarConfig = string | "|" | { items: ToolbarConfig[] }; describe("CKEditor config", () => { it("has same toolbar items for fixed and floating", () => { function traverseItems(config: ToolbarConfig): string[] { - const result = []; + const result: (string | string[])[] = []; if (typeof config === "object") { for (const item of config.items) { result.push(traverseItems(item)); From f87e7fb577609c0d7461eb2b8ba052fe10ce99ea Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 28 May 2025 23:03:19 +0300 Subject: [PATCH 19/19] chore(ckeditor5): missing type augmentations --- packages/ckeditor5/src/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/ckeditor5/src/index.ts b/packages/ckeditor5/src/index.ts index 58e72ca6d..117d14574 100644 --- a/packages/ckeditor5/src/index.ts +++ b/packages/ckeditor5/src/index.ts @@ -5,6 +5,10 @@ import { BalloonEditor, DecoupledEditor, FindAndReplaceEditing, FindCommand } fr export { EditorWatchdog } from "ckeditor5"; export type { EditorConfig, MentionFeed, MentionFeedObjectItem, Node, Position, Element, WatchdogConfig } from "ckeditor5"; +// Import with sideffects to ensure that type augmentations are present. +import "@triliumnext/ckeditor5-math"; +import "@triliumnext/ckeditor5-mermaid"; + /** * Short-hand for the CKEditor classes supported by Trilium for text editing. * Specialized editors such as the {@link AttributeEditor} are not included.