From adae0b76b1d1fd7f45e45dcbc0b59e8e2b5d87df Mon Sep 17 00:00:00 2001 From: Matsu Date: Wed, 9 Sep 2026 08:21:17 +0300 Subject: [PATCH] build(editor): Improve frontend builds (#37869) Co-authored-by: Claude Opus 5 (1M context) Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --- .github/workflows/ci-pull-requests.yml | 22 ++ .../test-frontend-declarations-reusable.yml | 44 ++++ packages/@n8n/mcp-apps/tsconfig.json | 3 +- packages/extensions/insights/package.json | 5 +- packages/extensions/insights/vite.config.ts | 4 +- packages/frontend/@n8n/chat/package.json | 5 +- .../frontend/@n8n/chat/tsconfig.build.json | 24 +++ packages/frontend/@n8n/chat/vite.config.mts | 19 +- .../frontend/@n8n/design-system/package.json | 5 +- .../@n8n/design-system/vite.config.mts | 30 +-- .../@n8n/frontend-module-sdk/tsconfig.json | 7 +- .../frontend/@n8n/storybook/tsconfig.app.json | 1 + .../components/SuggestedPromptsEditor.vue | 4 +- packages/frontend/editor-ui/tsconfig.json | 3 +- packages/frontend/editor-ui/vite.config.mts | 8 +- .../frontend/editor-ui/vite/aliases.test.ts | 49 ++++- pnpm-lock.yaml | 197 +++++++++--------- pnpm-workspace.yaml | 3 +- turbo.json | 23 ++ 19 files changed, 324 insertions(+), 132 deletions(-) create mode 100644 .github/workflows/test-frontend-declarations-reusable.yml create mode 100644 packages/frontend/@n8n/chat/tsconfig.build.json diff --git a/.github/workflows/ci-pull-requests.yml b/.github/workflows/ci-pull-requests.yml index 6a810d2753e..da07d342e9b 100644 --- a/.github/workflows/ci-pull-requests.yml +++ b/.github/workflows/ci-pull-requests.yml @@ -24,6 +24,7 @@ jobs: unit: ${{ fromJSON(steps.ci-filter.outputs.results).unit == true }} e2e: ${{ fromJSON(steps.ci-filter.outputs.results).e2e == true }} dev_server_smoke: ${{ fromJSON(steps.ci-filter.outputs.results)['dev-server-smoke'] == true }} + frontend_declarations: ${{ fromJSON(steps.ci-filter.outputs.results)['frontend-declarations'] == true }} workflows: ${{ fromJSON(steps.ci-filter.outputs.results).workflows == true }} workflow_scripts: ${{ fromJSON(steps.ci-filter.outputs.results)['workflow-scripts'] == true }} db: ${{ fromJSON(steps.ci-filter.outputs.results).db == true }} @@ -116,6 +117,14 @@ jobs: packages/testing/playwright/playwright-projects.ts packages/testing/playwright/package.json .github/workflows/test-dev-server-smoke-reusable.yml + frontend-declarations: + packages/frontend/@n8n/design-system/** + packages/frontend/@n8n/chat/** + packages/frontend/@n8n/frontend-vite-config/** + turbo.json + .github/workflows/ci-pull-requests.yml + .github/workflows/test-frontend-declarations-reusable.yml + .github/actions/setup-nodejs/** workflows: .github/** workflow-scripts: .github/scripts/** @@ -337,6 +346,18 @@ jobs: ref: ${{ needs.install-and-build.outputs.commit_sha }} secrets: inherit + # `@n8n/design-system` and `@n8n/chat` emit their declarations only when `RELEASE` is set, + # because no consumer in this repo reads them and the emit costs ~15s of build time. No other + # CI job builds them that way, so a break in the declaration emit would first show up in a + # release. + frontend-declarations: + name: Frontend declarations + needs: install-and-build + if: needs.install-and-build.outputs.frontend_declarations == 'true' + uses: ./.github/workflows/test-frontend-declarations-reusable.yml + with: + ref: ${{ needs.install-and-build.outputs.commit_sha }} + db-tests: name: DB Tests needs: install-and-build @@ -411,6 +432,7 @@ jobs: check-packaging, e2e, dev-server-smoke, + frontend-declarations, db-tests, security-checks, workflow-scripts, diff --git a/.github/workflows/test-frontend-declarations-reusable.yml b/.github/workflows/test-frontend-declarations-reusable.yml new file mode 100644 index 00000000000..9cef0e2e529 --- /dev/null +++ b/.github/workflows/test-frontend-declarations-reusable.yml @@ -0,0 +1,44 @@ +name: 'Test: Frontend declarations' + +on: + workflow_call: + inputs: + ref: + description: 'Git ref to test' + required: true + type: string + +permissions: {} + +jobs: + declarations: + name: Frontend declarations + runs-on: ${{ vars.RUNNER_PROVIDER == 'github' && 'ubuntu-latest' || 'blacksmith-4vcpu-ubuntu-2204' }} + timeout-minutes: 15 + permissions: + contents: read + env: + # Both vite configs read this as a flag. It is also part of the turbo cache key for these + # two build tasks, so this misses the declaration-less `dist` that the CI build cached. + RELEASE: true + + steps: + - name: Checkout + uses: useblacksmith/checkout@bcec731f1eb1367240608d1c889a75b96db6ec53 # v1.5.0 + with: + fetch-depth: 1 + ref: ${{ inputs.ref }} + + - name: Setup and build in release mode + uses: ./.github/actions/setup-nodejs + with: + build-command: pnpm turbo run build --filter=@n8n/design-system --filter=@n8n/chat + + - name: Verify the published frontend packages carry declarations + run: | + for pkg in packages/frontend/@n8n/design-system packages/frontend/@n8n/chat; do + if [ -z "$(find "$pkg/dist" -name '*.d.ts' -print -quit 2>/dev/null)" ]; then + echo "::error::$pkg/dist has no .d.ts — the RELEASE-gated declaration emit did not run" + exit 1 + fi + done diff --git a/packages/@n8n/mcp-apps/tsconfig.json b/packages/@n8n/mcp-apps/tsconfig.json index 4f1808ccbbd..e90807ac9a0 100644 --- a/packages/@n8n/mcp-apps/tsconfig.json +++ b/packages/@n8n/mcp-apps/tsconfig.json @@ -17,7 +17,8 @@ "skipLibCheck": true, "paths": { "@mcp-apps/*": ["./src/*"], - "@n8n/design-system*": ["../../frontend/@n8n/design-system/src*"] + "@n8n/design-system": ["../../frontend/@n8n/design-system/src/index.ts"], + "@n8n/design-system/*": ["../../frontend/@n8n/design-system/src/*"] } }, "include": ["src/**/*.ts", "src/**/*.vue"] diff --git a/packages/extensions/insights/package.json b/packages/extensions/insights/package.json index 33fbcd8ff3e..81d1e03cf87 100644 --- a/packages/extensions/insights/package.json +++ b/packages/extensions/insights/package.json @@ -58,8 +58,11 @@ "rimraf": "catalog:", "vite": "catalog:", "vitest": "catalog:", - "vite-plugin-dts": "catalog:", + "unplugin-dts": "catalog:", "vue-tsc": "catalog:frontend" }, + "peerDependencies": { + "@vue/language-core": "catalog:frontend" + }, "license": "LicenseRef-n8n-sustainable-use" } diff --git a/packages/extensions/insights/vite.config.ts b/packages/extensions/insights/vite.config.ts index 2b9bc8eb7d0..8743f3556bf 100644 --- a/packages/extensions/insights/vite.config.ts +++ b/packages/extensions/insights/vite.config.ts @@ -1,7 +1,7 @@ import { resolve } from 'path'; import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; -import dts from 'vite-plugin-dts'; +import dts from 'unplugin-dts/vite'; import { configDefaults as vitestConfig } from 'vitest/config'; const cwd = process.cwd(); @@ -10,8 +10,8 @@ export default defineConfig({ plugins: [ vue(), dts({ - rollupTypes: true, tsconfigPath: resolve(cwd, 'tsconfig.frontend.json'), + processor: 'vue', }), ], build: { diff --git a/packages/frontend/@n8n/chat/package.json b/packages/frontend/@n8n/chat/package.json index 4f0f0990d5c..1c850aefb18 100644 --- a/packages/frontend/@n8n/chat/package.json +++ b/packages/frontend/@n8n/chat/package.json @@ -68,10 +68,13 @@ "unplugin-icons": "^0.19.0", "typescript": "catalog:", "vite": "catalog:", - "vite-plugin-dts": "catalog:", + "unplugin-dts": "catalog:", "vitest": "catalog:", "vue-tsc": "catalog:frontend" }, + "peerDependencies": { + "@vue/language-core": "catalog:frontend" + }, "files": [ "README.md", "dist" diff --git a/packages/frontend/@n8n/chat/tsconfig.build.json b/packages/frontend/@n8n/chat/tsconfig.build.json new file mode 100644 index 00000000000..32bdbdb9096 --- /dev/null +++ b/packages/frontend/@n8n/chat/tsconfig.build.json @@ -0,0 +1,24 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": false, + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "dist", + // `rootDir` is what puts the declarations at `dist/index.d.ts`, where the `types` of the + // manifest points. Without it unplugin-dts takes the common directory of the program, + // which is the package root, and writes them to `dist/src/` instead. + "rootDir": "src", + "noUnusedLocals": false, + "noUnusedParameters": false, + "types": ["vite/client"], + // No entry for `@n8n/design-system`: the sibling `paths` of `tsconfig.json` map it to `src`, + // which pulls files outside `rootDir` into the program (TS6059) and points the declarations + // at another package's sources rather than its published types. + "paths": { + "@n8n/chat/*": ["./src/*"] + } + }, + "include": ["src/**/*.ts", "src/**/*.vue"], + "exclude": ["src/__tests__/**", "src/__stories__/**", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/packages/frontend/@n8n/chat/vite.config.mts b/packages/frontend/@n8n/chat/vite.config.mts index 5c6d3f0b7ad..61d86a1fee1 100644 --- a/packages/frontend/@n8n/chat/vite.config.mts +++ b/packages/frontend/@n8n/chat/vite.config.mts @@ -3,7 +3,7 @@ import { resolve } from 'path'; import { renameSync, writeFileSync, readFileSync, existsSync } from 'fs'; import vue from '@vitejs/plugin-vue'; import icons from 'unplugin-icons/vite'; -import dts from 'vite-plugin-dts'; +import dts from 'unplugin-dts/vite'; import { vitestConfig } from '@n8n/vitest-config/frontend'; import pkg from './package.json'; @@ -11,6 +11,10 @@ const includeVue = process.env.INCLUDE_VUE === 'true'; const srcPath = resolve(__dirname, 'src'); const packagesDir = resolve(__dirname, '..', '..', '..'); +// Only the published package reads these declarations; editor-ui reads `src` instead. +// `RELEASE` marks the paths that ship `dist`. +const emitDeclarations = !!process.env.RELEASE; + const banner = `/*! Package version @n8n/chat@${pkg.version} */`; // https://vitejs.dev/config/ @@ -23,7 +27,18 @@ export default mergeConfig( autoInstall: true, }), // The bundle pass emits the same declarations as the lib pass — skip the ~12s duplicate run. - ...(includeVue ? [] : [dts()]), + ...(includeVue || !emitDeclarations + ? [] + : [ + dts({ + // `tsconfig.build.json` sets the `rootDir` that puts the declarations at + // `dist/index.d.ts`, where the `types` of the manifest points, and drops the + // tests and stories from the published surface. + tsconfigPath: resolve(__dirname, 'tsconfig.build.json'), + entryRoot: srcPath, + processor: 'vue' + }), + ]), { name: 'rename-css-file', closeBundle() { diff --git a/packages/frontend/@n8n/design-system/package.json b/packages/frontend/@n8n/design-system/package.json index ed5e70fdfbe..0c55d858e4f 100644 --- a/packages/frontend/@n8n/design-system/package.json +++ b/packages/frontend/@n8n/design-system/package.json @@ -84,7 +84,7 @@ "typescript": "catalog:", "unplugin-icons": "catalog:frontend", "vite": "catalog:", - "vite-plugin-dts": "catalog:", + "unplugin-dts": "catalog:", "vite-svg-loader": "catalog:frontend", "vitest": "catalog:", "vitest-mock-extended": "catalog:", @@ -130,7 +130,8 @@ }, "peerDependencies": { "vue": "catalog:frontend", - "vue-router": "catalog:frontend" + "vue-router": "catalog:frontend", + "@vue/language-core": "catalog:frontend" }, "license": "LicenseRef-n8n-sustainable-use" } diff --git a/packages/frontend/@n8n/design-system/vite.config.mts b/packages/frontend/@n8n/design-system/vite.config.mts index f45a27efcc8..48c1f9544c8 100644 --- a/packages/frontend/@n8n/design-system/vite.config.mts +++ b/packages/frontend/@n8n/design-system/vite.config.mts @@ -3,7 +3,7 @@ import { cpSync, readFileSync } from 'node:fs'; import { resolve } from 'path'; import { build, defineConfig, mergeConfig, type InlineConfig, type Plugin } from 'vite'; import icons from 'unplugin-icons/vite'; -import dts from 'vite-plugin-dts'; +import dts from 'unplugin-dts/vite'; import { vitestConfig } from '@n8n/vitest-config/frontend'; import svgLoader from 'vite-svg-loader'; import { lucideIconsPlugin } from './src/icons/lucide/vite'; @@ -11,6 +11,10 @@ import { lucideIconsPlugin } from './src/icons/lucide/vite'; const srcDir = resolve(__dirname, 'src'); const distDir = resolve(__dirname, 'dist'); +// Only the published package reads these declarations, and the emit is ~10s of a ~14s build. +// Every consumer in this repo reads `src` instead. `RELEASE` marks the paths that ship `dist`. +const emitDeclarations = !!process.env.RELEASE; + const manifest = JSON.parse(readFileSync(resolve(__dirname, 'package.json'), 'utf-8')) as { dependencies?: Record; peerDependencies?: Record; @@ -130,17 +134,19 @@ export default mergeConfig( // directly, vue-tsc exits 0 and silently writes nothing for a component // whose template context reaches a type it cannot name (54 of them during // the spike). Acceptance counts emitted files, not the exit code. - dts({ - // `tsconfig.build.json` rather than `tsconfig.json`: the latter maps the - // sibling `@n8n/*` packages to their `src`, which pulls files outside - // `rootDir` into the program (TS6059) and points the declarations at - // another package's sources instead of its published types. - tsconfigPath: resolve(__dirname, 'tsconfig.build.json'), - // Per-file declarations, not a rollup: api-extractor cannot follow `.vue` - // module specifiers and leaves the imports dangling. Rejected in ADR-0002. - rollupTypes: false, - entryRoot: resolve(__dirname, 'src'), - }), + ...(emitDeclarations + ? [ + dts({ + // `tsconfig.build.json` rather than `tsconfig.json`: the latter maps the + // sibling `@n8n/*` packages to their `src`, which pulls files outside + // `rootDir` into the program (TS6059) and points the declarations at + // another package's sources instead of its published types. + tsconfigPath: resolve(__dirname, 'tsconfig.build.json'), + entryRoot: resolve(__dirname, 'src'), + processor: 'vue', + }), + ] + : []), ], resolve: { alias: { diff --git a/packages/frontend/@n8n/frontend-module-sdk/tsconfig.json b/packages/frontend/@n8n/frontend-module-sdk/tsconfig.json index f006b9ad102..ac032859abd 100644 --- a/packages/frontend/@n8n/frontend-module-sdk/tsconfig.json +++ b/packages/frontend/@n8n/frontend-module-sdk/tsconfig.json @@ -11,9 +11,10 @@ "../design-system/src/shims-modules.d.ts" ], "paths": { - "@n8n/design-system*": ["../design-system/src*"], - "@n8n/composables*": ["../composables/src*"], - "@n8n/utils*": ["../../../@n8n/utils/src*"] + "@n8n/design-system": ["../design-system/src/index.ts"], + "@n8n/design-system/*": ["../design-system/src/*"], + "@n8n/composables/*": ["../composables/src/*"], + "@n8n/utils/*": ["../../../@n8n/utils/src/*"] } }, "include": ["src/**/*.ts", "vite.config.ts"] diff --git a/packages/frontend/@n8n/storybook/tsconfig.app.json b/packages/frontend/@n8n/storybook/tsconfig.app.json index f135d9713f8..feab0d7b81b 100644 --- a/packages/frontend/@n8n/storybook/tsconfig.app.json +++ b/packages/frontend/@n8n/storybook/tsconfig.app.json @@ -14,6 +14,7 @@ ], "paths": { "@n8n/chat*": ["../chat/src*"], + "@n8n/design-system": ["../design-system/src/index.ts"], "@n8n/design-system*": ["../design-system/src*"], "@n8n/composables*": ["../composables/src*"], "@n8n/i18n*": ["../i18n/src*"], diff --git a/packages/frontend/editor-ui/src/features/ai/chatHub/components/SuggestedPromptsEditor.vue b/packages/frontend/editor-ui/src/features/ai/chatHub/components/SuggestedPromptsEditor.vue index 9f0de52a3f7..fd7c227f15c 100644 --- a/packages/frontend/editor-ui/src/features/ai/chatHub/components/SuggestedPromptsEditor.vue +++ b/packages/frontend/editor-ui/src/features/ai/chatHub/components/SuggestedPromptsEditor.vue @@ -29,9 +29,9 @@ function updateText(index: number, text: string) { prompts.value = prompts.value.map((p, i) => (i === index ? { ...p, text } : p)); } -function updateIcon(index: number, icon: IconOrEmoji) { +function updateIcon(index: number, icon: IconOrEmoji | undefined) { prompts.value = prompts.value.map((p, i) => - i === index ? { ...p, icon: icon as AgentIconOrEmoji } : p, + i === index ? { ...p, icon: icon as AgentIconOrEmoji | undefined } : p, ); } diff --git a/packages/frontend/editor-ui/tsconfig.json b/packages/frontend/editor-ui/tsconfig.json index e65e92baea4..f5bb0c81cf2 100644 --- a/packages/frontend/editor-ui/tsconfig.json +++ b/packages/frontend/editor-ui/tsconfig.json @@ -41,7 +41,8 @@ "@n8n/frontend-constants*": ["../@n8n/frontend-constants/src*"], "@n8n/chat*": ["../@n8n/chat/src*"], "@n8n/chat-hub*": ["../../@n8n/chat-hub/src*"], - "@n8n/design-system*": ["../@n8n/design-system/src*"], + "@n8n/design-system": ["../@n8n/design-system/src/index.ts"], + "@n8n/design-system/*": ["../@n8n/design-system/src/*"], "@n8n/i18n*": ["../@n8n/i18n/src*"], "@n8n/stores*": ["../@n8n/stores/src*"], "@n8n/telemetry": ["../../@n8n/telemetry/src/index.ts"], diff --git a/packages/frontend/editor-ui/vite.config.mts b/packages/frontend/editor-ui/vite.config.mts index 5a366001c46..e107084f5ab 100644 --- a/packages/frontend/editor-ui/vite.config.mts +++ b/packages/frontend/editor-ui/vite.config.mts @@ -93,6 +93,10 @@ const plugins: UserConfig['plugins'] = [ ? [ legacy({ modernTargets: browsers, + // Every browser in `.browserslistrc` supports ESM and dynamic import, so the + // SystemJS/ES5 support is not needed. Enabling this would cause a >400% increase in build times + // for this package. + renderLegacyChunks: false, }), ] : []), @@ -109,10 +113,6 @@ const plugins: UserConfig['plugins'] = [ : html; }, }, - // For sanitize-html - // nodePolyfills({ - // include: ['fs', 'path', 'url', 'util', 'timers'], - // }), { name: 'i18n-locales-hmr', configureServer(server) { diff --git a/packages/frontend/editor-ui/vite/aliases.test.ts b/packages/frontend/editor-ui/vite/aliases.test.ts index 1850e90f25c..fa72d166782 100644 --- a/packages/frontend/editor-ui/vite/aliases.test.ts +++ b/packages/frontend/editor-ui/vite/aliases.test.ts @@ -1,5 +1,6 @@ import { existsSync, readFileSync } from 'node:fs'; import { dirname, join, relative, resolve } from 'node:path'; +import ts from 'typescript'; import type { Alias } from 'vite'; import { describe, expect, it } from 'vitest'; @@ -23,7 +24,11 @@ const readTsconfig = (file: string) => .join('\n'), ) as { compilerOptions?: { paths?: Record } }; -/** This function makes the short `"@n8n/x*"` form equal to the `"@n8n/x"` plus `"@n8n/x/*"` pair. */ +/** + * This function treats the short `"@n8n/x*"` form as the `"@n8n/x"` plus `"@n8n/x/*"` pair. That + * holds for the directory each maps to, but not for how TypeScript resolves a bare specifier — see + * `resolves the bare specifier of every entry package to src` below. + */ const pathsByPackage = (file: string) => { const paths = readTsconfig(file).compilerOptions?.paths ?? {}; const byPackage = new Map(); @@ -99,6 +104,48 @@ describe('editor-ui vite aliases', () => { } }); + /** + * The short `"@n8n/x*"` form maps a bare specifier to a directory, which TS declines. Node + * resolution then reads the `exports` of the package and returns its `dist`, while the bundle + * reads `src`. The fix is an explicit pair: `"@n8n/x": [".../src/index.ts"]` beside `"@n8n/x/*"`. + */ + it('resolves the bare specifier of every entry package to src', () => { + // Each still resolves to `dist` for the typecheck while the bundle reads `src`. Give a package + // the explicit pair and delete it here; expect new type errors, since `dist` declarations are + // looser than the source they come from. + const KNOWN_DIST_FALLBACK = new Set([ + '@n8n/api-types', + '@n8n/chat', + '@n8n/chat-hub', + '@n8n/constants', + '@n8n/i18n', + '@n8n/rest-api-client', + '@n8n/stores', + ]); + + const probe = join(editorUiDir, 'src', 'app', 'App.vue'); + const configPath = ts.findConfigFile(probe, ts.sys.fileExists); + if (!configPath) throw new Error('no tsconfig.json above src/app/App.vue'); + const { options } = ts.parseJsonConfigFileContent( + ts.readConfigFile(configPath, ts.sys.readFile).config, + ts.sys, + dirname(configPath), + undefined, + configPath, + ); + + const offenders = [...sourcePackages, ...modulePackages] + .filter(({ entry = true }) => entry) + .filter(({ name }) => !KNOWN_DIST_FALLBACK.has(name)) + .filter(({ name }) => { + const resolved = ts.resolveModuleName(name, probe, options, ts.sys).resolvedModule; + return !resolved || !resolved.resolvedFileName.includes('/src/'); + }) + .map(({ name }) => name); + + expect(offenders).toEqual([]); + }); + it('resolves @n8n/tournament from source', () => { // `n8n-workflow` brings in this package. Nothing declares it, so it is not in // `sourcePackages`. Its `dist` is CJS. The dev server gives a parse error for a named export. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3b772ceee5b..764019041f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -662,15 +662,15 @@ catalogs: typescript-eslint: specifier: 8.35.0 version: 8.35.0 + unplugin-dts: + specifier: ^1.1.0 + version: 1.1.0 uuid: specifier: 11.1.1 version: 11.1.1 vite: specifier: ^8.0.2 version: 8.0.2 - vite-plugin-dts: - specifier: ^4.5.4 - version: 4.5.4 vite-plugin-singlefile: specifier: 2.3.3 version: 2.3.3 @@ -733,6 +733,9 @@ catalogs: '@vitejs/plugin-vue': specifier: ^6.0.8 version: 6.0.8 + '@vue/language-core': + specifier: ^3.3.11 + version: 3.3.11 '@vue/test-utils': specifier: ^2.4.6 version: 2.4.6 @@ -5117,6 +5120,9 @@ importers: '@n8n/extension-sdk': specifier: workspace:* version: link:../../@n8n/extension-sdk + '@vue/language-core': + specifier: catalog:frontend + version: 3.3.11 vue: specifier: catalog:frontend version: 3.5.26(typescript@6.0.2) @@ -5148,12 +5154,12 @@ importers: typescript: specifier: 'catalog:' version: 6.0.2 + unplugin-dts: + specifier: 'catalog:' + version: 1.1.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.41))(@vue/language-core@3.3.11)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.52.4)(supports-color@8.1.1)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) vite: specifier: 'catalog:' version: 8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) - vite-plugin-dts: - specifier: 'catalog:' - version: 4.5.4(@types/node@20.19.41)(rollup@4.52.4)(supports-color@8.1.1)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(supports-color@8.1.1)(utf-8-validate@5.0.10))(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -5166,6 +5172,9 @@ importers: '@n8n/design-system': specifier: workspace:* version: link:../design-system + '@vue/language-core': + specifier: catalog:frontend + version: 3.3.11 '@vueuse/core': specifier: catalog:frontend version: 14.3.0(vue@3.5.26(typescript@6.0.2)) @@ -5239,15 +5248,15 @@ importers: typescript: specifier: 'catalog:' version: 6.0.2 + unplugin-dts: + specifier: 'catalog:' + version: 1.1.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.41))(@vue/language-core@3.3.11)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.52.4)(supports-color@8.1.1)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) unplugin-icons: specifier: ^0.19.0 version: 0.19.0(@vue/compiler-sfc@3.5.26)(supports-color@8.1.1) vite: specifier: 'catalog:' version: 8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) - vite-plugin-dts: - specifier: 'catalog:' - version: 4.5.4(@types/node@20.19.41)(rollup@4.52.4)(supports-color@8.1.1)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) vitest: specifier: 'catalog:' version: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(supports-color@8.1.1)(utf-8-validate@5.0.10))(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) @@ -5402,6 +5411,9 @@ importers: '@tiptap/vue-3': specifier: 'catalog:' version: 3.27.0(@floating-ui/dom@1.7.0)(@tiptap/core@3.27.0(@tiptap/pm@3.27.0))(@tiptap/pm@3.27.0)(vue@3.5.26(typescript@6.0.2)) + '@vue/language-core': + specifier: catalog:frontend + version: 3.3.11 '@vueuse/core': specifier: catalog:frontend version: 14.3.0(vue@3.5.26(typescript@6.0.2)) @@ -5541,15 +5553,15 @@ importers: typescript: specifier: 'catalog:' version: 6.0.2 + unplugin-dts: + specifier: 'catalog:' + version: 1.1.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.41))(@vue/language-core@3.3.11)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.52.4)(supports-color@8.1.1)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) unplugin-icons: specifier: catalog:frontend version: 23.0.1(@vue/compiler-sfc@3.5.26) vite: specifier: 'catalog:' version: 8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) - vite-plugin-dts: - specifier: 'catalog:' - version: 4.5.4(@types/node@20.19.41)(rollup@4.52.4)(supports-color@8.1.1)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)) vite-svg-loader: specifier: catalog:frontend version: 5.1.0(vue@3.5.26(typescript@6.0.2)) @@ -15099,26 +15111,12 @@ packages: resolution: {integrity: sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - '@volar/language-core@2.4.12': - resolution: {integrity: sha512-RLrFdXEaQBWfSnYGVxvR2WrO6Bub0unkdHYIdC31HzIEqATIuuhRRzYu76iGPZ6OtA4Au1SnW0ZwIqPP217YhA==} - '@volar/language-core@2.4.28': resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} - '@volar/source-map@2.4.12': - resolution: {integrity: sha512-bUFIKvn2U0AWojOaqf63ER0N/iHIBYZPpNGogfLPQ68F5Eet6FnLlyho7BS0y2HJ1jFhSif7AcuTx1TqsCzRzw==} - '@volar/source-map@2.4.28': resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} - '@volar/typescript@2.4.12': - resolution: {integrity: sha512-HJB73OTJDgPc80K30wxi3if4fSsZZAOScbj2fcicMuOPoOkcf9NNAINb33o+DzhBdF9xTKC1gnPmIRDous5S0g==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@volar/typescript@2.4.28': resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} peerDependencies: @@ -15189,14 +15187,6 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - '@vue/language-core@2.2.0': - resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@vue/language-core@2.2.8': resolution: {integrity: sha512-rrzB0wPGBvcwaSNRriVWdNAbHQWSf0NlGqgKHK5mEkXpefjUlVRP62u03KvwZpvKVjRnBIQ/Lwre+Mx9N6juUQ==} peerDependencies: @@ -15591,9 +15581,6 @@ packages: engines: {node: '>=15'} hasBin: true - alien-signals@0.4.14: - resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} - alien-signals@1.0.4: resolution: {integrity: sha512-DJqqQD3XcsaQcQ1s+iE2jDUZmmQpXwHiR6fCAim/w87luaW+vmLY8fMlrdkmRwzaFXhkxf3rqPCR59tKVv1MDw==} @@ -18460,6 +18447,9 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me @@ -24010,6 +24000,36 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin-dts@1.1.0: + resolution: {integrity: sha512-KZJ+qk+lmd9dJY/PJvDRFL9BUtVubKDiX7Ai/X6mlkCArcQNzwmupKjVqHbRA42uqO5ZfFRFc+o8/OCbQ1GonQ==} + peerDependencies: + '@microsoft/api-extractor': '>=7' + '@rspack/core': ^1 + '@vue/language-core': ^3.1.5 + esbuild: ^0.28.1 + rolldown: '*' + rollup: '>=3' + typescript: '>=4' + vite: '>=3' + webpack: ^4 || ^5 + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@rspack/core': + optional: true + '@vue/language-core': + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + unplugin-icons@0.19.0: resolution: {integrity: sha512-u5g/gIZPZEj1wUGEQxe9nzftOSqmblhusc+sL3cawIRoIt/xWpE6XYcPOfAeFTYNjSbRrX/3QiX89PFiazgU1w==} peerDependencies: @@ -24194,15 +24214,6 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite-plugin-dts@4.5.4: - resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==} - peerDependencies: - typescript: '*' - vite: '*' - peerDependenciesMeta: - vite: - optional: true - vite-plugin-node-polyfills@0.25.0: resolution: {integrity: sha512-rHZ324W3LhfGPxWwQb2N048TThB6nVvnipsqBUJEzh3R9xeK9KI3si+GMQxCuAcpPJBVf0LpDtJ+beYzB3/chg==} peerDependencies: @@ -30496,6 +30507,7 @@ snapshots: '@rushstack/node-core-library': 5.12.0(@types/node@20.19.41) transitivePeerDependencies: - '@types/node' + optional: true '@microsoft/api-extractor@7.52.1(@types/node@20.19.41)': dependencies: @@ -30514,6 +30526,7 @@ snapshots: typescript: 5.8.2 transitivePeerDependencies: - '@types/node' + optional: true '@microsoft/tsdoc-config@0.17.1': dependencies: @@ -30521,8 +30534,10 @@ snapshots: ajv: 8.20.0 jju: 1.4.0 resolve: 1.22.11 + optional: true - '@microsoft/tsdoc@0.15.1': {} + '@microsoft/tsdoc@0.15.1': + optional: true '@minimistjs/subarg@1.0.0': dependencies: @@ -32254,11 +32269,13 @@ snapshots: semver: 7.7.3 optionalDependencies: '@types/node': 20.19.41 + optional: true '@rushstack/rig-package@0.5.3': dependencies: resolve: 1.22.11 strip-json-comments: 3.1.1 + optional: true '@rushstack/terminal@0.15.1(@types/node@20.19.41)': dependencies: @@ -32266,6 +32283,7 @@ snapshots: supports-color: 8.1.1 optionalDependencies: '@types/node': 20.19.41 + optional: true '@rushstack/ts-command-line@4.23.6(@types/node@20.19.41)': dependencies: @@ -32275,6 +32293,7 @@ snapshots: string-argv: 0.3.2 transitivePeerDependencies: - '@types/node' + optional: true '@sapphire/async-queue@1.5.5': {} @@ -33705,7 +33724,8 @@ snapshots: '@types/app-root-path@1.2.8': {} - '@types/argparse@1.0.38': {} + '@types/argparse@1.0.38': + optional: true '@types/aria-query@5.0.4': {} @@ -34827,26 +34847,12 @@ snapshots: '@vladfrangu/async_event_emitter@2.4.7': {} - '@volar/language-core@2.4.12': - dependencies: - '@volar/source-map': 2.4.12 - '@volar/language-core@2.4.28': dependencies: '@volar/source-map': 2.4.28 - '@volar/source-map@2.4.12': {} - '@volar/source-map@2.4.28': {} - '@volar/typescript@2.4.12(typescript@6.0.2)': - dependencies: - '@volar/language-core': 2.4.12 - path-browserify: 1.0.1 - vscode-uri: 3.0.8 - optionalDependencies: - typescript: 6.0.2 - '@volar/typescript@2.4.28(@typescript/typescript6@6.0.2)': dependencies: '@volar/language-core': 2.4.28 @@ -34983,19 +34989,6 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/language-core@2.2.0(typescript@6.0.2)': - dependencies: - '@volar/language-core': 2.4.12 - '@vue/compiler-dom': 3.5.40 - '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.40 - alien-signals: 0.4.14 - minimatch: 9.0.9 - muggle-string: 0.4.1 - path-browserify: 1.0.1 - optionalDependencies: - typescript: 6.0.2 - '@vue/language-core@2.2.8(@typescript/typescript6@6.0.2)': dependencies: '@volar/language-core': 2.4.28 @@ -35412,8 +35405,6 @@ snapshots: transitivePeerDependencies: - encoding - alien-signals@0.4.14: {} - alien-signals@1.0.4: {} alien-signals@3.2.1: {} @@ -39047,6 +39038,8 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regexp@0.4.1: {} + glob@10.5.0: dependencies: foreground-child: 3.3.1 @@ -39609,7 +39602,8 @@ snapshots: cjs-module-lexer: 2.2.0 module-details-from-path: 1.0.4 - import-lazy@4.0.0: {} + import-lazy@4.0.0: + optional: true import-meta-resolve@4.2.0: {} @@ -39982,7 +39976,8 @@ snapshots: jiti@2.6.1: {} - jju@1.4.0: {} + jju@1.4.0: + optional: true jmespath@0.16.0: {} @@ -45803,7 +45798,8 @@ snapshots: typescript@4.9.5: {} - typescript@5.8.2: {} + typescript@5.8.2: + optional: true typescript@5.9.3: {} @@ -45932,6 +45928,28 @@ snapshots: unpipe@1.0.0: {} + unplugin-dts@1.1.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.41))(@vue/language-core@3.3.11)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.52.4)(supports-color@8.1.1)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)): + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.52.4) + '@volar/typescript': 2.4.28(typescript@6.0.2) + compare-versions: 6.1.1 + debug: 4.4.3(supports-color@8.1.1) + glob-to-regexp: 0.4.1 + kolorist: 1.8.0 + local-pkg: 1.1.2 + magic-string: 0.30.21 + typescript: 6.0.2 + unplugin: 2.3.11 + optionalDependencies: + '@microsoft/api-extractor': 7.52.1(@types/node@20.19.41) + '@vue/language-core': 3.3.11 + esbuild: 0.28.1 + rolldown: 1.1.5 + rollup: 4.52.4 + vite: 8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) + transitivePeerDependencies: + - supports-color + unplugin-icons@0.19.0(@vue/compiler-sfc@3.5.26)(supports-color@8.1.1): dependencies: '@antfu/install-pkg': 0.3.3 @@ -46134,25 +46152,6 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-plugin-dts@4.5.4(@types/node@20.19.41)(rollup@4.52.4)(supports-color@8.1.1)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)): - dependencies: - '@microsoft/api-extractor': 7.52.1(@types/node@20.19.41) - '@rollup/pluginutils': 5.3.0(rollup@4.52.4) - '@volar/typescript': 2.4.12(typescript@6.0.2) - '@vue/language-core': 2.2.0(typescript@6.0.2) - compare-versions: 6.1.1 - debug: 4.4.3(supports-color@8.1.1) - kolorist: 1.8.0 - local-pkg: 1.1.2 - magic-string: 0.30.21 - typescript: 6.0.2 - optionalDependencies: - vite: 8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3) - transitivePeerDependencies: - - '@types/node' - - rollup - - supports-color - vite-plugin-node-polyfills@0.25.0(rollup@4.52.4)(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)): dependencies: '@rollup/plugin-inject': 5.0.5(rollup@4.52.4) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e0439b9ce3a..76111b3a239 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -265,7 +265,7 @@ catalog: typescript-eslint: 8.35.0 uuid: 11.1.1 vite: ^8.0.2 - vite-plugin-dts: ^4.5.4 + unplugin-dts: ^1.1.0 vite-plugin-singlefile: 2.3.3 vitest: ^4.1.9 vitest-mock-extended: ^3.1.0 @@ -294,6 +294,7 @@ catalogs: '@testing-library/user-event': ^14.6.1 '@testing-library/vue': ^8.1.0 '@vitejs/plugin-vue': ^6.0.8 + '@vue/language-core': ^3.3.11 '@vue/test-utils': ^2.4.6 '@vue/tsconfig': ^0.7.0 '@vueuse/core': ^14.3.0 diff --git a/turbo.json b/turbo.json index a26f9c06790..005a50df9af 100644 --- a/turbo.json +++ b/turbo.json @@ -26,6 +26,29 @@ "outputs": ["dist/**"], "env": ["RELEASE"] }, + // Both emit declarations only under `RELEASE`, so `RELEASE` has to be part of the cache + // key. Without it a cached non-release `dist`, which has no `.d.ts`, would be restored + // onto a release build and ship a package with no types. + "@n8n/design-system#build": { + "dependsOn": ["^build"], + "outputs": ["dist/**"], + "env": ["RELEASE"] + }, + "@n8n/design-system#build:unchecked": { + "dependsOn": ["^build:unchecked"], + "outputs": ["dist/**"], + "env": ["RELEASE"] + }, + "@n8n/chat#build": { + "dependsOn": ["^build"], + "outputs": ["dist/**"], + "env": ["RELEASE"] + }, + "@n8n/chat#build:unchecked": { + "dependsOn": ["^build:unchecked"], + "outputs": ["dist/**"], + "env": ["RELEASE"] + }, "typecheck": { "dependsOn": ["^build"] },