diff --git a/.vscode/extensions.json b/.vscode/extensions.json index a0aac80..733b417 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,7 @@ { "recommendations": [ "stylelint.vscode-stylelint", - "dbaeumer.vscode-eslint" + "dbaeumer.vscode-eslint", + "typescriptteam.native-preview" ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 8c0111c..cd2c7b2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,9 @@ { "files.eol": "\n", "postman.settings.dotenv-detection-notification-visibility": false, + // Use the native TypeScript compiler (tsgo, @typescript/native-preview) as the + // editor language server. Requires the "TypeScript (Native Preview)" extension. + // Every typecheck target now runs tsgo, so the whole workspace — incl. apps/backend + // (node16) — is tsgo-compatible. + "typescript.experimental.useTsgo": true, } diff --git a/CLAUDE.md b/CLAUDE.md index 1968407..b76e34b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -78,7 +78,7 @@ Standard Nest module layout (`words`, `user`, `auth`, `supabase`, `config`, `com Env is validated at startup (`src/config/env.validation.ts`); missing vars exit the process with a readable message instead of failing on the first request. See `apps/backend/README.md`. -Database types are generated, not hand-written: `generate-types` in `apps/backend` regenerates `database.types.ts` and copies it into `packages/api`. Do not edit those files, and note `lint` runs with `--fix` — the generated types are eslint-ignored so it cannot reformat them. +Database types are generated, not hand-written: `generate-types` in `apps/backend` regenerates `database.types.ts` and copies it into `packages/api`. Do not edit those files (they are eslint-ignored, so `lint:fix` cannot reformat them). Backend `lint` is check-only; use `lint:fix` to autofix — same split as every other package. **The API contract is generated too.** Backend DTOs → Swagger → `packages/api/src/schemas/openapi.json` → `api.ts` → SDK → `apps/web`. After changing a DTO or a handler's return type, run `pnpm --filter app-backend generate:api-schemas` (needs a valid root `.env`) and commit the regenerated schemas, otherwise `apps/web` typechecks against a stale contract. diff --git a/apps/backend/package.json b/apps/backend/package.json index b9e0173..ab4a405 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -7,8 +7,9 @@ "start": "nest start", "start:dev": "nest start --watch", "start:prod": "node dist/main.js", - "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", - "typecheck": "tsc --noEmit", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"", + "lint:fix": "npm run lint -- --fix", + "typecheck": "tsgo --noEmit", "generate:api-schemas": "ts-node --project tsconfig.json scripts/generate-api-schemas.ts", "generate-types": "ts-node ./scripts/generate-db-types.ts", "test:unit": "vitest", diff --git a/apps/backend/test/nest-app.ts b/apps/backend/test/nest-app.ts index 5f14953..1c3c005 100644 --- a/apps/backend/test/nest-app.ts +++ b/apps/backend/test/nest-app.ts @@ -46,8 +46,8 @@ export const supabaseStub = { export const createTestApp = async ( supabase: unknown = supabaseStub, ): Promise => { - const { AppModule } = await import("../src/app.module"); - const { SupabaseService } = await import("../src/supabase/supabase.service"); + const { AppModule } = await import("../src/app.module.js"); + const { SupabaseService } = await import("../src/supabase/supabase.service.js"); const moduleRef = await Test.createTestingModule({ imports: [AppModule] }) .overrideProvider(SupabaseService) diff --git a/apps/backend/tsconfig.json b/apps/backend/tsconfig.json index 9bcf7c2..90f0e99 100644 --- a/apps/backend/tsconfig.json +++ b/apps/backend/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "target": "ES2021", "lib": ["ES2021"], "declaration": true, @@ -14,11 +14,10 @@ "strictNullChecks": true, "noImplicitAny": true, "strictBindCallApply": true, - "forceConsistentCasingInFileNames": false, + "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": false, "sourceMap": true, "outDir": "./dist", - "baseUrl": "./", "incremental": true, "resolveJsonModule": true, "types": ["node"], diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 566c06a..cadce83 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -7,7 +7,7 @@ "scripts": { "build": "storybook build -o dist-storybook", "storybook": "storybook dev --no-open -p 6006", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "@heroui/system": "^2.4.23", diff --git a/apps/storybook/tsconfig.json b/apps/storybook/tsconfig.json index e2a5be8..c06251b 100644 --- a/apps/storybook/tsconfig.json +++ b/apps/storybook/tsconfig.json @@ -5,8 +5,6 @@ "include": [ ".", ".storybook/**/*", - ], - "compilerOptions": { - "baseUrl": ".", - } + "../../types/assets.d.ts", + ] } \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index 17fbc6f..89d14f3 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -24,7 +24,7 @@ "start:prod": "cross-env NODE_ENV=production tsx src/server/main.ts", "stylelint": "stylelint \"**/*.{css,scss}\" --config ../../stylelint.config.mjs", "stylelint:fix": "pnpm run stylelint -- --fix", - "typecheck": "tsc --build ./tsconfig.json", + "typecheck": "tsgo --build ./tsconfig.json", "knip": "knip --config ./knip.config.ts" }, "dependencies": { diff --git a/apps/web/src/locales/tsconfig.json b/apps/web/src/locales/tsconfig.json index dbd9355..36371a9 100644 --- a/apps/web/src/locales/tsconfig.json +++ b/apps/web/src/locales/tsconfig.json @@ -6,7 +6,6 @@ "**/*.json" ], "compilerOptions": { - "baseUrl": ".", "resolveJsonModule": true, } } \ No newline at end of file diff --git a/apps/web/src/server/tsconfig.json b/apps/web/src/server/tsconfig.json index b971625..98c7582 100644 --- a/apps/web/src/server/tsconfig.json +++ b/apps/web/src/server/tsconfig.json @@ -12,7 +12,6 @@ } ], "compilerOptions": { - "baseUrl": ".", // TODO: Fix relative server paths // "paths": { // "@/*": ["./*"], diff --git a/apps/web/src/shared/tsconfig.json b/apps/web/src/shared/tsconfig.json index c08a3cb..45ca08a 100644 --- a/apps/web/src/shared/tsconfig.json +++ b/apps/web/src/shared/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ "." - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/apps/web/src/ui/tsconfig.json b/apps/web/src/ui/tsconfig.json index d93a2ea..f0cece1 100644 --- a/apps/web/src/ui/tsconfig.json +++ b/apps/web/src/ui/tsconfig.json @@ -4,11 +4,10 @@ ], "include": [ ".", - "typings.d.ts", + "../../../../types/assets.d.ts", "../vite-env.d.ts" ], "exclude": [ - "**/*.test.*", "**/*.test.*", "**/*.stories.*", "**/__stories__", @@ -23,7 +22,6 @@ } ], "compilerOptions": { - "baseUrl": ".", "paths": { "@/*": [ "./*" diff --git a/apps/web/src/ui/typings.d.ts b/apps/web/src/ui/typings.d.ts deleted file mode 100644 index e0ceb0e..0000000 --- a/apps/web/src/ui/typings.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module "*.scss" { - const content: Record; - export default content; -} diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index ce63b02..1e7677c 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -5,6 +5,7 @@ "compilerOptions": { "rootDir": ".", "outDir": "./.typecheck", + "noEmit": true, }, "include": [ "*.config.ts", diff --git a/docs/tsgo-benchmark.md b/docs/tsgo-benchmark.md new file mode 100644 index 0000000..b5477b9 --- /dev/null +++ b/docs/tsgo-benchmark.md @@ -0,0 +1,74 @@ +# Typecheck: `tsc` → `tsgo` migration (`@typescript/native-preview`) + +Type checking was moved from classic `tsc` to the native `tsgo` compiler +(`@typescript/native-preview`, TypeScript 7 preview). Speedup measurements below. + +## Results (hyperfine / Measure-Command, Windows 11, warm FS cache) + +| Target | tsc | tsgo | Speedup | +|---|---|---|---| +| `apps/web` (`--build`, project references) | 4.13 s | 0.86 s | **4.77×** | +| `packages/uikit` (`--noEmit`) | 2.37 s | 0.39 s | **6.07×** | +| `packages/class-names` (`--noEmit`, small) | 0.83 s | 0.21 s | **3.86×** | +| **All 19 migrated targets** (sum, without nx) | **22.35 s** | **5.06 s** | **4.42×** | + +A full type-check pass over the migrated packages dropped from ~22 s to ~5 s +(~17 s saved). Smaller packages gain less — there the fixed process-startup cost +dominates. + +Methodology: `hyperfine -w 1 -r 5` for single targets (for `apps/web` — `-r 3`, +clearing `.typecheck` before each run); the aggregate is the sum of pure compiler +time across all 19 targets, averaged over 2 runs after warmup, without the nx +wrapper. Both compilers run against the same tsconfigs. + +## What changed + +- **All 20** typecheck scripts switched to `tsgo` (`tsc --noEmit` → `tsgo --noEmit`; + `apps/web`: `tsc --build` → `tsgo --build`). +- `@typescript/native-preview` added to the root devDependencies. `typescript`/`tsc` + is kept — it remains the runtime compiler for `tsx`, `nest build`, `vitest`, + `ts-node`, `vite`. +- **IDE:** the native tsgo language server is enabled — `.vscode/settings.json` → + `typescript.experimental.useTsgo: true`, and the `typescriptteam.native-preview` + extension is added to the recommendations (`.vscode/extensions.json`). Works in + both VS Code and Cursor. + +### Config changes required by TypeScript 7 + +tsgo is TS7, which removed a few options that the project actually used: + +- **`baseUrl` removed.** Dropped from every tsgo target (it was redundant: `paths` + work without it and resolve relative to the tsconfig directory). Verified green on + `tsc 5.7`. +- **Style side-effect imports** (`import "./x.scss"`) now require an ambient module + declaration (error TS2882), which `tsc` silently tolerated. Added a shared + `types/assets.d.ts` (`declare module "*.scss" | "*.css"`), wired via `include` into + the packages whose programs compile UI sources directly or transitively through + `@languages-learner/uikit` (`uikit`, `data-source`, `storybook`, `apps/web/src/ui`). + +### `apps/backend` modernized for TS7 + +`apps/backend` used `moduleResolution: "node"`, which was removed in TS7. It was +switched to `module: node16` + `moduleResolution: node16`. The only source change: +dynamic `import()` calls in `test/nest-app.ts` require the `.js` extension (ESM +resolution): `import("../src/app.module")` → `import("../src/app.module.js")`. +Verified nothing broke: + +- `tsgo --noEmit` and `tsc --noEmit` — green; +- 64 unit/e2e tests (`vitest`/`swc`) pass — the runtime resolves `.js` → `.ts`; +- `nest build` still emits CommonJS (`module: node16` for a CJS package without + `"type": "module"` yields `require`/`exports`). + +### Incidental cleanups + +- `apps/web/tsconfig.json`: added `noEmit: true` — the solution project no longer + emits config-file JS into `.typecheck/`. +- `apps/web/src/ui/tsconfig.json`: removed the duplicated `"**/*.test.*"` in `exclude`. +- `apps/backend/tsconfig.json`: `forceConsistentCasingInFileNames` aligned to `true` + (consistent with the base config). + +## Next (out of scope for this migration) + +- **Nx cache for `typecheck`** (`targetDefaults` in `nx.json`) — not configured yet, + so type checking is recomputed for every project on each run. Orthogonal to tsgo; + would let unchanged projects be skipped. Planned as a separate phase. diff --git a/nx.json b/nx.json index 086b82f..bb3cafe 100644 --- a/nx.json +++ b/nx.json @@ -1,3 +1,49 @@ { - "$schema": "./node_modules/nx/schemas/nx-schema.json" -} \ No newline at end of file + "$schema": "./node_modules/nx/schemas/nx-schema.json", + "namedInputs": { + "default": ["{projectRoot}/**/*", "sharedGlobals"], + "sharedGlobals": [ + "{workspaceRoot}/pnpm-lock.yaml", + "{workspaceRoot}/tsconfig.base.json", + "{workspaceRoot}/tsconfig.base.composite.json", + "{workspaceRoot}/types/**/*" + ] + }, + "targetDefaults": { + "typecheck": { + "cache": true, + "inputs": ["default", "^default"], + "outputs": [] + }, + "lint": { + "cache": true, + "inputs": [ + "default", + "^default", + "{workspaceRoot}/eslint.config.mjs", + "{workspaceRoot}/prettier.config.mjs" + ], + "outputs": [] + }, + "test:unit:ci": { + "cache": true, + "inputs": [ + "default", + "^default", + "{workspaceRoot}/vitest.config.ts", + "{workspaceRoot}/vitest.shims.d.ts" + ], + "outputs": [] + }, + "stylelint": { + "cache": true, + "inputs": ["default", "{workspaceRoot}/stylelint.config.mjs"], + "outputs": [] + }, + "circular-deps": { + "cache": true, + "inputs": ["default"], + "outputs": [] + } + } +} diff --git a/package.json b/package.json index 6f4c9e4..f47d501 100644 --- a/package.json +++ b/package.json @@ -37,10 +37,12 @@ "devDependencies": { "@formatjs/cli": "^6.7.1", "@languages-learner/har-sanitizer": "workspace:*", + "@playwright/experimental-ct-react": "1.52.0", "@tanstack/eslint-config": "^0.3.3", "@types/node": "^22.15.29", "@types/react": "^19.0.10", "@types/react-dom": "^19.2.3", + "@typescript/native-preview": "7.0.0-dev.20260707.2", "@vitest/browser": "^3.1.4", "cross-env": "^7.0.3", "eslint": "^9.39.1", @@ -68,8 +70,7 @@ "ts-node": "11.0.0-beta.1", "typescript": "~5.7.2", "typescript-eslint": "^8.26.1", - "vitest": "^3.1.4", - "@playwright/experimental-ct-react": "1.52.0" + "vitest": "^3.1.4" }, "pnpm": { "overrides": { diff --git a/packages/api/package.json b/packages/api/package.json index a5fdf32..111e930 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "@supabase/supabase-js": "2.49.4" diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index ab56f64..8b40cc0 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ "./src", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } diff --git a/packages/app-core-tests-utils/package.json b/packages/app-core-tests-utils/package.json index d4e7802..c6bef20 100644 --- a/packages/app-core-tests-utils/package.json +++ b/packages/app-core-tests-utils/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "devDependencies": { "@playwright/test": "1.52.0", diff --git a/packages/app-integration-tests-utils/package.json b/packages/app-integration-tests-utils/package.json index fd36396..22021a9 100644 --- a/packages/app-integration-tests-utils/package.json +++ b/packages/app-integration-tests-utils/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "devDependencies": { "@languages-learner/playwright-utils": "workspace:*", diff --git a/packages/class-names/package.json b/packages/class-names/package.json index bdc8b21..3e88e65 100644 --- a/packages/class-names/package.json +++ b/packages/class-names/package.json @@ -9,7 +9,7 @@ "lint:fix": "npm run lint -- --fix", "test:unit": "vitest", "test:unit:ci": "vitest --run", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "devDependencies": { "@bem-react/classname": "^1.7.0", diff --git a/packages/class-names/tsconfig.json b/packages/class-names/tsconfig.json index eb751bd..562939f 100644 --- a/packages/class-names/tsconfig.json +++ b/packages/class-names/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/packages/component-core-tests-utils/package.json b/packages/component-core-tests-utils/package.json index 21cd136..6cebb49 100644 --- a/packages/component-core-tests-utils/package.json +++ b/packages/component-core-tests-utils/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "@playwright/experimental-ct-react": "1.52.0", diff --git a/packages/data-source/package.json b/packages/data-source/package.json index 418196d..1b69155 100644 --- a/packages/data-source/package.json +++ b/packages/data-source/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "@gravity-ui/data-source": "^0.6.1", diff --git a/packages/data-source/tsconfig.json b/packages/data-source/tsconfig.json index eb751bd..ed60bfc 100644 --- a/packages/data-source/tsconfig.json +++ b/packages/data-source/tsconfig.json @@ -4,8 +4,6 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + "../../types/assets.d.ts", + ] } \ No newline at end of file diff --git a/packages/error-utils/package.json b/packages/error-utils/package.json index fb5d2b8..158802f 100644 --- a/packages/error-utils/package.json +++ b/packages/error-utils/package.json @@ -9,7 +9,7 @@ "lint:fix": "npm run lint -- --fix", "test:unit": "vitest", "test:unit:ci": "vitest --run", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "devDependencies": { "vitest": "^3.1.4" diff --git a/packages/error-utils/tsconfig.json b/packages/error-utils/tsconfig.json index eb751bd..562939f 100644 --- a/packages/error-utils/tsconfig.json +++ b/packages/error-utils/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/packages/form-components/package.json b/packages/form-components/package.json index eebd1ec..5c54f49 100644 --- a/packages/form-components/package.json +++ b/packages/form-components/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "@heroui/input": "^2.4.28", diff --git a/packages/har-sanitizer/package.json b/packages/har-sanitizer/package.json index 5e97270..3f6dd8f 100644 --- a/packages/har-sanitizer/package.json +++ b/packages/har-sanitizer/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "@types/har-format": "^1.2.16" diff --git a/packages/har-sanitizer/tsconfig.json b/packages/har-sanitizer/tsconfig.json index eb751bd..562939f 100644 --- a/packages/har-sanitizer/tsconfig.json +++ b/packages/har-sanitizer/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/packages/i18n-core/package.json b/packages/i18n-core/package.json index c0d036c..6c7c713 100644 --- a/packages/i18n-core/package.json +++ b/packages/i18n-core/package.json @@ -7,6 +7,6 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" } } diff --git a/packages/i18n-core/tsconfig.json b/packages/i18n-core/tsconfig.json index eb751bd..562939f 100644 --- a/packages/i18n-core/tsconfig.json +++ b/packages/i18n-core/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/packages/locale/package.json b/packages/locale/package.json index 3df87a4..dda1655 100644 --- a/packages/locale/package.json +++ b/packages/locale/package.json @@ -7,6 +7,6 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" } } diff --git a/packages/locale/tsconfig.json b/packages/locale/tsconfig.json index eb751bd..562939f 100644 --- a/packages/locale/tsconfig.json +++ b/packages/locale/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/packages/playwright-utils/package.json b/packages/playwright-utils/package.json index 8cf9b31..c2fef61 100644 --- a/packages/playwright-utils/package.json +++ b/packages/playwright-utils/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "devDependencies": { "@languages-learner/har-sanitizer": "workspace:*", diff --git a/packages/react-router-utils/package.json b/packages/react-router-utils/package.json index 5f6d140..6dd685e 100644 --- a/packages/react-router-utils/package.json +++ b/packages/react-router-utils/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "react": "^19.2.0", diff --git a/packages/react-router-utils/tsconfig.json b/packages/react-router-utils/tsconfig.json index eb751bd..562939f 100644 --- a/packages/react-router-utils/tsconfig.json +++ b/packages/react-router-utils/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/packages/react-utils/package.json b/packages/react-utils/package.json index e01a874..aa5162c 100644 --- a/packages/react-utils/package.json +++ b/packages/react-utils/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "react": "^19.2.0" diff --git a/packages/react-utils/tsconfig.json b/packages/react-utils/tsconfig.json index eb751bd..562939f 100644 --- a/packages/react-utils/tsconfig.json +++ b/packages/react-utils/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/packages/tailwind/package.json b/packages/tailwind/package.json index f87c43a..11724e2 100644 --- a/packages/tailwind/package.json +++ b/packages/tailwind/package.json @@ -8,7 +8,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "devDependencies": { "@heroui/theme": "^2.4.23", diff --git a/packages/tailwind/tsconfig.json b/packages/tailwind/tsconfig.json index ec70878..d093ce8 100644 --- a/packages/tailwind/tsconfig.json +++ b/packages/tailwind/tsconfig.json @@ -8,6 +8,5 @@ ], "compilerOptions": { "allowJs": true, - "baseUrl": ".", } } \ No newline at end of file diff --git a/packages/uikit/package.json b/packages/uikit/package.json index cf91afe..a270002 100644 --- a/packages/uikit/package.json +++ b/packages/uikit/package.json @@ -11,7 +11,7 @@ "test:component:docker": "pnpm -w run component-tests:test uikit test:component", "test:component:update": "npm run test:component -- -update", "test:component:update:docker": "pnpm -w run component-tests:test uikit test:component:update", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "@heroui/button": "^2.2.27", diff --git a/packages/uikit/tsconfig.json b/packages/uikit/tsconfig.json index acaaa99..60d2c2f 100644 --- a/packages/uikit/tsconfig.json +++ b/packages/uikit/tsconfig.json @@ -4,6 +4,7 @@ ], "include": [ ".", - "../playwright-utils/src/types/goToWithLocaleFixture.d.ts" + "../playwright-utils/src/types/goToWithLocaleFixture.d.ts", + "../../types/assets.d.ts" ] } \ No newline at end of file diff --git a/packages/zod/package.json b/packages/zod/package.json index 3183e87..042d728 100644 --- a/packages/zod/package.json +++ b/packages/zod/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint --concurrency=auto .", "lint:fix": "npm run lint -- --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit" }, "dependencies": { "lodash": "^4.17.21" diff --git a/packages/zod/tsconfig.json b/packages/zod/tsconfig.json index eb751bd..562939f 100644 --- a/packages/zod/tsconfig.json +++ b/packages/zod/tsconfig.json @@ -4,8 +4,5 @@ ], "include": [ ".", - ], - "compilerOptions": { - "baseUrl": ".", - } + ] } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e0db67b..a891c05 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.7) + '@typescript/native-preview': + specifier: 7.0.0-dev.20260707.2 + version: 7.0.0-dev.20260707.2 '@vitest/browser': specifier: ^3.1.4 version: 3.2.4(playwright@1.57.0)(vite@6.4.1(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)(sugarss@2.0.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vitest@3.2.4) @@ -173,7 +176,7 @@ importers: devDependencies: '@nestjs/cli': specifier: ^10.4.8 - version: 10.4.9(@swc/core@1.15.46(@swc/helpers@0.5.17)) + version: 10.4.9(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12) '@nestjs/schematics': specifier: ^10.1.1 version: 10.2.3(chokidar@3.6.0)(typescript@5.7.3) @@ -3175,6 +3178,53 @@ packages: resolution: {integrity: sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-wny2pgKjGbiZtnOIHVa3tXC1UfDqxNEFzyPGmiqybedG8hipG2Nfp0l5UxbaKCjkLacUpH/W5bP2hBOMVhCOzg==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-Afc7M5zOwo+GpfcYwz5Z8HMB2tPVsui7nNIqEuuFB73MPdVqNn/Wmpe4tP4MRri0AtJnJknoHBaTJ/VDAp/Jhw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-iITBa2WjjTI5N9t5l7Z4KoOSI+2zBlhbvFzsD/f8qX8QoKjz/Y4DPyBDgezYi8nkqjjksbgSOJ3/ykzhwrB9cg==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/native-preview-linux-arm@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-hJm/UOqZTr9FHmR7uNm8VGX4oKtfWk0Jem0zPeJFNC8ckGUfSBueyiEYMZB+XmRc1aG4x1E46y3CplP4CLHvGQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/native-preview-linux-x64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-du0dzi6y97Po5vDNdPJTyyijHCpaS22JLRnKZEJXBDaO9gCIymOv/5QQokFRuOlQm0bWl3i9PF4OVdGP6uAOQA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-SsAwfhyHJ1akgBc+99z4+hwdbHsdWaKB8EwCNIMA6JfSLMeUjffrYvxu+vfMyxVtOVOz7RrRXRoiDiu4a2sCtg==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/native-preview-win32-x64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-DL4u27stv0fo71sVhOzHSwE+YMZsbBijVI+kg5dLDLilSH79WFTJ8RSQ46vJrCMt+Gjlv/JOZP1PuLJDfioYeQ==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@typescript/native-preview@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-oUGp+Rep/hqMhPunyinsALUwSlzHINSxitifPiSaeqoKOKD2OlR9NE3TaPqwsl4NlGslsOSUXI1JotWQzpYCPg==} + engines: {node: '>=16.20.0'} + hasBin: true + '@unrs/resolver-binding-android-arm-eabi@1.11.1': resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} cpu: [arm] @@ -9315,7 +9365,7 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@nestjs/cli@10.4.9(@swc/core@1.15.46(@swc/helpers@0.5.17))': + '@nestjs/cli@10.4.9(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12)': dependencies: '@angular-devkit/core': 17.3.11(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0) @@ -9325,7 +9375,7 @@ snapshots: chokidar: 3.6.0 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.7.2)(webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))) + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.7.2)(webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12)) glob: 10.4.5 inquirer: 8.2.6 node-emoji: 1.11.0 @@ -9334,7 +9384,7 @@ snapshots: tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 typescript: 5.7.2 - webpack: 5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17)) + webpack: 5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12) webpack-node-externals: 3.0.0 optionalDependencies: '@swc/core': 1.15.46(@swc/helpers@0.5.17) @@ -10942,6 +10992,37 @@ snapshots: '@typescript-eslint/types': 8.48.1 eslint-visitor-keys: 4.2.1 + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-linux-arm@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-linux-x64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-win32-x64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview@7.0.0-dev.20260707.2': + optionalDependencies: + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260707.2 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260707.2 + '@unrs/resolver-binding-android-arm-eabi@1.11.1': optional: true @@ -12932,7 +13013,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))): + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12)): dependencies: '@babel/code-frame': 7.27.1 chalk: 4.1.2 @@ -12947,7 +13028,7 @@ snapshots: semver: 7.7.3 tapable: 2.3.0 typescript: 5.7.2 - webpack: 5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17)) + webpack: 5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12) form-data@4.0.5: dependencies: @@ -15861,15 +15942,16 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - terser-webpack-plugin@5.3.17(@swc/core@1.15.46(@swc/helpers@0.5.17))(webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))): + terser-webpack-plugin@5.3.17(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12)(webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 terser: 5.46.0 - webpack: 5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17)) + webpack: 5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12) optionalDependencies: '@swc/core': 1.15.46(@swc/helpers@0.5.17) + esbuild: 0.25.12 terser@5.46.0: dependencies: @@ -16394,7 +16476,7 @@ snapshots: webpack-virtual-modules@0.6.2: {} - webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17)): + webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -16416,7 +16498,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.3.0 - terser-webpack-plugin: 5.3.17(@swc/core@1.15.46(@swc/helpers@0.5.17))(webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))) + terser-webpack-plugin: 5.3.17(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12)(webpack@5.97.1(@swc/core@1.15.46(@swc/helpers@0.5.17))(esbuild@0.25.12)) watchpack: 2.5.1 webpack-sources: 3.3.4 transitivePeerDependencies: diff --git a/stylelint.config.mjs b/stylelint.config.mjs index 4064da4..a001bf6 100644 --- a/stylelint.config.mjs +++ b/stylelint.config.mjs @@ -5,6 +5,18 @@ export default { "stylelint-config-standard-scss", "stylelint-config-rational-order", ], + // Never lint build output — the globs (`**/*.{css,scss}`) would otherwise pick up + // bundled/minified CSS in gitignored dirs like `apps/web/dist`. + ignoreFiles: [ + "**/dist/**", + "**/dist-ssr/**", + "**/dist-docker/**", + "**/dist-storybook/**", + "**/dev-dist/**", + "**/storybook-static/**", + "**/.typecheck/**", + "**/coverage/**", + ], rules: { "selector-pseudo-class-no-unknown": [ true, diff --git a/types/assets.d.ts b/types/assets.d.ts new file mode 100644 index 0000000..8cb0868 --- /dev/null +++ b/types/assets.d.ts @@ -0,0 +1,13 @@ +// Ambient declarations for style side-effect imports (`import "./x.scss"`). +// TypeScript 7 / tsgo reports TS2882 for side-effect imports without a module +// declaration, whereas tsc <=5.7 silently tolerated them. Shared across packages +// that compile UI source (directly or transitively through `@languages-learner/uikit`). +declare module "*.scss" { + const content: Record; + export default content; +} + +declare module "*.css" { + const content: Record; + export default content; +}