From 31a027fc64c3706d39d79ad698a9d1a303c9d4a8 Mon Sep 17 00:00:00 2001 From: Matiss Janis Aboltins Date: Sat, 21 Feb 2026 21:26:22 +0000 Subject: [PATCH] [AI] Add per-package tsconfigs and typescript-strict-plugin for typecheck (#7019) * [AI] Add per-package tsconfigs and typescript-strict-plugin for typecheck Co-authored-by: Cursor * Update TypeScript configuration across multiple packages to correct plugin path key from "path" to "paths" and add reference to process-worker typings in index.electron.ts. * Remove reference to process-worker typings in index.electron.ts and add new process-worker typings file for global Process augmentation. * Refactor TypeScript build configurations across multiple packages by removing tsconfig.dist.json files and updating build scripts to use default TypeScript compilation. Adjusted compiler options to target ES2021 and enable declaration generation. * Update TypeScript configuration in api package to refine include and exclude patterns for better file management. * Update build script in api package to ensure migration SQL files are copied to the correct directory by creating the destination folder if it doesn't exist. * Update TypeScript configurations in crdt and desktop-electron packages to refine include and exclude patterns for improved file management. * Update TypeScript dependencies across multiple packages to include typescript-strict-plugin for enhanced type checking and maintain consistency in package.json files. --------- Co-authored-by: Cursor --- lage.config.js | 3 +++ package.json | 5 ++--- packages/api/package.json | 8 ++++--- .../api/{tsconfig.dist.json => tsconfig.json} | 5 +++-- packages/component-library/package.json | 3 ++- packages/component-library/tsconfig.json | 10 +++++++++ packages/crdt/package.json | 5 +++-- .../{tsconfig.dist.json => tsconfig.json} | 0 packages/desktop-client/package.json | 5 ++++- packages/desktop-client/tsconfig.json | 22 +++++++++++++++++++ packages/desktop-electron/package.json | 6 +++-- .../{tsconfig.dist.json => tsconfig.json} | 5 +++-- packages/loot-core/package.json | 5 ++++- packages/loot-core/tsconfig.api.json | 2 +- packages/loot-core/tsconfig.json | 21 ++++++++++++++++++ packages/loot-core/typings/process-worker.ts | 12 ++++++++++ packages/loot-core/typings/window.ts | 5 +++++ packages/plugins-service/package.json | 4 +++- packages/plugins-service/tsconfig.json | 3 ++- packages/sync-server/package.json | 2 ++ packages/sync-server/tsconfig.json | 3 ++- tsconfig.json | 8 +------ tsconfig.root.json | 5 +++++ upcoming-release-notes/7019.md | 6 +++++ yarn.lock | 14 ++++++++---- 25 files changed, 135 insertions(+), 32 deletions(-) rename packages/api/{tsconfig.dist.json => tsconfig.json} (77%) create mode 100644 packages/component-library/tsconfig.json rename packages/crdt/{tsconfig.dist.json => tsconfig.json} (100%) create mode 100644 packages/desktop-client/tsconfig.json rename packages/desktop-electron/{tsconfig.dist.json => tsconfig.json} (74%) create mode 100644 packages/loot-core/tsconfig.json create mode 100644 packages/loot-core/typings/process-worker.ts create mode 100644 tsconfig.root.json create mode 100644 upcoming-release-notes/7019.md diff --git a/lage.config.js b/lage.config.js index 91f000bd9a..0c2a24894f 100644 --- a/lage.config.js +++ b/lage.config.js @@ -1,6 +1,9 @@ /** @type {import('lage').ConfigOptions} */ module.exports = { pipeline: { + typecheck: { + type: 'npmScript', + }, test: { type: 'npmScript', options: { diff --git a/package.json b/package.json index 2fd381e946..08ba079882 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "lint": "oxfmt --check . && oxlint --type-aware", "lint:fix": "oxfmt . && oxlint --fix --type-aware", "install:server": "yarn workspaces focus @actual-app/sync-server --production", - "typecheck": "yarn tsc --incremental && tsc-strict", + "typecheck": "tsc -p tsconfig.root.json --noEmit && lage typecheck", "jq": "./node_modules/node-jq/bin/jq", "prepare": "husky" }, @@ -84,8 +84,7 @@ "prompts": "^2.4.2", "source-map-support": "^0.5.21", "ts-node": "^10.9.2", - "typescript": "^5.9.3", - "typescript-strict-plugin": "^2.4.4" + "typescript": "^5.9.3" }, "resolutions": { "rollup": "4.40.1", diff --git a/packages/api/package.json b/packages/api/package.json index 3abb9bf6f2..a9aed456fc 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -12,12 +12,13 @@ "scripts": { "build:app": "yarn workspace loot-core build:api", "build:crdt": "yarn workspace @actual-app/crdt build", - "build:node": "tsc --p tsconfig.dist.json && tsc-alias -p tsconfig.dist.json", - "build:migrations": "cp migrations/*.sql dist/migrations", + "build:node": "tsc && tsc-alias", + "build:migrations": "mkdir dist/migrations && cp migrations/*.sql dist/migrations", "build:default-db": "cp default-db.sqlite dist/", "build": "yarn run clean && yarn run build:app && yarn run build:node && yarn run build:migrations && yarn run build:default-db", "test": "yarn run clean && yarn run build:app && yarn run build:crdt && vitest --run", - "clean": "rm -rf dist @types" + "clean": "rm -rf dist @types", + "typecheck": "yarn build && tsc --noEmit && tsc-strict" }, "dependencies": { "@actual-app/crdt": "workspace:^", @@ -29,6 +30,7 @@ "devDependencies": { "tsc-alias": "^1.8.16", "typescript": "^5.9.3", + "typescript-strict-plugin": "^2.4.4", "vitest": "^4.0.18" }, "engines": { diff --git a/packages/api/tsconfig.dist.json b/packages/api/tsconfig.json similarity index 77% rename from packages/api/tsconfig.dist.json rename to packages/api/tsconfig.json index a87d796263..e1f1c45a68 100644 --- a/packages/api/tsconfig.dist.json +++ b/packages/api/tsconfig.json @@ -12,8 +12,9 @@ "declarationDir": "@types", "paths": { "loot-core/*": ["./@types/loot-core/src/*"] - } + }, + "plugins": [{ "name": "typescript-strict-plugin", "paths": ["."] }] }, - "include": ["."], + "include": [".", "../../packages/loot-core/typings/pegjs.ts"], "exclude": ["**/node_modules/*", "dist", "@types", "*.test.ts"] } diff --git a/packages/component-library/package.json b/packages/component-library/package.json index 1e0b5c6b42..9f81665c61 100644 --- a/packages/component-library/package.json +++ b/packages/component-library/package.json @@ -39,7 +39,8 @@ "test": "npm-run-all -cp 'test:*'", "test:web": "ENV=web vitest --run -c vitest.web.config.ts", "start:storybook": "storybook dev -p 6006", - "build:storybook": "storybook build" + "build:storybook": "storybook build", + "typecheck": "tsc --noEmit" }, "dependencies": { "@emotion/css": "^11.13.5", diff --git a/packages/component-library/tsconfig.json b/packages/component-library/tsconfig.json new file mode 100644 index 0000000000..b21368159b --- /dev/null +++ b/packages/component-library/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "src", + "strict": true + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/packages/crdt/package.json b/packages/crdt/package.json index ab29f1af54..cb1f1d7e4c 100644 --- a/packages/crdt/package.json +++ b/packages/crdt/package.json @@ -9,10 +9,11 @@ "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { - "build:node": "tsc --p tsconfig.dist.json", + "build:node": "tsc", "proto:generate": "./bin/generate-proto", "build": "rm -rf dist && yarn run build:node", - "test": "vitest --run" + "test": "vitest --run", + "typecheck": "tsc --noEmit" }, "dependencies": { "google-protobuf": "^3.21.4", diff --git a/packages/crdt/tsconfig.dist.json b/packages/crdt/tsconfig.json similarity index 100% rename from packages/crdt/tsconfig.dist.json rename to packages/crdt/tsconfig.json diff --git a/packages/desktop-client/package.json b/packages/desktop-client/package.json index 612bc4389d..edcb4ba2fe 100644 --- a/packages/desktop-client/package.json +++ b/packages/desktop-client/package.json @@ -15,7 +15,8 @@ "test": "vitest --run", "e2e": "npx playwright test --browser=chromium", "vrt": "cross-env VRT=true npx playwright test --browser=chromium", - "playwright": "playwright" + "playwright": "playwright", + "typecheck": "tsc --noEmit && tsc-strict" }, "devDependencies": { "@actual-app/components": "workspace:*", @@ -90,6 +91,8 @@ "remark-gfm": "^4.0.1", "rollup-plugin-visualizer": "^6.0.5", "sass": "^1.97.3", + "typescript": "^5.9.3", + "typescript-strict-plugin": "^2.4.4", "usehooks-ts": "^3.1.1", "uuid": "^13.0.0", "vite": "^7.3.1", diff --git a/packages/desktop-client/tsconfig.json b/packages/desktop-client/tsconfig.json new file mode 100644 index 0000000000..ad637cec77 --- /dev/null +++ b/packages/desktop-client/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": true, + "plugins": [{ "name": "typescript-strict-plugin", "paths": ["."] }] + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "../../packages/loot-core/typings/pegjs.ts", + "../../packages/loot-core/typings/window.ts" + ], + "exclude": [ + "node_modules", + "build", + "**/service-worker/**", + "e2e", + "**/*.test.ts", + "**/*.test.tsx", + "**/setupTests.ts" + ] +} diff --git a/packages/desktop-electron/package.json b/packages/desktop-electron/package.json index 1e4b4e3c69..fd37343e36 100644 --- a/packages/desktop-electron/package.json +++ b/packages/desktop-electron/package.json @@ -8,7 +8,8 @@ "clean": "rm -rf dist", "update-client": "bin/update-client", "build": "yarn build:dist && electron-builder", - "build:dist": "tsc --p tsconfig.dist.json && yarn copy-static-assets", + "build:dist": "tsc && yarn copy-static-assets", + "typecheck": "tsc --noEmit && tsc-strict", "copy-static-assets": "copyfiles --exclude 'build/**/*' **/*.html icons/**/* build/desktop-electron", "watch": "yarn build:dist && cross-env ACTUAL_DOCUMENT_DIR=\"../../data\" ACTUAL_DATA_DIR=\"../../data\" electron .", "e2e": "npx playwright test" @@ -29,7 +30,8 @@ "cross-env": "^10.1.0", "electron": "39.2.7", "electron-builder": "26.4.0", - "typescript": "^5.9.3" + "typescript": "^5.9.3", + "typescript-strict-plugin": "^2.4.4" }, "build": { "appId": "com.actualbudget.actual", diff --git a/packages/desktop-electron/tsconfig.dist.json b/packages/desktop-electron/tsconfig.json similarity index 74% rename from packages/desktop-electron/tsconfig.dist.json rename to packages/desktop-electron/tsconfig.json index f6dcce0f52..4af99749cd 100644 --- a/packages/desktop-electron/tsconfig.dist.json +++ b/packages/desktop-electron/tsconfig.json @@ -9,9 +9,10 @@ "noEmit": false, "declaration": true, "outDir": "build", - "rootDir": ".." + "rootDir": "..", + "plugins": [{ "name": "typescript-strict-plugin", "paths": ["."] }] }, - "include": ["."], + "include": [".", "../../packages/loot-core/typings/window.ts"], "exclude": [ "**/node_modules/*", "build/**/*", diff --git a/packages/loot-core/package.json b/packages/loot-core/package.json index c983a249f6..ca05c48b90 100644 --- a/packages/loot-core/package.json +++ b/packages/loot-core/package.json @@ -60,7 +60,8 @@ "generate:i18n": "i18next", "test": "npm-run-all -cp 'test:*'", "test:node": "ENV=node vitest --run", - "test:web": "ENV=web vitest --run -c vitest.web.config.ts" + "test:web": "ENV=web vitest --run -c vitest.web.config.ts", + "typecheck": "tsc --noEmit && tsc-strict" }, "dependencies": { "@jlongster/sql.js": "^1.6.7", @@ -81,6 +82,8 @@ "memoize-one": "^6.0.0", "mitt": "^3.0.1", "slash": "5.1.0", + "typescript": "^5.9.3", + "typescript-strict-plugin": "^2.4.4", "ua-parser-js": "^2.0.9", "uuid": "^13.0.0" }, diff --git a/packages/loot-core/tsconfig.api.json b/packages/loot-core/tsconfig.api.json index 56ea2d8cdc..349518c690 100644 --- a/packages/loot-core/tsconfig.api.json +++ b/packages/loot-core/tsconfig.api.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "./tsconfig.json", "compilerOptions": { "rootDir": ".", "declaration": true, diff --git a/packages/loot-core/tsconfig.json b/packages/loot-core/tsconfig.json new file mode 100644 index 0000000000..c5d0d20cf5 --- /dev/null +++ b/packages/loot-core/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": true, + "types": ["vite/client", "vitest/globals", "node"], + "plugins": [{ "name": "typescript-strict-plugin", "paths": ["."] }] + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "typings/**/*.ts", + "typings/**/*.d.ts" + ], + "exclude": [ + "node_modules", + "build", + "lib-dist", + "**/*.test.ts", + "**/*.spec.ts" + ] +} diff --git a/packages/loot-core/typings/process-worker.ts b/packages/loot-core/typings/process-worker.ts new file mode 100644 index 0000000000..f4781bebf0 --- /dev/null +++ b/packages/loot-core/typings/process-worker.ts @@ -0,0 +1,12 @@ +import type { MessagePort } from 'worker_threads'; + +declare global { + namespace NodeJS { + // oxlint-disable-next-line typescript/consistent-type-definitions -- global Process augmentation requires interface for declaration merging + interface Process { + parentPort?: MessagePort; + } + } +} + +export {}; diff --git a/packages/loot-core/typings/window.ts b/packages/loot-core/typings/window.ts index e9387a5d3f..5ce4b36bff 100644 --- a/packages/loot-core/typings/window.ts +++ b/packages/loot-core/typings/window.ts @@ -51,6 +51,11 @@ type Actual = { declare global { var Actual: Actual; + // oxlint-disable-next-line typescript/consistent-type-definitions -- global Window augmentation requires interface + interface Window { + Actual: Actual; + } + var IS_TESTING: boolean; var currentMonth: string | null; diff --git a/packages/plugins-service/package.json b/packages/plugins-service/package.json index 62d8001b8b..fcca186c25 100644 --- a/packages/plugins-service/package.json +++ b/packages/plugins-service/package.json @@ -8,7 +8,8 @@ "scripts": { "build": "cross-env NODE_ENV=production ./bin/build-service-worker", "build-dev": "cross-env NODE_ENV=development ./bin/build-service-worker", - "watch": "cross-env NODE_ENV=development ./bin/build-service-worker --watch" + "watch": "cross-env NODE_ENV=development ./bin/build-service-worker --watch", + "typecheck": "tsc --noEmit && tsc-strict" }, "dependencies": { "workbox-precaching": "^7.4.0" @@ -17,6 +18,7 @@ "@types/node": "^22.19.10", "cross-env": "^10.1.0", "typescript": "^5.9.3", + "typescript-strict-plugin": "^2.4.4", "vite": "^7.3.1" } } diff --git a/packages/plugins-service/tsconfig.json b/packages/plugins-service/tsconfig.json index fab078e6e6..3cf12372d6 100644 --- a/packages/plugins-service/tsconfig.json +++ b/packages/plugins-service/tsconfig.json @@ -10,7 +10,8 @@ "strict": false, "types": ["vite/client"], "outDir": "dist", - "rootDir": "src" + "rootDir": "src", + "plugins": [{ "name": "typescript-strict-plugin", "paths": ["."] }] }, "include": ["src/**/*"], "exclude": ["node_modules"] diff --git a/packages/sync-server/package.json b/packages/sync-server/package.json index 9bb140a618..ef5f737997 100644 --- a/packages/sync-server/package.json +++ b/packages/sync-server/package.json @@ -16,6 +16,7 @@ "start": "yarn build && node build/app", "start-monitor": "nodemon --exec 'yarn build && node build/app' --ignore './build/**/*' --ext 'ts,js' build/app", "build": "tsc && yarn add-import-extensions && yarn copy-static-assets", + "typecheck": "tsc --noEmit && tsc-strict", "add-import-extensions": "node bin/add-import-extensions.mjs", "copy-static-assets": "rm -rf build/src/sql && cp -r src/sql build/src/sql", "test": "NODE_ENV=test NODE_OPTIONS='--experimental-vm-modules --import ./register-loader.mjs --trace-warnings' vitest --run", @@ -64,6 +65,7 @@ "nodemon": "^3.1.11", "supertest": "^7.2.2", "typescript": "^5.9.3", + "typescript-strict-plugin": "^2.4.4", "vitest": "^4.0.18" } } diff --git a/packages/sync-server/tsconfig.json b/packages/sync-server/tsconfig.json index 0c9b5aebc4..4ff66d7075 100644 --- a/packages/sync-server/tsconfig.json +++ b/packages/sync-server/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "lib": ["ES2021"], "noEmit": false, - "outDir": "build" + "outDir": "build", + "plugins": [{ "name": "typescript-strict-plugin", "paths": ["."] }] }, "include": [ "src/**/*", diff --git a/tsconfig.json b/tsconfig.json index 966fcd78ef..a2465d8379 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -36,13 +36,7 @@ "@desktop-client/e2e/*": ["./packages/desktop-client/e2e/*"], // Allow importing from hyperformula's internal typings for custom function plugins "hyperformula/typings/*": ["./node_modules/hyperformula/typings/*"] - }, - "plugins": [ - { - "name": "typescript-strict-plugin", - "path": ["./packages"] - } - ] + } }, "include": ["packages/**/*", "bin/*.ts"], "exclude": [ diff --git a/tsconfig.root.json b/tsconfig.root.json new file mode 100644 index 0000000000..67361eb861 --- /dev/null +++ b/tsconfig.root.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["bin/*.ts"], + "exclude": ["node_modules"] +} diff --git a/upcoming-release-notes/7019.md b/upcoming-release-notes/7019.md new file mode 100644 index 0000000000..622536029a --- /dev/null +++ b/upcoming-release-notes/7019.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +TypeScript: individual tsconfig files per package, running via lage diff --git a/yarn.lock b/yarn.lock index edbc88ef72..81a5019e6a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,6 +29,7 @@ __metadata: node-fetch: "npm:^3.3.2" tsc-alias: "npm:^1.8.16" typescript: "npm:^5.9.3" + typescript-strict-plugin: "npm:^2.4.4" uuid: "npm:^13.0.0" vitest: "npm:^4.0.18" languageName: unknown @@ -128,6 +129,7 @@ __metadata: pluggy-sdk: "npm:^0.83.0" supertest: "npm:^7.2.2" typescript: "npm:^5.9.3" + typescript-strict-plugin: "npm:^2.4.4" uuid: "npm:^13.0.0" vitest: "npm:^4.0.18" winston: "npm:^3.19.0" @@ -212,6 +214,8 @@ __metadata: remark-gfm: "npm:^4.0.1" rollup-plugin-visualizer: "npm:^6.0.5" sass: "npm:^1.97.3" + typescript: "npm:^5.9.3" + typescript-strict-plugin: "npm:^2.4.4" usehooks-ts: "npm:^3.1.1" uuid: "npm:^13.0.0" vite: "npm:^7.3.1" @@ -4508,11 +4512,11 @@ __metadata: linkType: hard "@isaacs/brace-expansion@npm:^5.0.0": - version: 5.0.1 - resolution: "@isaacs/brace-expansion@npm:5.0.1" + version: 5.0.0 + resolution: "@isaacs/brace-expansion@npm:5.0.0" dependencies: "@isaacs/balanced-match": "npm:^4.0.1" - checksum: 10/aec226065bc4285436a27379e08cc35bf94ef59f5098ac1c026495c9ba4ab33d851964082d3648d56d63eb90f2642867bd15a3e1b810b98beb1a8c14efce6a94 + checksum: 10/cf3b7f206aff12128214a1df764ac8cdbc517c110db85249b945282407e3dfc5c6e66286383a7c9391a059fc8e6e6a8ca82262fc9d2590bd615376141fbebd2d languageName: node linkType: hard @@ -10791,7 +10795,6 @@ __metadata: source-map-support: "npm:^0.5.21" ts-node: "npm:^10.9.2" typescript: "npm:^5.9.3" - typescript-strict-plugin: "npm:^2.4.4" languageName: unknown linkType: soft @@ -14414,6 +14417,7 @@ __metadata: fs-extra: "npm:^11.3.3" promise-retry: "npm:^2.0.1" typescript: "npm:^5.9.3" + typescript-strict-plugin: "npm:^2.4.4" languageName: unknown linkType: soft @@ -19687,6 +19691,7 @@ __metadata: stream-browserify: "npm:^3.0.0" ts-node: "npm:^10.9.2" typescript: "npm:^5.9.3" + typescript-strict-plugin: "npm:^2.4.4" ua-parser-js: "npm:^2.0.9" uuid: "npm:^13.0.0" vite: "npm:^7.3.1" @@ -22681,6 +22686,7 @@ __metadata: "@types/node": "npm:^22.19.10" cross-env: "npm:^10.1.0" typescript: "npm:^5.9.3" + typescript-strict-plugin: "npm:^2.4.4" vite: "npm:^7.3.1" workbox-precaching: "npm:^7.4.0" languageName: unknown