diff --git a/.gitignore b/.gitignore index 8de9b0e66..b7e68531f 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ stats.html # Nitro .nitro +.output /migrations.json /.env @@ -85,4 +86,4 @@ gradle.properties .cursor .claude gradle.properties -*.tsbuildinfo \ No newline at end of file +*.tsbuildinfo diff --git a/apps/analog-app/package.json b/apps/analog-app/package.json index a1702bd87..a6b1397b6 100644 --- a/apps/analog-app/package.json +++ b/apps/analog-app/package.json @@ -13,6 +13,7 @@ "@analogjs/platform": "workspace:*", "@analogjs/storybook-angular": "workspace:*", "@analogjs/vite-plugin-angular": "workspace:*", - "@analogjs/vitest-angular": "workspace:*" + "@analogjs/vitest-angular": "workspace:*", + "nitro": "catalog:" } } diff --git a/apps/analog-app/project.json b/apps/analog-app/project.json index 5217ef58e..9350c3b01 100644 --- a/apps/analog-app/project.json +++ b/apps/analog-app/project.json @@ -7,19 +7,14 @@ "tags": [], "targets": { "build": { - "executor": "@nx/vite:build", + "executor": "@analogjs/platform:vite", "dependsOn": [ "platform:build", "router:build", "my-package:build", "top-bar:build" ], - "outputs": [ - "{options.outputPath}", - "{workspaceRoot}/dist/apps/analog-app/.nitro", - "{workspaceRoot}/dist/apps/analog-app/ssr", - "{workspaceRoot}/dist/apps/analog-app/analog" - ], + "outputs": ["{workspaceRoot}/dist/apps/analog-app/analog"], "options": { "configFile": "apps/analog-app/vite.config.ts", "outputPath": "dist/apps/analog-app/client" diff --git a/apps/analog-app/vite.config.ts b/apps/analog-app/vite.config.ts index feb168cab..3afc4f02a 100644 --- a/apps/analog-app/vite.config.ts +++ b/apps/analog-app/vite.config.ts @@ -1,6 +1,8 @@ /// -import analog from '@analogjs/platform'; +import analog, { discoverLibraryRoutes, pageGlobs } from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; import { resolve } from 'node:path'; import { defineConfig, PluginOption } from 'vite'; import { getWorkspaceDependencyExcludes } from '../../tools/vite/get-workspace-dependency-excludes.js'; @@ -37,12 +39,15 @@ export default defineConfig(async ({ mode, command }) => { }, ]; + const discoveredLibs = discoverLibraryRoutes(resolve(__dirname, '../..')); + const explicitLibPages = useBuiltWorkspaceLibs + ? [] + : ['/libs/my-package/src/**/*.ts', '/libs/top-bar/src/**/*.ts']; + return { root: __dirname, publicDir: 'src/public', build: { - outDir: '../../dist/apps/analog-app/client', - emptyOutDir: true, reportCompressedSize: true, target: ['es2020'], }, @@ -58,11 +63,9 @@ export default defineConfig(async ({ mode, command }) => { content: { highlighter: 'prism', }, - include: useBuiltWorkspaceLibs - ? [] - : ['/libs/my-package/src/**/*.ts', '/libs/top-bar/src/**/*.ts'], - discoverRoutes: true, - fileReplacements, + additionalPagesDirs: discoveredLibs.additionalPagesDirs, + additionalContentDirs: discoveredLibs.additionalContentDirs, + additionalAPIDirs: discoveredLibs.additionalAPIDirs, prerender: { routes: [ '/', @@ -79,23 +82,25 @@ export default defineConfig(async ({ mode, command }) => { host: base, }, }, - inlineStylesExtension: 'scss', - fastCompile: true, experimental: { typedRouter: true, }, - nitro: { - routeRules: { - '/client': { - ssr: false, - }, - '/cart/**': { - ssr: false, - }, - '/404.html': { - ssr: false, - }, - }, + }), + angular({ + include: [ + ...explicitLibPages, + ...pageGlobs(discoveredLibs.additionalPagesDirs), + ], + additionalContentDirs: discoveredLibs.additionalContentDirs, + inlineStylesExtension: 'scss', + fileReplacements, + fastCompile: true, + }), + nitro({ + routeRules: { + '/client': { ssr: false }, + '/cart/**': { ssr: false }, + '/404.html': { ssr: false }, }, }), { diff --git a/apps/blog-app/package.json b/apps/blog-app/package.json index d1f5633cc..48cc4eca8 100644 --- a/apps/blog-app/package.json +++ b/apps/blog-app/package.json @@ -7,6 +7,8 @@ "@analogjs/router": "workspace:*" }, "devDependencies": { - "@analogjs/platform": "workspace:*" + "@analogjs/platform": "workspace:*", + "@analogjs/vite-plugin-angular": "workspace:*", + "nitro": "catalog:" } } diff --git a/apps/blog-app/project.json b/apps/blog-app/project.json index 5d78732c4..6ecbe0a79 100644 --- a/apps/blog-app/project.json +++ b/apps/blog-app/project.json @@ -7,14 +7,9 @@ "tags": [], "targets": { "build": { - "executor": "@nx/vite:build", + "executor": "@analogjs/platform:vite", "dependsOn": ["platform:build", "router:build", "content:build"], - "outputs": [ - "{options.outputPath}", - "{workspaceRoot}/dist/apps/blog-app/.nitro", - "{workspaceRoot}/dist/apps/blog-app/ssr", - "{workspaceRoot}/dist/apps/blog-app/analog" - ], + "outputs": ["{workspaceRoot}/dist/apps/blog-app/analog"], "options": { "configFile": "apps/blog-app/vite.config.ts", "outputPath": "dist/apps/blog-app/client" diff --git a/apps/blog-app/src/server/routes/rss.xml.ts b/apps/blog-app/src/server/routes/api/rss.xml.ts similarity index 100% rename from apps/blog-app/src/server/routes/rss.xml.ts rename to apps/blog-app/src/server/routes/api/rss.xml.ts diff --git a/apps/blog-app/src/server/routes/v1/[...slug].ts b/apps/blog-app/src/server/routes/api/v1/[...slug].ts similarity index 100% rename from apps/blog-app/src/server/routes/v1/[...slug].ts rename to apps/blog-app/src/server/routes/api/v1/[...slug].ts diff --git a/apps/blog-app/vite.config.ts b/apps/blog-app/vite.config.ts index 6f14b2adb..ebc284956 100644 --- a/apps/blog-app/vite.config.ts +++ b/apps/blog-app/vite.config.ts @@ -1,6 +1,8 @@ /// import analog, { type PrerenderContentFile } from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; import { defineConfig } from 'vite'; import { getWorkspaceDependencyExcludes } from '../../tools/vite/get-workspace-dependency-excludes.js'; @@ -26,14 +28,11 @@ export default defineConfig(() => { exclude: getWorkspaceDependencyExcludes(__dirname), }, build: { - outDir: '../../dist/apps/blog-app/client', - emptyOutDir: true, reportCompressedSize: true, target: ['es2020'], }, plugins: [ analog({ - liveReload: true, content: { highlighter: 'shiki', shikiOptions: { @@ -84,11 +83,14 @@ export default defineConfig(() => { host: 'https://analog-blog.netlify.app', }, }, - nitro: { - prerender: { - autoSubfolderIndex: false, - failOnError: true, - }, + }), + angular({ + liveReload: true, + }), + nitro({ + prerender: { + autoSubfolderIndex: false, + failOnError: true, }, }), ], diff --git a/apps/docs-app/docs/guides/migrating-v2-to-v3.md b/apps/docs-app/docs/guides/migrating-v2-to-v3.md index 88b0c92e6..1d3146d6c 100644 --- a/apps/docs-app/docs/guides/migrating-v2-to-v3.md +++ b/apps/docs-app/docs/guides/migrating-v2-to-v3.md @@ -37,6 +37,172 @@ Analog v3 no longer supports Angular v16. Upgrade the workspace to Angular v17 o Analog SFC support was removed and `.agx` files are no longer supported. Replace any remaining SFC usage with standard Angular components, markdown content files, or route/page files that use the current Analog conventions. +### `analog()`, `angular()`, and `nitro()` are now separate plugins + +Analog v3 splits the Vite plugin chain into three explicit calls. `analog()` no longer internally invokes `@analogjs/vite-plugin-angular` or `nitro/vite` — you call them yourself. Pass each plugin only the options it owns. + +`@analogjs/platform` v3 owns its own Nitro orchestration via `nitro/vite` directly and no longer composes `@analogjs/vite-plugin-nitro` internally. `@analogjs/vite-plugin-nitro` continues to ship as a standalone package for projects that want to wire it themselves; users coming from a v2 `analog({ nitro: {...} })` shape should migrate to the separated shape below (analog + angular + nitro from `nitro/vite`). + +Before: + +```ts +import { defineConfig } from 'vite'; +import analog from '@analogjs/platform'; + +export default defineConfig(() => ({ + plugins: [ + analog({ + ssr: true, + apiPrefix: 'api', + vite: { + inlineStylesExtension: 'scss', + fastCompile: true, + }, + fileReplacements: [ + { replace: 'src/environment.ts', with: 'src/environment.prod.ts' }, + ], + nitro: { + routeRules: { '/admin/**': { ssr: false } }, + }, + prerender: { + routes: ['/', '/about'], + }, + }), + ], +})); +``` + +After: + +```ts +import { resolve } from 'node:path'; +import { defineConfig } from 'vite'; +import analog from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; + +export default defineConfig(() => ({ + server: { + // Vite 8's strict fs only allows reads under config.root; nitro/vite's + // env-runner reaches pnpm content-hash paths at the workspace root + // when loading its own dev runtime. + fs: { allow: [resolve(__dirname, '../..')] }, + }, + plugins: [ + analog({ + ssr: true, + apiPrefix: 'api', + prerender: { + routes: ['/', '/about'], + }, + }), + angular({ + workspaceRoot: resolve(__dirname, '../..'), + inlineStylesExtension: 'scss', + fastCompile: true, + fileReplacements: [ + { replace: 'src/environment.ts', with: 'src/environment.prod.ts' }, + ], + }), + nitro({ + routeRules: { '/admin/**': { ssr: false } }, + }), + ], +})); +``` + +Add `@analogjs/vite-plugin-angular` and `nitro` to the app's `devDependencies`: + +```json +{ + "devDependencies": { + "@analogjs/platform": "...", + "@analogjs/vite-plugin-angular": "...", + "nitro": "..." + } +} +``` + +#### Options that moved off `analog()` + +These options used to live on `analog()`. Pass them to `angular()` or `nitro()` directly: + +| v2 location | v3 location | +| ------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | +| `analog({ vite: {...} })` | spread directly into `angular({...})` | +| `analog({ jit })`, `disableTypeChecking`, `liveReload`, `inlineStylesExtension`, `fileReplacements`, `fastCompile`, `fastCompileMode`, `include` | `angular({...})` | +| `analog({ tailwindCss: {...} })` | `angular({ tailwindCss: {...} })` | +| `analog({ experimental: { useAngularCompilationAPI: true } })` | `angular({ experimental: { useAngularCompilationAPI: true } })` | +| `analog({ experimental: { stylePipeline: { angularPlugins: [...] } } })` | `angular({ stylePipeline: { plugins: [...] } })` | +| `analog({ nitro: {...} })` | `nitro({...})` (first arg) | +| `analog({ vite: false })` | drop `angular()` from the plugins array | + +`analog()` retains `ssr`, `apiPrefix`, `entryServer`, `content`, `prerender`, `i18n`, `discoverRoutes`, `additionalPagesDirs`/`additionalContentDirs`/`additionalAPIDirs`, `debug`, and `experimental.typedRouter`/`experimental.stylePipeline`. + +#### Workspace library globs + +If your v2 config used `discoverRoutes: true` to compile workspace library pages, the same helper is now exported from `@analogjs/platform`. Call it once and feed the result to both `analog()` and `angular()`: + +```ts +import analog, { discoverLibraryRoutes, pageGlobs } from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; + +const libs = discoverLibraryRoutes(resolve(__dirname, '../..')); + +plugins: [ + analog({ + additionalPagesDirs: libs.additionalPagesDirs, + additionalContentDirs: libs.additionalContentDirs, + additionalAPIDirs: libs.additionalAPIDirs, + }), + angular({ + include: pageGlobs(libs.additionalPagesDirs), + additionalContentDirs: libs.additionalContentDirs, + }), + nitro(), +]; +``` + +#### Nx build target + +If your app uses `@nx/vite:build`, switch it to `nx:run-commands` invoking `vite build`. `@nx/vite:build` iterates `builder.environments` but doesn't call `builder.buildApp()` — and `nitro/vite`'s prerender + final Nitro env build orchestration lives in the `buildApp` hook. Without the CLI's `buildApp` invocation, no prerender runs and the SSR/Nitro env outputs are skipped. + +Before (`apps//project.json`): + +```json +{ + "build": { + "executor": "@nx/vite:build", + "outputs": [ + "{options.outputPath}", + "{workspaceRoot}/dist/apps//.nitro", + "{workspaceRoot}/dist/apps//ssr", + "{workspaceRoot}/dist/apps//analog" + ], + "options": { + "configFile": "apps//vite.config.ts", + "outputPath": "dist/apps//client" + } + } +} +``` + +After: + +```json +{ + "build": { + "executor": "nx:run-commands", + "outputs": ["{workspaceRoot}/apps//.output"], + "options": { + "command": "vite build -c apps//vite.config.ts" + } + } +} +``` + +Also drop the top-level `build.outDir` override in `vite.config.ts`. Under `nitro/vite`, the client environment's output is relocated to `/.output/public` by Nitro; the legacy `dist/apps//client` override no longer matches the active output path. + ### Content rendering now requires an explicit highlighter If your app renders markdown content, configure the content highlighter through the `analog()` plugin in `vite.config.ts`. New blog templates already do this, but older full-stack apps often do not. @@ -152,6 +318,11 @@ Keep automated migration tooling focused on the breaking changes above: - require Angular v17 or newer before applying v3 changes - replace deep or internal imports with public package entrypoints +- split `analog()` into `analog() + angular() + nitro()`, moving each option to the plugin that now owns it (see [plugin separation](#analog-angular-and-nitro-are-now-separate-plugins)) +- @analogjs/platform no longer composes @analogjs/vite-plugin-nitro internally; direct importers can either migrate to `@analogjs/platform` + `nitro/vite` (recommended) or continue using @analogjs/vite-plugin-nitro standalone +- add `@analogjs/vite-plugin-angular` to app `devDependencies` (the separated shape imports it directly). `nitro` is picked up as a transitive of `@analogjs/platform` for npm/yarn; pnpm users must add it to `devDependencies` explicitly +- replace `@nx/vite:build` with `nx:run-commands` invoking `vite build -c apps//vite.config.ts`; drop the legacy `build.outDir` override and update `outputs` to `apps//.output` +- add `server.fs.allow` pointing at the workspace root in `vite.config.ts` so Vite 8's strict fs allows nitro/vite's env runner to load its own dev runtime through pnpm content-hash paths - add explicit `analog({ content: { highlighter: 'shiki' } })` config when the app renders markdown content - add `withContentRoutes()` from `@analogjs/router/content` when the app uses markdown page routes - flag `analog({ i18n: ... })`, `provideI18n()`, `injectSwitchLocale()`, `loadTranslationsRuntime()`, or content locale helpers as removed v3 APIs diff --git a/apps/opt-catchall-app/package.json b/apps/opt-catchall-app/package.json index ca967937d..957553fdd 100644 --- a/apps/opt-catchall-app/package.json +++ b/apps/opt-catchall-app/package.json @@ -8,6 +8,7 @@ }, "devDependencies": { "@analogjs/platform": "workspace:*", - "@analogjs/vite-plugin-angular": "workspace:*" + "@analogjs/vite-plugin-angular": "workspace:*", + "nitro": "catalog:" } } diff --git a/apps/opt-catchall-app/project.json b/apps/opt-catchall-app/project.json index 638e54f21..1eba6c4c2 100644 --- a/apps/opt-catchall-app/project.json +++ b/apps/opt-catchall-app/project.json @@ -7,14 +7,9 @@ "tags": [], "targets": { "build": { - "executor": "@nx/vite:build", + "executor": "@analogjs/platform:vite", "dependsOn": ["platform:build", "router:build", "content:build"], - "outputs": [ - "{options.outputPath}", - "{workspaceRoot}/dist/apps/opt-catchall-app/.nitro", - "{workspaceRoot}/dist/apps/opt-catchall-app/ssr", - "{workspaceRoot}/dist/apps/opt-catchall-app/analog" - ], + "outputs": ["{workspaceRoot}/dist/apps/opt-catchall-app/analog"], "options": { "configFile": "apps/opt-catchall-app/vite.config.ts", "outputPath": "dist/apps/opt-catchall-app/client" diff --git a/apps/opt-catchall-app/vite.config.ts b/apps/opt-catchall-app/vite.config.ts index 4d1108cfb..95751ee34 100644 --- a/apps/opt-catchall-app/vite.config.ts +++ b/apps/opt-catchall-app/vite.config.ts @@ -1,6 +1,8 @@ /// import analog from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; import { defineConfig } from 'vite'; import { getWorkspaceDependencyExcludes } from '../../tools/vite/get-workspace-dependency-excludes.js'; @@ -15,21 +17,22 @@ export default defineConfig(() => { exclude: getWorkspaceDependencyExcludes(__dirname), }, build: { - outDir: '../../dist/apps/opt-catchall-app/client', - emptyOutDir: true, reportCompressedSize: true, target: ['es2020'], }, plugins: [ analog({ + content: { + highlighter: 'shiki', + }, + }), + angular({ liveReload: true, experimental: { useAngularCompilationAPI: true, }, - content: { - highlighter: 'shiki', - }, }), + nitro(), ], }; }); diff --git a/apps/tailwind-debug-app/package.json b/apps/tailwind-debug-app/package.json index 7d8a9aef0..097fe45c5 100644 --- a/apps/tailwind-debug-app/package.json +++ b/apps/tailwind-debug-app/package.json @@ -8,6 +8,7 @@ "devDependencies": { "@analogjs/platform": "workspace:*", "@analogjs/vite-plugin-angular": "workspace:*", - "@analogjs/vitest-angular": "workspace:*" + "@analogjs/vitest-angular": "workspace:*", + "nitro": "catalog:" } } diff --git a/apps/tailwind-debug-app/project.json b/apps/tailwind-debug-app/project.json index 0eeee883d..2a7a3a6f5 100644 --- a/apps/tailwind-debug-app/project.json +++ b/apps/tailwind-debug-app/project.json @@ -7,14 +7,9 @@ "tags": [], "targets": { "build": { - "executor": "@nx/vite:build", + "executor": "@analogjs/platform:vite", "dependsOn": ["platform:build", "router:build"], - "outputs": [ - "{options.outputPath}", - "{workspaceRoot}/dist/apps/tailwind-debug-app/.nitro", - "{workspaceRoot}/dist/apps/tailwind-debug-app/ssr", - "{workspaceRoot}/dist/apps/tailwind-debug-app/analog" - ], + "outputs": ["{workspaceRoot}/dist/apps/tailwind-debug-app/analog"], "options": { "configFile": "apps/tailwind-debug-app/vite.config.ts", "outputPath": "dist/apps/tailwind-debug-app/client" @@ -52,6 +47,7 @@ }, "test": { "executor": "@nx/vitest:test", + "dependsOn": ["platform:build", "router:build", "vitest-angular:build"], "outputs": ["{projectRoot}/coverage"] }, "typecheck": { diff --git a/apps/tailwind-debug-app/vite.config.ts b/apps/tailwind-debug-app/vite.config.ts index dd25855ec..717ded16d 100644 --- a/apps/tailwind-debug-app/vite.config.ts +++ b/apps/tailwind-debug-app/vite.config.ts @@ -1,9 +1,12 @@ /// import analog from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; import tailwindcss from '@tailwindcss/vite'; import fs from 'node:fs'; import path from 'node:path'; +import { resolve } from 'node:path'; import { createLogger, defineConfig, type Plugin } from 'vite'; import { getWorkspaceDependencyExcludes } from '../../tools/vite/get-workspace-dependency-excludes.js'; @@ -88,7 +91,6 @@ export default defineConfig(({ mode }) => ({ exclude: getWorkspaceDependencyExcludes(__dirname), }, build: { - outDir: '../../dist/apps/tailwind-debug-app/client', reportCompressedSize: true, target: ['es2020'], }, @@ -106,31 +108,36 @@ export default defineConfig(({ mode }) => ({ plugins: [ analog({ apiPrefix: 'api', + prerender: { + routes: [], + }, + ssr: false, + }), + angular({ experimental: { // Required to reproduce #2293: @apply inside :host with Tailwind // prefix configuration requires the Angular Compilation API path // for style externalization. useAngularCompilationAPI: true, }, - prerender: { - routes: [], - }, - ssr: false, - nitro: { - routeRules: { - '/probe': { - ssr: false, - }, - }, - experimental: { - websocket: true, - }, - }, tailwindCss: { prefixes: ['tdbg:'], rootStylesheet: 'apps/tailwind-debug-app/src/styles.css', }, }), + nitro({ + routeRules: { + '/probe': { + ssr: false, + }, + }, + // Vitest spins up a headless Vite (server.httpServer === null), and + // nitro/vite's configureViteDevServer unconditionally calls + // `server.httpServer.on('upgrade', ...)` when websocket is enabled, + // crashing the test runner. Drop the flag under Vitest; the websocket + // probe is only exercised by the dev server and e2e suite. + ...(process.env['VITEST'] ? {} : { experimental: { websocket: true } }), + }), tailwindcss(), hmrWiretapPlugin(), ], @@ -150,9 +157,6 @@ export default defineConfig(({ mode }) => ({ }, server: { port: 43040, - fs: { - allow: ['.'], - }, hmr: { clientPort: 4201, path: 'vite-hmr', diff --git a/apps/tanstack-query-app/package.json b/apps/tanstack-query-app/package.json index 8b6998990..92ed2a369 100644 --- a/apps/tanstack-query-app/package.json +++ b/apps/tanstack-query-app/package.json @@ -7,9 +7,11 @@ }, "devDependencies": { "@analogjs/platform": "workspace:*", + "@analogjs/vite-plugin-angular": "workspace:*", "@analogjs/vitest-angular": "workspace:*", "@tailwindcss/vite": "catalog:", "daisyui": "^5.5.19", + "nitro": "catalog:", "tailwindcss": "catalog:" } } diff --git a/apps/tanstack-query-app/project.json b/apps/tanstack-query-app/project.json index 21bde6f84..22710642e 100644 --- a/apps/tanstack-query-app/project.json +++ b/apps/tanstack-query-app/project.json @@ -7,14 +7,9 @@ "tags": [], "targets": { "build": { - "executor": "@nx/vite:build", + "executor": "@analogjs/platform:vite", "dependsOn": ["platform:build", "router:build"], - "outputs": [ - "{options.outputPath}", - "{workspaceRoot}/dist/apps/tanstack-query-app/.nitro", - "{workspaceRoot}/dist/apps/tanstack-query-app/ssr", - "{workspaceRoot}/dist/apps/tanstack-query-app/analog" - ], + "outputs": ["{workspaceRoot}/dist/apps/tanstack-query-app/analog"], "options": { "configFile": "apps/tanstack-query-app/vite.config.ts", "outputPath": "dist/apps/tanstack-query-app/client" diff --git a/apps/tanstack-query-app/vite.config.ts b/apps/tanstack-query-app/vite.config.ts index 6c8bebd24..907bd9a53 100644 --- a/apps/tanstack-query-app/vite.config.ts +++ b/apps/tanstack-query-app/vite.config.ts @@ -1,6 +1,8 @@ /// import analog from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; import tailwindcss from '@tailwindcss/vite'; import { defineConfig } from 'vite'; import { getWorkspaceDependencyExcludes } from '../../tools/vite/get-workspace-dependency-excludes.js'; @@ -11,7 +13,6 @@ export default defineConfig(({ mode }) => { root: __dirname, publicDir: 'src/public', build: { - outDir: '../../dist/apps/tanstack-query-app/client', reportCompressedSize: true, target: ['es2020'], }, @@ -26,6 +27,8 @@ export default defineConfig(({ mode }) => { analog({ apiPrefix: 'api', }), + angular(), + nitro(), ], test: { reporters: ['default'], diff --git a/package.json b/package.json index 8e17bf68b..dbcf65f7e 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "lint": "pnpm run /^lint:/", "ng": "nx", "preinstall": "npx only-allow pnpm", - "prepare": "git config core.hookspath .githooks || true && node tools/scripts/build-release.mts", + "prepare": "node tools/scripts/build-release.mts", "prettier:check": "prettier --check .", "release:pack": "node tools/scripts/release-artifacts.mts pack", "release:smoke": "node tools/scripts/smoke-release-consumers.mts", diff --git a/packages/create-analog/index.js b/packages/create-analog/index.js index d84e456ee..483b5457b 100755 --- a/packages/create-analog/index.js +++ b/packages/create-analog/index.js @@ -506,8 +506,13 @@ function addPnpmDependencies(pkg, template) { if (H3_TEMPLATES.includes(template)) { pkg.dependencies ??= {}; pkg.dependencies.h3 = '^1.13.0'; - pkg.dependencies.nitro = '3.0.260415-beta'; pkg.dependencies.ofetch = '2.0.0-alpha.3'; + // nitro is only imported via `nitro/vite` in vite.config.ts (a build-time + // tool). npm/yarn auto-hoist it as a transitive of @analogjs/platform; + // pnpm's strict node_modules layout doesn't, so add it explicitly for + // pnpm users only. + pkg.devDependencies ??= {}; + pkg.devDependencies.nitro = '3.0.260522-beta'; } } diff --git a/packages/create-analog/package.json b/packages/create-analog/package.json index 6ad68788a..f2117c839 100644 --- a/packages/create-analog/package.json +++ b/packages/create-analog/package.json @@ -41,7 +41,9 @@ "prompts": "catalog:" }, "devDependencies": { - "@analogjs/platform": "workspace:*" + "@analogjs/platform": "workspace:*", + "@analogjs/vite-plugin-angular": "workspace:*", + "nitro": "catalog:" }, "publishConfig": { "access": "public", diff --git a/packages/create-analog/template-blog/vite.config.ts b/packages/create-analog/template-blog/vite.config.ts index d6427eab1..7564e5a84 100644 --- a/packages/create-analog/template-blog/vite.config.ts +++ b/packages/create-analog/template-blog/vite.config.ts @@ -2,6 +2,8 @@ import { defineConfig } from 'vite'; __TAILWIND_IMPORT__import analog from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; // https://vitejs.dev/config/ export default defineConfig(({ mode }) => ({ @@ -20,6 +22,8 @@ __TAILWIND_PLUGIN__ analog({ routes: ['/blog', '/blog/2022-12-27-my-first-post'], }, }), + angular(), + nitro(), ], test: { globals: true, diff --git a/packages/create-analog/template-latest/vite.config.ts b/packages/create-analog/template-latest/vite.config.ts index 8737bf35c..6da8e9cf5 100644 --- a/packages/create-analog/template-latest/vite.config.ts +++ b/packages/create-analog/template-latest/vite.config.ts @@ -2,6 +2,8 @@ import { defineConfig } from 'vite'; __TAILWIND_IMPORT__import analog from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; // https://vitejs.dev/config/ export default defineConfig(({ mode }) => ({ @@ -13,6 +15,8 @@ export default defineConfig(({ mode }) => ({ }, plugins: [ analog(), + angular(), + nitro(), __TAILWIND_PLUGIN__ ], test: { globals: true, diff --git a/packages/create-analog/template-minimal/vite.config.ts b/packages/create-analog/template-minimal/vite.config.ts index bc4c98d2e..c340a496e 100644 --- a/packages/create-analog/template-minimal/vite.config.ts +++ b/packages/create-analog/template-minimal/vite.config.ts @@ -2,6 +2,8 @@ import { defineConfig } from 'vite'; __TAILWIND_IMPORT__import analog from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; // https://vitejs.dev/config/ export default defineConfig(({ mode }) => ({ @@ -14,10 +16,11 @@ export default defineConfig(({ mode }) => ({ plugins: [ __TAILWIND_PLUGIN__ analog({ ssr: false, - static: true, prerender: { routes: [], }, }), + angular(), + nitro({ static: true }), ], })); diff --git a/packages/nx-plugin/builders.json b/packages/nx-plugin/builders.json index 3eaec9e31..d851afe65 100644 --- a/packages/nx-plugin/builders.json +++ b/packages/nx-plugin/builders.json @@ -1,7 +1,15 @@ { "builders": { - "vite-dev-server": "@analogjs/vite-plugin-angular:vite-dev-server", - "vite": "@analogjs/vite-plugin-angular:vite", + "vite-dev-server": { + "implementation": "./src/builders/vite-dev-server/dev-server.js", + "schema": "./src/builders/vite-dev-server/schema.json", + "description": "Vite dev server." + }, + "vite": { + "implementation": "./src/builders/vite/vite-build.js", + "schema": "./src/builders/vite/schema.json", + "description": "Build with Vite." + }, "vitest": "@analogjs/vitest-angular:test" } } diff --git a/packages/nx-plugin/executors.json b/packages/nx-plugin/executors.json index 06935b94a..c0166c990 100644 --- a/packages/nx-plugin/executors.json +++ b/packages/nx-plugin/executors.json @@ -1,7 +1,15 @@ { "builders": { - "vite-dev-server": "@analogjs/vite-plugin-angular:vite-dev-server", - "vite": "@analogjs/vite-plugin-angular:vite", + "vite-dev-server": { + "implementation": "./src/builders/vite-dev-server/dev-server.js", + "schema": "./src/builders/vite-dev-server/schema.json", + "description": "Vite dev server." + }, + "vite": { + "implementation": "./src/builders/vite/vite-build.js", + "schema": "./src/builders/vite/schema.json", + "description": "Build with Vite." + }, "vitest": "@analogjs/vitest-angular:test" }, "executors": { @@ -10,11 +18,6 @@ "schema": "./src/executors/vite-dev-server/schema.json", "description": "Vite dev server." }, - "vite": { - "implementation": "./src/executors/vite/vite.impl", - "schema": "./src/executors/vite/schema.json", - "description": "Build with Vite." - }, "vitest": { "implementation": "./src/executors/vitest/vitest.impl", "schema": "./src/executors/vitest/schema.json", diff --git a/packages/nx-plugin/src/builders/vite-dev-server/dev-server.ts b/packages/nx-plugin/src/builders/vite-dev-server/dev-server.ts new file mode 100644 index 000000000..ffdbe8fb3 --- /dev/null +++ b/packages/nx-plugin/src/builders/vite-dev-server/dev-server.ts @@ -0,0 +1,8 @@ +/** + * Thin shim that re-exports the Angular Devkit Architect dev-server builder + * shipped by `@analogjs/vite-plugin-angular`. See `../vite/vite-build.ts` for + * the rationale; mirrors `@analogjs/storybook-angular`'s pattern. + */ +import devServerBuilder from '@analogjs/vite-plugin-angular/builders/vite-dev-server'; + +export default devServerBuilder; diff --git a/packages/nx-plugin/src/builders/vite-dev-server/schema.json b/packages/nx-plugin/src/builders/vite-dev-server/schema.json new file mode 100644 index 000000000..82e1ff61d --- /dev/null +++ b/packages/nx-plugin/src/builders/vite-dev-server/schema.json @@ -0,0 +1,27 @@ +{ + "version": 2, + "outputCapture": "direct-nodejs", + "title": "Vite Dev Server", + "description": "Starts a dev server using Vite.", + "type": "object", + "properties": { + "buildTarget": { + "type": "string", + "description": "Target which builds the application. Only used to retrieve the configuration as the dev-server does not build the code.", + "x-priority": "important" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "description": "Port to listen on.", + "x-priority": "important" + }, + "hmr": { + "description": "Enable hot module replacement. For more options, use the 'hmr' option in the Vite configuration file.", + "type": "boolean" + } + }, + "definitions": {}, + "required": ["buildTarget"] +} diff --git a/packages/nx-plugin/src/builders/vite/schema.json b/packages/nx-plugin/src/builders/vite/schema.json new file mode 100644 index 000000000..c96d6dfbd --- /dev/null +++ b/packages/nx-plugin/src/builders/vite/schema.json @@ -0,0 +1,39 @@ +{ + "version": 2, + "outputCapture": "direct-nodejs", + "title": "Vite Prod Builder", + "cli": "nx", + "description": "Builds a Vite.js application for production.", + "type": "object", + "properties": { + "outputPath": { + "type": "string", + "description": "The output path of the generated files.", + "x-completion-type": "directory", + "x-priority": "important" + }, + "configFile": { + "type": "string", + "description": "The name of the Vite.js configuration file.", + "x-completion-type": "file", + "x-completion-glob": "vite.config.@(js|ts)" + }, + "sourcemap": { + "description": "Output sourcemaps. Use 'hidden' for use with error reporting tools without generating sourcemap comment.", + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ] + }, + "mode": { + "type": "string", + "description": "Mode to run the build in." + } + }, + "definitions": {}, + "required": ["outputPath"] +} diff --git a/packages/nx-plugin/src/builders/vite/vite-build.ts b/packages/nx-plugin/src/builders/vite/vite-build.ts new file mode 100644 index 000000000..473b1a0f5 --- /dev/null +++ b/packages/nx-plugin/src/builders/vite/vite-build.ts @@ -0,0 +1,12 @@ +/** + * Thin shim that re-exports the Angular Devkit Architect build builder + * shipped by `@analogjs/vite-plugin-angular`. Architect resolves the + * implementation from the local `builders.json` entry without traversing a + * cross-package string redirect, so the user-facing `@analogjs/platform:vite` + * identifier stays stable while the real implementation continues to live in + * `@analogjs/vite-plugin-angular`. Mirrors `@analogjs/storybook-angular`'s + * pattern for surfacing `@storybook/angular`'s builders. + */ +import viteBuilder from '@analogjs/vite-plugin-angular/builders/vite'; + +export default viteBuilder; diff --git a/packages/nx-plugin/src/executors/vite/compat.ts b/packages/nx-plugin/src/executors/vite/compat.ts deleted file mode 100644 index 218bebba5..000000000 --- a/packages/nx-plugin/src/executors/vite/compat.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { convertNxExecutor } from '@nx/devkit'; - -import viteBuildExecutor from './vite.impl'; - -const compat: ReturnType = - convertNxExecutor(viteBuildExecutor); -export default compat; diff --git a/packages/nx-plugin/src/executors/vite/schema.d.ts b/packages/nx-plugin/src/executors/vite/schema.d.ts deleted file mode 100644 index bd161aeb9..000000000 --- a/packages/nx-plugin/src/executors/vite/schema.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { FileReplacement } from '@nx/vite/plugins/rollup-replace-files.plugin'; -export type { ViteBuildExecutorOptions } from '@nx/vite/executors'; diff --git a/packages/nx-plugin/src/executors/vite/schema.json b/packages/nx-plugin/src/executors/vite/schema.json deleted file mode 100644 index 961943531..000000000 --- a/packages/nx-plugin/src/executors/vite/schema.json +++ /dev/null @@ -1,147 +0,0 @@ -{ - "version": 2, - "outputCapture": "direct-nodejs", - "title": "Vite Prod Builder", - "cli": "nx", - "description": "Builds a Vite.js application for production.", - "type": "object", - "presets": [ - { - "name": "Default minimum setup", - "keys": [] - } - ], - "properties": { - "outputPath": { - "type": "string", - "description": "The output path of the generated files.", - "x-completion-type": "directory", - "x-priority": "important" - }, - "buildLibsFromSource": { - "type": "boolean", - "description": "Read buildable libraries from source instead of building them separately.", - "default": true - }, - "skipTypeCheck": { - "type": "boolean", - "description": "Skip type-checking via TypeScript. Skipping type-checking speeds up the build but type errors are not caught.", - "default": false - }, - "base": { - "type": "string", - "description": "Base public path when served in development or production.", - "alias": "baseHref" - }, - "configFile": { - "type": "string", - "description": "The name of the Vite.js configuration file.", - "x-completion-type": "file", - "x-completion-glob": "vite.config.@(js|ts)" - }, - "emptyOutDir": { - "description": "When set to false, outputPath will not be emptied during the build process.", - "type": "boolean", - "default": true - }, - "sourcemap": { - "description": "Output sourcemaps. Use 'hidden' for use with error reporting tools without generating sourcemap comment.", - "oneOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - }, - "target": { - "description": "Browser compatibility target for the final bundle. For more info: https://vitejs.dev/config/build-options.html#build-target", - "type": "string" - }, - "minify": { - "description": "Output sourcemaps. Use 'hidden' for use with error reporting tools without generating sourcemap comment.", - "oneOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - }, - "manifest": { - "description": "Output sourcemaps. Use 'hidden' for use with error reporting tools without generating sourcemap comment.", - "oneOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - }, - "ssrManifest": { - "description": "When set to true, the build will also generate an SSR manifest for determining style links and asset preload directives in production. When the value is a string, it will be used as the manifest file name.", - "oneOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - }, - "ssr": { - "description": "Produce SSR-oriented build. The value can be a string to directly specify the SSR entry, or true, which requires specifying the SSR entry via rollupOptions.input.", - "oneOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - }, - "logLevel": { - "type": "string", - "description": "Adjust console output verbosity.", - "enum": ["info", "warn", "error", "silent"] - }, - "mode": { - "type": "string", - "description": "Mode to run the build in." - }, - "force": { - "description": "Force the optimizer to ignore the cache and re-bundle", - "type": "boolean" - }, - "cssCodeSplit": { - "description": "Enable/disable CSS code splitting. When enabled, CSS imported in async chunks will be inlined into the async chunk itself and inserted when the chunk is loaded.", - "type": "boolean" - }, - "watch": { - "description": "Enable re-building when files change.", - "oneOf": [ - { - "type": "boolean" - }, - { - "type": "object" - } - ], - "default": false - }, - "generatePackageJson": { - "description": "Generate a package.json for the build output.", - "type": "boolean" - }, - "includeDevDependenciesInPackageJson": { - "description": "Include devDependencies in the generated package.json.", - "type": "boolean" - } - }, - "definitions": {}, - "required": [], - "examplesFile": "../../../docs/build-examples.md" -} diff --git a/packages/nx-plugin/src/executors/vite/vite.impl.ts b/packages/nx-plugin/src/executors/vite/vite.impl.ts deleted file mode 100644 index ffaf2b4c6..000000000 --- a/packages/nx-plugin/src/executors/vite/vite.impl.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { viteBuildExecutor } from '@nx/vite/executors'; - -export default viteBuildExecutor; diff --git a/packages/nx-plugin/vite.config.lib.ts b/packages/nx-plugin/vite.config.lib.ts index e3fa4a3e4..f5b34127a 100644 --- a/packages/nx-plugin/vite.config.lib.ts +++ b/packages/nx-plugin/vite.config.lib.ts @@ -122,15 +122,16 @@ export default defineConfig({ pkgDir, 'src/generators/setup-vitest/compat.ts', ), - // Executors - 'src/executors/vite/vite.impl': resolve( + // Architect builders (thin shims re-exporting from vpa) + 'src/builders/vite/vite-build': resolve( pkgDir, - 'src/executors/vite/vite.impl.ts', + 'src/builders/vite/vite-build.ts', ), - 'src/executors/vite/compat': resolve( + 'src/builders/vite-dev-server/dev-server': resolve( pkgDir, - 'src/executors/vite/compat.ts', + 'src/builders/vite-dev-server/dev-server.ts', ), + // Executors 'src/executors/vite-dev-server/vite-dev-server.impl': resolve( pkgDir, 'src/executors/vite-dev-server/vite-dev-server.impl.ts', @@ -153,6 +154,7 @@ export default defineConfig({ outDir: resolve(pkgDir, '../platform/dist/src/lib/nx-plugin'), rolldownOptions: { external: [ + /^@analogjs\//, /^@angular-devkit\//, /^@angular\//, /^@nx\//, diff --git a/packages/platform/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.spec.ts b/packages/platform/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.spec.ts new file mode 100644 index 000000000..cde90921d --- /dev/null +++ b/packages/platform/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.spec.ts @@ -0,0 +1,424 @@ +import { describe, expect, it, beforeEach, vi } from 'vitest'; +import { UnitTestTree } from '@angular-devkit/schematics/testing'; +import { Tree, SchematicContext } from '@angular-devkit/schematics'; + +import migrateToSeparatedPlugins from './migrate-to-separated-plugins'; + +const LEGACY_CONFIG = ` +import analog from '@analogjs/platform'; +import { defineConfig } from 'vite'; + +export default defineConfig(() => ({ + plugins: [ + analog({ apiPrefix: 'api' }), + ], +})); +`; + +const SEPARATED_CONFIG = ` +import analog from '@analogjs/platform'; +import angular from '@analogjs/vite-plugin-angular'; +import { nitro } from 'nitro/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig(() => ({ + plugins: [analog(), angular(), nitro()], +})); +`; + +function createContext() { + const infoLogs: string[] = []; + return { + infoLogs, + context: { + logger: { + info: (msg: string) => infoLogs.push(msg), + }, + addTask: vi.fn(), + } as unknown as SchematicContext, + }; +} + +describe('migrate-to-separated-plugins', () => { + let tree: UnitTestTree; + + beforeEach(() => { + tree = new UnitTestTree(Tree.empty()); + }); + + // Stand-in for whatever `@analogjs/platform` version a consuming workspace + // happens to have pinned. The schematic mirrors this onto + // `@analogjs/vite-plugin-angular`; tests assert the mirroring behavior, + // not a specific release line. + const PLATFORM_VERSION = '^3.0.0'; + + it('logs the migration notice and adds deps when a legacy vite.config.ts is detected', () => { + tree.create('/vite.config.ts', LEGACY_CONFIG); + tree.create( + '/package.json', + JSON.stringify({ + devDependencies: { '@analogjs/platform': PLATFORM_VERSION }, + }), + ); + + const { context, infoLogs } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const pkg = JSON.parse(tree.readContent('/package.json')); + expect(pkg.devDependencies['@analogjs/vite-plugin-angular']).toBe( + PLATFORM_VERSION, + ); + // The schematic does not pin `nitro` — npm/yarn pick it up as a transitive + // of @analogjs/platform; pnpm users add it themselves following the + // migration guide. + expect(pkg.devDependencies['nitro']).toBeUndefined(); + expect(infoLogs.join('\n')).toContain('/vite.config.ts'); + expect(infoLogs.join('\n')).toContain('migrating-v2-to-v3'); + }); + + it('is a no-op when the vite.config is already on the separated shape', () => { + tree.create('/vite.config.ts', SEPARATED_CONFIG); + tree.create( + '/package.json', + JSON.stringify({ + devDependencies: { '@analogjs/platform': PLATFORM_VERSION }, + }), + ); + + const { context, infoLogs } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const pkg = JSON.parse(tree.readContent('/package.json')); + expect( + pkg.devDependencies['@analogjs/vite-plugin-angular'], + ).toBeUndefined(); + expect(infoLogs).toEqual([]); + }); + + it('does not duplicate deps that are already declared', () => { + const PREEXISTING_VPA = '^2.5.0'; + tree.create('/vite.config.ts', LEGACY_CONFIG); + tree.create( + '/package.json', + JSON.stringify({ + devDependencies: { + '@analogjs/platform': PLATFORM_VERSION, + '@analogjs/vite-plugin-angular': PREEXISTING_VPA, + }, + }), + ); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const pkg = JSON.parse(tree.readContent('/package.json')); + expect(pkg.devDependencies['@analogjs/vite-plugin-angular']).toBe( + PREEXISTING_VPA, + ); + }); + + it('reads version from `dependencies` if `devDependencies` is missing platform', () => { + const FROM_DEPS = '~3.0.0'; + tree.create('/vite.config.ts', LEGACY_CONFIG); + tree.create( + '/package.json', + JSON.stringify({ + dependencies: { '@analogjs/platform': FROM_DEPS }, + }), + ); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const pkg = JSON.parse(tree.readContent('/package.json')); + expect(pkg.devDependencies['@analogjs/vite-plugin-angular']).toBe( + FROM_DEPS, + ); + }); + + it('skips files inside node_modules', () => { + tree.create('/node_modules/some-pkg/vite.config.ts', LEGACY_CONFIG); + tree.create( + '/package.json', + JSON.stringify({ + devDependencies: { '@analogjs/platform': PLATFORM_VERSION }, + }), + ); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const pkg = JSON.parse(tree.readContent('/package.json')); + expect( + pkg.devDependencies['@analogjs/vite-plugin-angular'], + ).toBeUndefined(); + }); + + it('only matches vite.config files (vite.config.ts, .mts, .js, .mjs)', () => { + // Looks like a legacy analog() call but isn't a vite config. + tree.create('/src/example.ts', LEGACY_CONFIG); + tree.create( + '/package.json', + JSON.stringify({ + devDependencies: { '@analogjs/platform': PLATFORM_VERSION }, + }), + ); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const pkg = JSON.parse(tree.readContent('/package.json')); + expect( + pkg.devDependencies['@analogjs/vite-plugin-angular'], + ).toBeUndefined(); + }); + + it('detects a vite.config.mts file', () => { + tree.create('/apps/example/vite.config.mts', LEGACY_CONFIG); + tree.create( + '/package.json', + JSON.stringify({ + devDependencies: { '@analogjs/platform': PLATFORM_VERSION }, + }), + ); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const pkg = JSON.parse(tree.readContent('/package.json')); + expect(pkg.devDependencies['@analogjs/vite-plugin-angular']).toBe( + PLATFORM_VERSION, + ); + }); + + it('does not treat a config that already imports the new plugins as legacy', () => { + // analog() still appears but both new imports are present — already migrated. + tree.create('/vite.config.ts', SEPARATED_CONFIG); + tree.create( + '/package.json', + JSON.stringify({ + devDependencies: { + '@analogjs/platform': PLATFORM_VERSION, + '@analogjs/vite-plugin-angular': PLATFORM_VERSION, + }, + }), + ); + + const { context, infoLogs } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + expect(infoLogs).toEqual([]); + }); + + describe('option transform', () => { + const PKG = JSON.stringify({ + devDependencies: { '@analogjs/platform': PLATFORM_VERSION }, + }); + + it('lifts `vite: {...}` into a companion angular() call', () => { + tree.create( + '/vite.config.ts', + [ + `import analog from '@analogjs/platform';`, + `import { defineConfig } from 'vite';`, + ``, + `export default defineConfig(() => ({`, + ` plugins: [`, + ` analog({`, + ` apiPrefix: 'api',`, + ` vite: { fastCompile: true },`, + ` }),`, + ` ],`, + `}));`, + ].join('\n'), + ); + tree.create('/package.json', PKG); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const result = tree.readContent('/vite.config.ts'); + expect(result).toContain( + `import angular from '@analogjs/vite-plugin-angular';`, + ); + expect(result).toContain(`import { nitro } from 'nitro/vite';`); + expect(result).toContain(`angular({ fastCompile: true })`); + expect(result).toContain(`nitro()`); + expect(result).not.toContain(`vite: { fastCompile: true }`); + expect(result).toContain(`apiPrefix: 'api'`); + }); + + it('lifts `nitro: {...}` into a companion nitro() call', () => { + tree.create( + '/vite.config.ts', + [ + `import analog from '@analogjs/platform';`, + ``, + `export default {`, + ` plugins: [`, + ` analog({`, + ` apiPrefix: 'api',`, + ` nitro: { preset: 'node-server' },`, + ` }),`, + ` ],`, + `};`, + ].join('\n'), + ); + tree.create('/package.json', PKG); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const result = tree.readContent('/vite.config.ts'); + expect(result).toContain(`nitro({ preset: 'node-server' })`); + expect(result).toContain(`angular()`); + expect(result).not.toContain(`nitro: { preset: 'node-server' }`); + expect(result).toContain(`apiPrefix: 'api'`); + }); + + it('lifts both `vite` and `nitro` and keeps the remaining analog options', () => { + tree.create( + '/vite.config.ts', + [ + `import analog from '@analogjs/platform';`, + ``, + `export default {`, + ` plugins: [`, + ` analog({`, + ` apiPrefix: 'api',`, + ` ssr: true,`, + ` vite: { fastCompile: true, liveReload: true },`, + ` nitro: { routeRules: { '/admin/**': { ssr: false } } },`, + ` prerender: { routes: ['/'] },`, + ` }),`, + ` ],`, + `};`, + ].join('\n'), + ); + tree.create('/package.json', PKG); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const result = tree.readContent('/vite.config.ts'); + expect(result).toContain( + `angular({ fastCompile: true, liveReload: true })`, + ); + expect(result).toContain( + `nitro({ routeRules: { '/admin/**': { ssr: false } } })`, + ); + // Remaining analog options stay on analog(). + expect(result).toMatch(/analog\(\{[\s\S]*apiPrefix: 'api'/); + expect(result).toMatch(/analog\(\{[\s\S]*ssr: true/); + expect(result).toMatch( + /analog\(\{[\s\S]*prerender: \{ routes: \['\/'\] \}/, + ); + // The `vite` and `nitro` keys are gone from the analog literal. + expect(result).not.toMatch(/vite:\s*\{/); + // The `nitro: {` form is gone; only `nitro({` remains. + expect(result).not.toMatch(/nitro:\s*\{/); + }); + + it('rewrites analog() with no argument into analog(), angular(), nitro()', () => { + tree.create( + '/vite.config.ts', + [ + `import analog from '@analogjs/platform';`, + ``, + `export default {`, + ` plugins: [analog()],`, + `};`, + ].join('\n'), + ); + tree.create('/package.json', PKG); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const result = tree.readContent('/vite.config.ts'); + expect(result).toContain( + `import angular from '@analogjs/vite-plugin-angular';`, + ); + expect(result).toContain(`import { nitro } from 'nitro/vite';`); + expect(result).toMatch(/analog\(\),\s+angular\(\),\s+nitro\(\)/); + }); + + it('rewrites analog({ apiPrefix }) (no vite/nitro keys) and adds empty companion plugins', () => { + tree.create( + '/vite.config.ts', + [ + `import analog from '@analogjs/platform';`, + ``, + `export default {`, + ` plugins: [`, + ` analog({ apiPrefix: 'api' }),`, + ` ],`, + `};`, + ].join('\n'), + ); + tree.create('/package.json', PKG); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const result = tree.readContent('/vite.config.ts'); + expect(result).toContain(`analog({`); + expect(result).toContain(`apiPrefix: 'api'`); + expect(result).toContain(`angular()`); + expect(result).toContain(`nitro()`); + }); + + it('does not rewrite when the analog() call argument is not an object literal', () => { + tree.create( + '/vite.config.ts', + [ + `import analog from '@analogjs/platform';`, + ``, + `const opts = { apiPrefix: 'api' };`, + `export default { plugins: [analog(opts)] };`, + ].join('\n'), + ); + tree.create('/package.json', PKG); + + const { context, infoLogs } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const result = tree.readContent('/vite.config.ts'); + // Source untouched because we can't safely split a variable reference. + expect(result).toContain(`plugins: [analog(opts)]`); + // Doc link is logged. + expect(infoLogs.join('\n')).toContain(MIGRATION_DOC_PHRASE); + }); + + it('does not duplicate the angular/nitro imports when they are already present', () => { + tree.create( + '/vite.config.ts', + [ + `import analog from '@analogjs/platform';`, + `import angular from '@analogjs/vite-plugin-angular';`, + ``, + `export default {`, + ` plugins: [`, + ` analog({ apiPrefix: 'api', vite: { fastCompile: true } }),`, + ` angular({ liveReload: true }),`, + ` ],`, + `};`, + ].join('\n'), + ); + tree.create('/package.json', PKG); + + const { context } = createContext(); + migrateToSeparatedPlugins()(tree, context); + + const result = tree.readContent('/vite.config.ts'); + const angularImports = result.match( + /import angular from '@analogjs\/vite-plugin-angular';/g, + ); + expect(angularImports?.length).toBe(1); + // The nitro import is still added since it wasn't there. + expect(result).toContain(`import { nitro } from 'nitro/vite';`); + }); + }); +}); + +const MIGRATION_DOC_PHRASE = 'migrating-v2-to-v3'; diff --git a/packages/platform/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.ts b/packages/platform/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.ts new file mode 100644 index 000000000..2bc3a996c --- /dev/null +++ b/packages/platform/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.ts @@ -0,0 +1,328 @@ +import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; +import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; +import * as ts from 'typescript'; + +const ANALOG_PLATFORM_IMPORT = `from '@analogjs/platform'`; +const ANGULAR_PLUGIN_IMPORT = `from '@analogjs/vite-plugin-angular'`; +const NITRO_VITE_IMPORT = `from 'nitro/vite'`; +const ANGULAR_PLUGIN_PKG = '@analogjs/vite-plugin-angular'; +const MIGRATION_DOC_URL = + 'https://analogjs.org/docs/guides/migrating-v2-to-v3#analog-angular-and-nitro-are-now-separate-plugins'; + +const VITE_CONFIG_EXTENSIONS = ['.ts', '.mts', '.js', '.mjs']; + +function isViteConfig(filePath: string): boolean { + const file = filePath.slice(filePath.lastIndexOf('/') + 1); + if (!file.startsWith('vite.config.')) { + return false; + } + return VITE_CONFIG_EXTENSIONS.some((ext) => file.endsWith(ext)); +} + +function usesLegacyPluginShape(source: string): boolean { + if (!source.includes(ANALOG_PLATFORM_IMPORT)) { + return false; + } + if ( + source.includes(ANGULAR_PLUGIN_IMPORT) && + source.includes(NITRO_VITE_IMPORT) + ) { + return false; + } + return /\banalog\s*\(/.test(source); +} + +function readPackageJson( + tree: Tree, +): { raw: string; pkg: Record } | null { + const content = tree.read('/package.json'); + if (!content) return null; + const raw = content.toString('utf-8'); + try { + return { raw, pkg: JSON.parse(raw) }; + } catch { + return null; + } +} + +function getDepVersion( + pkg: Record, + name: string, +): string | undefined { + const dev = + (pkg['devDependencies'] as Record | undefined) ?? {}; + const reg = (pkg['dependencies'] as Record | undefined) ?? {}; + return dev[name] ?? reg[name]; +} + +function addDependencies(tree: Tree, context: SchematicContext): boolean { + const info = readPackageJson(tree); + if (!info) return false; + + const { pkg, raw } = info; + const devDeps = { + ...((pkg['devDependencies'] as Record | undefined) ?? {}), + }; + let changed = false; + + if (!getDepVersion(pkg, ANGULAR_PLUGIN_PKG)) { + // Match the @analogjs/platform pin so the angular plugin stays aligned + // with the rest of the Analog packages already in this workspace. + const platformVersion = getDepVersion(pkg, '@analogjs/platform') ?? '*'; + devDeps[ANGULAR_PLUGIN_PKG] = platformVersion; + changed = true; + context.logger.info( + `Added '${ANGULAR_PLUGIN_PKG}': '${platformVersion}' to devDependencies.`, + ); + } + + if (!changed) return false; + + pkg['devDependencies'] = devDeps; + const trailingNewline = raw.endsWith('\n') ? '\n' : ''; + tree.overwrite( + '/package.json', + JSON.stringify(pkg, null, 2) + trailingNewline, + ); + context.addTask(new NodePackageInstallTask()); + return true; +} + +interface TransformResult { + source: string; + movedVite: boolean; + movedNitro: boolean; +} + +interface Edit { + start: number; + end: number; + text: string; +} + +function applyEdits(source: string, edits: Edit[]): string { + // Apply right-to-left so earlier offsets stay valid. + const sorted = [...edits].sort((a, b) => b.start - a.start); + let result = source; + for (const edit of sorted) { + result = result.slice(0, edit.start) + edit.text + result.slice(edit.end); + } + return result; +} + +function getLineIndent(source: string, pos: number): string { + let lineStart = pos; + while (lineStart > 0 && source[lineStart - 1] !== '\n') { + lineStart--; + } + let indent = ''; + for (let i = lineStart; i < source.length; i++) { + const ch = source[i]; + if (ch === ' ' || ch === '\t') indent += ch; + else break; + } + return indent; +} + +/** + * Tries to lift `vite: {...}` and `nitro: {...}` properties off the + * single `analog(...)` call into companion `angular(...)` / `nitro(...)` + * calls. Returns the rewritten source on success, or null if the file + * doesn't match the supported pattern (we then fall back to logging + * instructions rather than risking a corrupted file). + * + * Supported pattern: exactly one `analog(...)` call whose argument is + * an object literal. Properties named `vite` and `nitro` are recognized; + * everything else stays on `analog`. + */ +function tryTransformViteConfig( + filePath: string, + source: string, +): TransformResult | null { + let sourceFile: ts.SourceFile; + try { + sourceFile = ts.createSourceFile( + filePath, + source, + ts.ScriptTarget.Latest, + true, + ts.ScriptKind.TS, + ); + } catch { + return null; + } + + let analogImportEnd = -1; + let angularImported = false; + let nitroImported = false; + const analogCalls: ts.CallExpression[] = []; + + function visit(node: ts.Node): void { + if (ts.isImportDeclaration(node)) { + const ml = node.moduleSpecifier; + if (ts.isStringLiteral(ml)) { + if (ml.text === '@analogjs/platform') { + analogImportEnd = node.end; + } else if (ml.text === '@analogjs/vite-plugin-angular') { + angularImported = true; + } else if (ml.text === 'nitro/vite') { + nitroImported = true; + } + } + } else if (ts.isCallExpression(node)) { + if ( + ts.isIdentifier(node.expression) && + node.expression.text === 'analog' + ) { + analogCalls.push(node); + } + } + ts.forEachChild(node, visit); + } + visit(sourceFile); + + if (analogImportEnd === -1) return null; + if (analogCalls.length !== 1) return null; + + const analogCall = analogCalls[0]; + const callStart = analogCall.getStart(sourceFile); + const callEnd = analogCall.getEnd(); + + let viteValueText: string | null = null; + let nitroValueText: string | null = null; + let remainingPropsText: string | null = null; + + const arg = analogCall.arguments[0]; + if (arg && ts.isObjectLiteralExpression(arg)) { + const remaining: ts.ObjectLiteralElementLike[] = []; + for (const prop of arg.properties) { + if ( + ts.isPropertyAssignment(prop) && + ts.isIdentifier(prop.name) && + (prop.name.text === 'vite' || prop.name.text === 'nitro') + ) { + const value = prop.initializer; + const text = source.slice(value.getStart(sourceFile), value.getEnd()); + if (prop.name.text === 'vite') viteValueText = text; + else nitroValueText = text; + } else { + remaining.push(prop); + } + } + + if (remaining.length > 0) { + // Reconstruct the analog object literal from the remaining props, + // preserving their original source text (comments, spacing). + const propTexts = remaining.map((p) => + source.slice(p.getStart(sourceFile), p.getEnd()), + ); + const objStart = arg.getStart(sourceFile); + const indent = getLineIndent(source, objStart); + const propIndent = indent + ' '; + remainingPropsText = `{\n${propTexts.map((t) => `${propIndent}${t}`).join(',\n')},\n${indent}}`; + } + } else if (arg !== undefined) { + // analog(otherExpression) — can't statically split a variable or call + // expression. Fall back to logging instructions. + return null; + } + // analog() with no argument falls through to the rewrite below; we just + // emit `analog(), angular(), nitro()` to scaffold the new plugin chain. + + const indent = getLineIndent(source, callStart); + const newAnalogCall = remainingPropsText + ? `analog(${remainingPropsText})` + : `analog()`; + const parts: string[] = [newAnalogCall]; + if (viteValueText !== null) parts.push(`angular(${viteValueText})`); + else parts.push('angular()'); + if (nitroValueText !== null) parts.push(`nitro(${nitroValueText})`); + else parts.push('nitro()'); + const replacement = parts.join(`,\n${indent}`); + + const edits: Edit[] = [{ start: callStart, end: callEnd, text: replacement }]; + + const importsToAdd: string[] = []; + if (!angularImported) { + importsToAdd.push(`import angular from '@analogjs/vite-plugin-angular';`); + } + if (!nitroImported) { + importsToAdd.push(`import { nitro } from 'nitro/vite';`); + } + if (importsToAdd.length > 0) { + edits.push({ + start: analogImportEnd, + end: analogImportEnd, + text: `\n${importsToAdd.join('\n')}`, + }); + } + + const rewritten = applyEdits(source, edits); + + return { + source: rewritten, + movedVite: viteValueText !== null, + movedNitro: nitroValueText !== null, + }; +} + +export default function migrateToSeparatedPlugins(): Rule { + return (tree: Tree, context: SchematicContext) => { + const filesUsingLegacyShape: string[] = []; + const rewrittenFiles: string[] = []; + const unhandledFiles: string[] = []; + + tree.visit((filePath) => { + if (filePath.includes('/node_modules/')) return; + if (!isViteConfig(filePath)) return; + + const content = tree.read(filePath); + if (!content) return; + + const source = content.toString('utf-8'); + if (!usesLegacyPluginShape(source)) return; + + filesUsingLegacyShape.push(filePath); + + const transformed = tryTransformViteConfig(filePath, source); + if (transformed) { + tree.overwrite(filePath, transformed.source); + rewrittenFiles.push(filePath); + } else { + unhandledFiles.push(filePath); + } + }); + + if (filesUsingLegacyShape.length === 0) { + return tree; + } + + if (rewrittenFiles.length > 0) { + context.logger.info( + `Rewrote ${rewrittenFiles.length} vite.config file(s) to the separated \`analog() + angular() + nitro()\` shape:`, + ); + for (const file of rewrittenFiles) { + context.logger.info(` - ${file}`); + } + context.logger.info( + `Review the result — only \`vite\` and \`nitro\` were moved automatically. Other angular-passthrough options (\`liveReload\`, \`fastCompile\`, \`fileReplacements\`, \`tailwindCss\`, etc.) still need to be relocated by hand.\nSee ${MIGRATION_DOC_URL}`, + ); + } + + if (unhandledFiles.length > 0) { + context.logger.info( + `Could not safely rewrite ${unhandledFiles.length} vite.config file(s); migrate them by hand:`, + ); + for (const file of unhandledFiles) { + context.logger.info(` - ${file}`); + } + context.logger.info( + `Split \`analog()\` into \`analog() + angular() + nitro()\` and move each option to its owning plugin.\nSee ${MIGRATION_DOC_URL}`, + ); + } + + addDependencies(tree, context); + + return tree; + }; +} diff --git a/packages/platform/migrations/migration.json b/packages/platform/migrations/migration.json index 00b46c7ac..7bbffd6cb 100644 --- a/packages/platform/migrations/migration.json +++ b/packages/platform/migrations/migration.json @@ -1,4 +1,10 @@ { "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json", - "schematics": {} + "schematics": { + "migrate-to-separated-plugins": { + "version": "3.0.0-alpha.56", + "description": "Migrate Analog vite.config from a single analog() call to the separated analog() + angular() + nitro() plugin shape", + "factory": "./migrate-to-separated-plugins/migrate-to-separated-plugins" + } + } } diff --git a/packages/platform/package.json b/packages/platform/package.json index b7e436cba..68cc2db56 100644 --- a/packages/platform/package.json +++ b/packages/platform/package.json @@ -46,10 +46,13 @@ "tinyglobby": "catalog:", "nitro": "catalog:", "@analogjs/vite-plugin-angular": "workspace:*", - "@analogjs/vite-plugin-nitro": "workspace:*", + "@babel/core": "catalog:", + "ofetch": "catalog:", + "oxc-parser": "catalog:", "rolldown": "catalog:", "obug": "catalog:", - "vitefu": "catalog:" + "vitefu": "catalog:", + "xmlbuilder2": "catalog:" }, "peerDependencies": { "@nx/angular": "catalog:peerCompat", diff --git a/packages/platform/project.json b/packages/platform/project.json index edbd2a0c0..6b8640dae 100644 --- a/packages/platform/project.json +++ b/packages/platform/project.json @@ -4,12 +4,12 @@ "sourceRoot": "packages/platform/src", "projectType": "library", "tags": ["type:release"], - "implicitDependencies": ["vite-plugin-angular", "vite-plugin-nitro"], + "implicitDependencies": ["vite-plugin-angular"], "targets": { "build-self": { "executor": "nx:run-commands", "cache": false, - "dependsOn": ["vite-plugin-angular:build", "vite-plugin-nitro:build"], + "dependsOn": ["vite-plugin-angular:build"], "outputs": ["{projectRoot}/dist"], "options": { "commands": [ @@ -34,7 +34,7 @@ }, "test": { "executor": "@nx/vitest:test", - "dependsOn": ["vite-plugin-angular:build", "vite-plugin-nitro:build"] + "dependsOn": ["vite-plugin-angular:build"] }, "version": { "executor": "@jscutlery/semver:version", diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index 5bcfebc28..b535d40a8 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -14,6 +14,11 @@ export type { SitemapRouteSource, SitemapTransform, } from './lib/options.js'; +export { + discoverLibraryRoutes, + pageGlobs, +} from './lib/discover-library-routes.js'; +export type { DiscoveredLibraryRoutes } from './lib/discover-library-routes.js'; export { routeGenerationPlugin } from './lib/route-generation-plugin.js'; export { tailwindPreprocessor } from './lib/tailwind-preprocessor.js'; export type { diff --git a/packages/platform/src/lib/deps-plugin.spec.ts b/packages/platform/src/lib/deps-plugin.spec.ts index e9b088343..07f92beea 100644 --- a/packages/platform/src/lib/deps-plugin.spec.ts +++ b/packages/platform/src/lib/deps-plugin.spec.ts @@ -11,35 +11,10 @@ describe('depsPlugin oxc config', () => { expect(result).not.toHaveProperty('esbuild'); }); - it('excludes ts/js files by default', () => { + it('excludes ts/js files so vite-plugin-angular owns Angular file compilation', () => { const plugins = depsPlugin(); const result = (plugins[0].config as any)(); expect(result.oxc).toEqual({ exclude: ['**/*.ts', '**/*.js'] }); }); - - it('uses empty oxc config when vite option is false', () => { - const plugins = depsPlugin({ vite: false } as any); - const result = (plugins[0].config as any)(); - - expect(result.oxc).toEqual({}); - }); - - it('uses empty config when useAngularCompilationAPI is enabled', () => { - const plugins = depsPlugin({ - vite: { experimental: { useAngularCompilationAPI: true } }, - } as any); - const result = (plugins[0].config as any)(); - - expect(result.oxc).toEqual({}); - }); - - it('uses empty config when top-level experimental useAngularCompilationAPI is enabled', () => { - const plugins = depsPlugin({ - experimental: { useAngularCompilationAPI: true }, - } as any); - const result = (plugins[0].config as any)(); - - expect(result.oxc).toEqual({}); - }); }); diff --git a/packages/platform/src/lib/deps-plugin.ts b/packages/platform/src/lib/deps-plugin.ts index 03db5e5e8..1c279b223 100644 --- a/packages/platform/src/lib/deps-plugin.ts +++ b/packages/platform/src/lib/deps-plugin.ts @@ -9,24 +9,19 @@ import { getJsTransformConfigKey } from './utils/rolldown.js'; export function depsPlugin(options?: Options): Plugin[] { const workspaceRoot = options?.workspaceRoot ?? process.env['NX_WORKSPACE_ROOT'] ?? process.cwd(); - const viteOptions = options?.vite === false ? undefined : options?.vite; return [ { name: 'analogjs-deps-plugin', config() { - const useAngularCompilationAPI = - options?.experimental?.useAngularCompilationAPI ?? - viteOptions?.experimental?.useAngularCompilationAPI; - - const transformConfig = - options?.vite === false || useAngularCompilationAPI - ? {} - : { exclude: ['**/*.ts', '**/*.js'] }; + // Skip Vite's built-in ts/js transform so `@analogjs/vite-plugin-angular` + // (when the user includes it) owns Angular file compilation. Users who + // run an alternative compiler or compile through Angular's own + // compilation API can override this in their own Vite config. + const transformConfig = { exclude: ['**/*.ts', '**/*.js'] }; debugPlatform('deps transform config', { - useAngularCompilationAPI: !!useAngularCompilationAPI, jsTransformKey: getJsTransformConfigKey(), - transformExcluded: 'exclude' in transformConfig, + transformExcluded: true, }); return { diff --git a/packages/platform/src/lib/discover-library-routes.spec.ts b/packages/platform/src/lib/discover-library-routes.spec.ts index 680608b7a..61488fa46 100644 --- a/packages/platform/src/lib/discover-library-routes.spec.ts +++ b/packages/platform/src/lib/discover-library-routes.spec.ts @@ -5,7 +5,7 @@ vi.mock('tinyglobby', () => ({ })); import { globSync } from 'tinyglobby'; -import { discoverLibraryRoutes } from './discover-library-routes.js'; +import { discoverLibraryRoutes, pageGlobs } from './discover-library-routes.js'; const mockGlobSync = vi.mocked(globSync); @@ -99,3 +99,16 @@ describe('discoverLibraryRoutes', () => { ]); }); }); + +describe('pageGlobs', () => { + it('maps directories to *.page.ts globs', () => { + expect(pageGlobs(['/libs/foo', '/libs/bar'])).toEqual([ + '/libs/foo/**/*.page.ts', + '/libs/bar/**/*.page.ts', + ]); + }); + + it('returns an empty array for no directories', () => { + expect(pageGlobs([])).toEqual([]); + }); +}); diff --git a/packages/platform/src/lib/discover-library-routes.ts b/packages/platform/src/lib/discover-library-routes.ts index 8e1b4ef17..e9c534314 100644 --- a/packages/platform/src/lib/discover-library-routes.ts +++ b/packages/platform/src/lib/discover-library-routes.ts @@ -109,3 +109,15 @@ export function discoverLibraryRoutes( return result; } + +/** + * Builds `${dir}/**\/*.page.ts` globs for each provided directory. + * + * Pass the result to `@analogjs/vite-plugin-angular`'s `include` option so + * workspace libraries discovered by `discoverLibraryRoutes` (or supplied + * via `analog({ additionalPagesDirs })`) participate in Angular + * compilation. + */ +export function pageGlobs(dirs: string[]): string[] { + return dirs.map((dir) => `${dir}/**/*.page.ts`); +} diff --git a/packages/platform/src/lib/nitro/analog-nitro-plugin.spec.ts b/packages/platform/src/lib/nitro/analog-nitro-plugin.spec.ts new file mode 100644 index 000000000..5d9ea4689 --- /dev/null +++ b/packages/platform/src/lib/nitro/analog-nitro-plugin.spec.ts @@ -0,0 +1,144 @@ +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { analogNitroPlugin } from './analog-nitro-plugin'; + +function callConfig(plugin: any, root: string) { + const hook = plugin.config; + return typeof hook === 'function' + ? hook({ root }, { command: 'build', mode: 'production' }) + : hook?.handler({ root }, { command: 'build', mode: 'production' }); +} + +function callResolveId(plugin: any, id: string) { + const hook = plugin.resolveId; + if (typeof hook === 'function') { + return hook.call({} as any, id, undefined, {} as any); + } + return hook?.handler.call({} as any, id, undefined, {} as any); +} + +function callLoad(plugin: any, id: string) { + const hook = plugin.load; + if (typeof hook === 'function') { + return hook.call({} as any, id); + } + return hook?.handler.call({} as any, id); +} + +describe('analogNitroPlugin', () => { + let workspaceRoot: string; + let projectRoot: string; + + beforeEach(() => { + workspaceRoot = mkdtempSync(join(tmpdir(), 'analog-nitro-plugin-')); + projectRoot = workspaceRoot; + mkdirSync(join(workspaceRoot, 'src'), { recursive: true }); + writeFileSync( + join(workspaceRoot, 'src/main.server.ts'), + 'export default () => "";', + ); + writeFileSync( + join(workspaceRoot, 'index.html'), + '
', + ); + }); + + afterEach(() => { + rmSync(workspaceRoot, { recursive: true, force: true }); + }); + + it('exposes the expected plugin shape', () => { + const plugin = analogNitroPlugin({ workspaceRoot }); + expect(plugin.name).toBe('@analogjs/nitro'); + expect(plugin.enforce).toBe('pre'); + expect(typeof plugin.config).toBe('function'); + expect(typeof plugin.resolveId).toBe('function'); + expect(typeof plugin.load).toBe('function'); + expect(typeof (plugin as any).nitro.setup).toBe('function'); + }); + + it('registers the SSR service entry and linker optimizeDeps when ssr=true', () => { + const plugin = analogNitroPlugin({ workspaceRoot, ssr: true }); + const overrides: any = callConfig(plugin, projectRoot); + + expect(overrides.experimental.vite.services.ssr.entry).toMatch( + /\.analog\/__ssr-entry\.mjs$/, + ); + expect(overrides.environments.ssr.optimizeDeps.include).toContain( + '@angular/core', + ); + expect(overrides.environments.ssr.optimizeDeps.include).toContain( + '@angular/platform-server', + ); + expect( + overrides.environments.ssr.optimizeDeps.rolldownOptions.plugins, + ).toHaveLength(1); + }); + + it('does not configure SSR overrides when ssr=false', () => { + const plugin = analogNitroPlugin({ workspaceRoot, ssr: false }); + const overrides: any = callConfig(plugin, projectRoot); + + expect(overrides.experimental).toBeUndefined(); + expect(overrides.environments).toBeUndefined(); + }); + + it('resolves the SSR entry marker path to the virtual id', () => { + const plugin = analogNitroPlugin({ workspaceRoot }); + callConfig(plugin, projectRoot); + + const markerPath = join(workspaceRoot, '.analog/__ssr-entry.mjs'); + expect(callResolveId(plugin, markerPath)).toBe( + '\0virtual:@analogjs/nitro/ssr-entry', + ); + expect(callResolveId(plugin, '/some/other/path.ts')).toBeNull(); + }); + + it('emits a wrapper that imports the user main.server.ts and inlines the template', () => { + const plugin = analogNitroPlugin({ workspaceRoot }); + callConfig(plugin, projectRoot); + + const code = callLoad(plugin, '\0virtual:@analogjs/nitro/ssr-entry'); + expect(typeof code).toBe('string'); + expect(code).toContain('main.server.ts'); + expect(code).toContain('export default {'); + expect(code).toContain('fetch(req)'); + // Template is JSON.stringified into the wrapper, so quotes are escaped. + expect(code).toContain('id=\\"app\\"'); + expect(code).toContain("'x-analog-no-ssr'"); + }); + + it('registers page handlers and the page-endpoints rollup plugin in nitro setup', async () => { + mkdirSync(join(workspaceRoot, 'src/app/pages'), { recursive: true }); + writeFileSync( + join(workspaceRoot, 'src/app/pages/index.server.ts'), + 'export const load = () => ({});', + ); + + const plugin = analogNitroPlugin({ workspaceRoot }); + callConfig(plugin, projectRoot); + + const hookFn = vi.fn(); + const nitroMock: any = { + options: { + rootDir: projectRoot, + buildDir: join(projectRoot, '.nitro'), + handlers: [], + scanDirs: [], + virtual: {}, + renderer: {}, + dev: true, + }, + hooks: { hook: hookFn }, + }; + + await (plugin as any).nitro.setup(nitroMock); + + expect(nitroMock.options.handlers).toHaveLength(1); + expect(nitroMock.options.handlers[0].route).toContain('/_analog/pages'); + expect(hookFn).toHaveBeenCalledWith('rollup:before', expect.any(Function)); + }); +}); diff --git a/packages/platform/src/lib/nitro/analog-nitro-plugin.ts b/packages/platform/src/lib/nitro/analog-nitro-plugin.ts new file mode 100644 index 000000000..0a10c2e7a --- /dev/null +++ b/packages/platform/src/lib/nitro/analog-nitro-plugin.ts @@ -0,0 +1,946 @@ +import { existsSync, readFileSync, readdirSync } from 'node:fs'; +import { mkdir, writeFile } from 'node:fs/promises'; +import { dirname, relative, resolve } from 'node:path'; +import type { Nitro, NitroEventHandler, PrerenderRoute } from 'nitro/types'; +import type { Plugin, UserConfig } from 'vite'; + +import type { Options } from '../options.js'; +import type { + PrerenderContentDir, + PrerenderContentFile, + PrerenderRouteConfig, + PrerenderSitemapConfig, +} from './types.js'; +import { getPageHandlers } from './get-page-handlers.js'; +import { pageEndpointsPlugin } from './page-endpoints-plugin.js'; +import { getMatchingContentFilesWithFrontMatter } from './get-content-files.js'; +import { buildSitemap } from './build-sitemap.js'; +import { addPostRenderingHooks } from './post-rendering-hook.js'; +import { + expandRoutesWithLocales, + createI18nPostRenderingHook, +} from './i18n-prerender.js'; +import { angularLinkerPlugin } from './angular-linker-plugin.js'; + +const SSR_ENTRY_VIRTUAL_ID = '\0virtual:@analogjs/nitro/ssr-entry'; + +/** + * Angular packages that ship in partial-compilation form and must pass + * through the linker before the SSR / nitro bundle can execute without + * JIT. Wired into `ssr.optimizeDeps.rolldownOptions.plugins`. + */ +const ANGULAR_SSR_DEPS = [ + '@angular/compiler', + '@angular/core', + '@angular/common', + '@angular/platform-browser', + '@angular/platform-server', +]; + +interface NitroPluginContext { + workspaceRoot: string; + rootDir: string; + sourceRoot: string; +} + +type RouteSitemap = + | PrerenderSitemapConfig + | (() => PrerenderSitemapConfig) + | undefined; + +/** + * Analog's NitroModule. Plug it into the Vite plugin chain alongside + * `nitro()` from `nitro/vite`; nitro/vite picks up the `.nitro` property + * and runs `setup(nitro)` once the Nitro instance is ready. + */ +export function analogNitroPlugin(options: Options = {}): Plugin { + const workspaceRoot = + options.workspaceRoot ?? process.env['NX_WORKSPACE_ROOT'] ?? process.cwd(); + const sourceRoot = 'src'; + const ssr = options.ssr ?? true; + const apiPrefix = options.apiPrefix ?? 'api'; + + let context: NitroPluginContext = { + workspaceRoot, + rootDir: '.', + sourceRoot, + }; + let ssrEntryMarkerPath = ''; + let userPublicDir: string | undefined; + + function refreshContext(viteRoot: string | undefined) { + const root = viteRoot ?? process.cwd(); + context = { + workspaceRoot, + rootDir: relative(workspaceRoot, root) || '.', + sourceRoot, + }; + ssrEntryMarkerPath = resolve( + context.workspaceRoot, + context.rootDir, + '.analog/__ssr-entry.mjs', + ); + } + + function readIndexHtml(): string { + const indexFile = options.index ?? 'index.html'; + const candidates = [ + resolve(context.workspaceRoot, context.rootDir, indexFile), + resolve( + context.workspaceRoot, + 'dist', + context.rootDir, + 'client', + indexFile, + ), + ]; + for (const candidate of candidates) { + if (existsSync(candidate)) { + return readFileSync(candidate, 'utf-8'); + } + } + return '
'; + } + + function resolveEntryServer(): string { + return ( + options.entryServer ?? + resolve( + context.workspaceRoot, + context.rootDir, + `${sourceRoot}/main.server.ts`, + ) + ); + } + + const plugin: Plugin & { + nitro: { setup: (nitro: Nitro) => void | Promise }; + } = { + name: '@analogjs/nitro', + enforce: 'pre', + + config(userConfig) { + refreshContext(userConfig.root); + + // Capture the user's Vite `publicDir` so the nitro `setup()` hook can + // register it as a Nitro `publicAssets` source. nitro/vite forces the + // client environment's `build.copyPublicDir` to `false` + // (vite.mjs:248), expecting Nitro to manage public assets — but + // doesn't auto-add the user's `publicDir`. Without this, anything + // under `src/public/` (e.g. `/assets/shipping.json`) 404s during SSR + // and ofetch consumers parse the catch-all SSR HTML as JSON. + if (userConfig.publicDir !== false) { + userPublicDir = resolve( + context.workspaceRoot, + context.rootDir, + (userConfig.publicDir as string | undefined) ?? 'public', + ); + } + + // Bridge the legacy `BUILD_PRESET` env var that `@analogjs/vite-plugin-nitro` + // accepted into Nitro v3's `NITRO_PRESET`, and auto-pick the matching + // preset when the build runs inside a host's CI (each host sets its + // own well-known env var). Mirrors the legacy plugin's behavior so + // users upgrading don't need to change their CI configuration. + if (!process.env['NITRO_PRESET']) { + if (process.env['BUILD_PRESET']) { + process.env['NITRO_PRESET'] = process.env['BUILD_PRESET']; + } else if (process.env['VERCEL']) { + process.env['NITRO_PRESET'] = 'vercel'; + } else if (process.env['NETLIFY']) { + process.env['NITRO_PRESET'] = 'netlify'; + } else if (process.env['CF_PAGES']) { + process.env['NITRO_PRESET'] = 'cloudflare-pages'; + } + } + + const overrides: UserConfig = { + // Vite 8 defaults `server.fs.allow` to `[searchForWorkspaceRoot(root)]`, + // which should already cover the workspace root. In practice, nitro/vite's + // env-runner loads its own `dev-entry.mjs` from a pnpm content-hash path + // (`node_modules/.pnpm/nitro@.../...`) through Vite's ModuleRunner and + // hits an `ERR_LOAD_URL`/"Does the file exist?" error unless an explicit + // allow entry covers the same root. Whitelist the workspace root here so + // users don't have to write the workaround in every vite.config.ts. + server: { + fs: { + allow: [context.workspaceRoot], + }, + }, + }; + + if (ssr) { + // Two-pronged registration: `experimental.vite.services.ssr.entry` + // is the documented hook, but nitro/vite's setupNitroContext also + // accepts an `environments.ssr.build.rollupOptions.input` entry + // (see node_modules/nitro/dist/vite.mjs:710-734). When `analog()` + // and `nitro()` are invoked separately, the `services` slot on + // `nitro()`'s pluginConfig is empty, so the rollupOptions.input + // path is how we get our wrapper entry recognized. + overrides.experimental = { + vite: { + services: { + ssr: { entry: ssrEntryMarkerPath }, + }, + }, + }; + overrides.environments = { + ssr: { + build: { + outDir: resolve( + context.workspaceRoot, + 'dist', + context.rootDir, + 'ssr', + ), + rollupOptions: { + input: { index: ssrEntryMarkerPath }, + }, + }, + optimizeDeps: { + include: ANGULAR_SSR_DEPS, + rolldownOptions: { + plugins: [angularLinkerPlugin()], + }, + }, + }, + } as UserConfig['environments']; + } + + return overrides; + }, + + resolveId(id) { + if (id === ssrEntryMarkerPath || id === SSR_ENTRY_VIRTUAL_ID) { + return SSR_ENTRY_VIRTUAL_ID; + } + return null; + }, + + load(id) { + if (id !== SSR_ENTRY_VIRTUAL_ID) return null; + return generateSsrEntryWrapper(resolveEntryServer(), readIndexHtml()); + }, + + nitro: { + async setup(nitro) { + // refreshContext may not have run yet if nitro/vite resolved the + // plugin before `config()`; fall back to nitro's own root. + if (!context || context.rootDir === '.') { + refreshContext(nitro.options.rootDir); + } + + // Preserve the legacy `@analogjs/vite-plugin-nitro` final output + // layout so downstream tooling (deploy scripts, docs, the + // `dist/analog/server` start command) keeps working. nitro/vite's + // default `/.output` would otherwise drop artifacts in an + // unexpected location for users upgrading from v2. + // + // Build only. During dev, leaving the output paths at Nitro's + // defaults keeps the dev server's `readAsset` happy — those + // virtuals expect to read from the in-memory module graph, not + // from a `dist/` directory that doesn't exist yet. + // + // `buildDir` (Nitro's intermediate scratch dir) stays at its default + // inside the project root. Nitro's prerender phase re-bundles SSR + // chunks out of `/vite/services/ssr/`, and Rolldown's + // resolver walks up from those files looking for `node_modules/`. + // Keeping `buildDir` adjacent to the project root means workspace + // packages installed at `/node_modules/` (the usual install + // shape for both standalone and Nx setups) remain reachable. + if (!nitro.options.dev) { + // Deployment presets (Vercel, Netlify, Cloudflare, Firebase, ...) + // own their own output layout — Vercel writes the Build Output API + // tree under `.vercel/output/`, Netlify expects functions under + // `.netlify/functions-internal/` with static assets under `dist/`, + // and so on. Clobbering `output.{dir,publicDir,serverDir}` for + // those presets leaves functions and static files in different + // trees and breaks the deploy. Only override when running the + // default node-server preset (or no preset at all) so docs and + // the legacy `dist/analog/server` start command keep working for + // standalone Node deployments. + const preset = (nitro.options.preset ?? '').toLowerCase(); + const isManagedPreset = + preset !== '' && + preset !== 'node-server' && + preset !== 'node' && + preset !== 'nitro-dev'; + + // Vercel's Build Output API expects `.vercel/output/` at the cwd + // `vercel build` runs from (the repo root). Nitro's preset anchors + // to `{{rootDir}}`, so in Nx monorepos artifacts land at + // `apps//.vercel/output/` and the deploy can't find them. + // Hoist to workspace root and apply Analog's runtime defaults. + if (preset.includes('vercel')) { + const vercel = (nitro.options as { vercel?: Record }) + .vercel; + (nitro.options as { vercel?: Record }).vercel = { + ...vercel, + entryFormat: vercel?.entryFormat ?? 'node', + functions: { + runtime: vercel?.functions?.runtime ?? 'nodejs24.x', + ...vercel?.functions, + }, + }; + const vercelDir = resolve(context.workspaceRoot, '.vercel/output'); + nitro.options.output = { + ...nitro.options.output, + dir: vercelDir, + serverDir: resolve(vercelDir, 'functions/__server.func'), + publicDir: resolve(vercelDir, 'static'), + }; + } + + // Netlify auto-discovers functions under + // `/.netlify/functions-internal/`. Nitro's netlify + // preset anchors that to `{{rootDir}}`, which in Nx monorepos + // becomes `apps//.netlify/...` and is invisible to the + // Netlify deploy. Hoist the functions to the workspace root so + // `nx build ` produces a deploy-ready tree at the repo root. + // Keep `publicDir` under `dist//analog/public/` (the + // legacy Analog Netlify publish layout) — the user wires their + // `netlify.toml` publish path to it. + if (preset === 'netlify' || preset === 'netlify-edge') { + const netlifyDir = resolve( + context.workspaceRoot, + '.netlify/functions-internal', + ); + nitro.options.output = { + ...nitro.options.output, + dir: netlifyDir, + serverDir: resolve(netlifyDir, 'server'), + publicDir: resolve( + context.workspaceRoot, + 'dist', + context.rootDir, + 'analog/public', + ), + }; + } + + // Cloudflare Pages/Workers presets anchor their output at + // `{{rootDir}}/dist` or `{{rootDir}}/.output`, which puts the + // deploy tree at `apps//...` for Nx monorepos. Hoist to + // `/dist//` so `wrangler pages deploy + // dist/` from the workspace root finds `_worker.js/` + // alongside the static assets. + if (preset.includes('cloudflare')) { + const cfDir = resolve( + context.workspaceRoot, + 'dist', + context.rootDir, + ); + nitro.options.output = { + ...nitro.options.output, + dir: cfDir, + publicDir: cfDir, + serverDir: resolve(cfDir, '_worker.js'), + }; + } + + if (!isManagedPreset) { + const distRoot = resolve( + context.workspaceRoot, + 'dist', + context.rootDir, + ); + nitro.options.output = { + ...nitro.options.output, + dir: resolve(distRoot, 'analog'), + publicDir: resolve(distRoot, 'analog/public'), + serverDir: resolve(distRoot, 'analog/server'), + }; + } + + // Nitro v3's prerender writer compares `filePath.startsWith(publicDir)` + // with `filePath` built via `node:path.join` (platform-native + // separators on Windows) and `publicDir` set via `resolveNitroPath` + // (always forward slashes via pathe). On Windows the two sides + // disagree and every route is marked `(skipped)` — no HTML is + // written. Hook `prerender:route` and write the file ourselves + // when Nitro has skipped it but the route generated content. + nitro.hooks.hook('prerender:route', async (route) => { + if (!route.skip || route.error) return; + const buffer = route.data; + if (!buffer || !route.fileName) return; + const filePath = resolve( + nitro.options.output.publicDir, + route.fileName.replace(/^[\\/]+/, ''), + ); + try { + await mkdir(dirname(filePath), { recursive: true }); + await writeFile(filePath, Buffer.from(buffer)); + route.skip = false; + } catch { + // leave Nitro's skip in place if the manual write also fails + } + }); + } + + // Register the user's Vite `publicDir` (e.g. `src/public/`) as a + // Nitro public asset source. nitro/vite turns off Vite's own copy + // of publicDir so Nitro can take over, but doesn't auto-bridge the + // user's setting — without this entry, files like + // `src/public/assets/shipping.json` aren't served and `HttpClient` + // SSR fetches fall through to the catch-all SSR renderer, leaking + // HTML where consumers expected JSON. + if (userPublicDir && existsSync(userPublicDir)) { + const already = nitro.options.publicAssets.some( + (asset) => asset.dir === userPublicDir, + ); + if (!already) { + nitro.options.publicAssets.push({ + dir: userPublicDir, + baseURL: '/', + maxAge: 0, + fallthrough: true, + }); + } + } + + // Bridge the outer Nitro's `output.publicDir` into the prerender's + // own Nitro instance. Nitro spawns a nested `nitroRenderer` for the + // prerender pass (`createNitro({ preset: 'nitro-prerender' })`) and + // builds the public-assets manifest by glob-scanning that + // instance's `output.publicDir`. The nested config resets + // `output.publicDir` to undefined and resolves it against the + // prerender preset defaults (`/.output/public`), so the + // scan hits an empty directory and the manifest is empty — every + // `HttpClient.get('/assets/...')` during SSR then falls through to + // the catch-all SSR renderer and the consumer parses HTML as JSON. + // Force the nested publicDir to match the outer publicDir (which + // `copyPublicAssets` has already populated by this point). + nitro.hooks.hook( + 'prerender:config', + (prerendererConfig: { output?: Record }) => { + prerendererConfig.output = { + ...prerendererConfig.output, + publicDir: nitro.options.output.publicDir, + }; + }, + ); + + const hasAPIDir = existsSync( + resolve( + context.workspaceRoot, + context.rootDir, + `${context.sourceRoot}/server/routes/api`, + ), + ); + + const pageHandlers: NitroEventHandler[] = getPageHandlers({ + workspaceRoot: context.workspaceRoot, + sourceRoot: context.sourceRoot, + rootDir: context.rootDir, + additionalPagesDirs: options.additionalPagesDirs, + hasAPIDir, + }); + nitro.options.handlers.push(...pageHandlers); + + const serverDir = resolve( + context.workspaceRoot, + context.rootDir, + `${context.sourceRoot}/server`, + ); + if ( + existsSync(serverDir) && + !nitro.options.scanDirs.includes(serverDir) + ) { + nitro.options.scanDirs.push(serverDir); + } + + nitro.hooks.hook('rollup:before', (_n, rollupConfig: any) => { + if (Array.isArray(rollupConfig.plugins)) { + rollupConfig.plugins.push(pageEndpointsPlugin()); + } + applyAnalogNitroExternals(rollupConfig); + sanitizeNitroBundlerConfig(rollupConfig); + }); + + if (ssr) { + // Override Nitro's auto-detected template-serving renderer with one + // that routes HTML requests to our SSR service. Nitro's + // `resolveRendererOptions` finds `index.html` at the project root + // and installs `internal/routes/renderer-template[.dev]`, which + // just serves the raw template. nitro/vite's own SSR-routing + // renderer only auto-installs when both `renderer.handler` and + // `renderer.template` are empty (vite.mjs:574), which never holds + // for a typical app — so we install our own renderer virtual + // explicitly here. + // + // `#analog/ssr` is a Nitro virtual (not a Vite virtual) so it + // resolves under both Vite-built bundles (main) and Rolldown-built + // bundles (Nitro's prerender, which forces builder: 'rolldown' — + // see nitro/dist/_chunks/nitro.mjs:769). That sidesteps nitro/vite's + // prodSetup polyfill, which is Vite-only and leaves + // `__nitro_vite_envs__` unset in the prerender bundle. + nitro.options.virtual['#analog/ssr'] = () => + generateSsrServiceVirtual(nitro); + nitro.options.virtual['#analog/ssr-renderer'] = + generateSsrRendererVirtual(readIndexHtml()); + nitro.options.renderer ??= {}; + nitro.options.renderer.handler = '#analog/ssr-renderer'; + delete nitro.options.renderer.template; + } + // When ssr === false, Nitro's auto-detected template-serving + // renderer is exactly what we want (serve the raw index.html for + // every HTML request) — leave it in place. + + injectAnalogRouteRuleHeaders(nitro); + + await wirePrerender(nitro, options, context, apiPrefix); + + if (options.i18n) { + addPostRenderingHooks(nitro, [ + createI18nPostRenderingHook({ + defaultLocale: options.i18n.defaultLocale, + locales: options.i18n.locales, + }), + ]); + } + }, + }, + }; + + return plugin; +} + +/** + * Builds the h3 handler installed as Nitro's `renderer.handler`. Short-circuits + * `ssr: false` routes to the raw client template; otherwise dispatches the + * request to the SSR service env (`fetchViteEnv("ssr", req)` works in dev via + * the env-runner and in prod via the `__nitro_vite_envs__` global set up by + * nitro/vite's `prodSetup`). + */ +function generateSsrRendererVirtual(template: string): string { + return ` +import { defineHandler } from 'nitro/h3'; +import ssr from '#analog/ssr'; + +const TEMPLATE = ${JSON.stringify(template)}; + +export default defineHandler(async (event) => { + event.res.headers.set('content-type', 'text/html; charset=utf-8'); + // 'x-analog-no-ssr' is stamped on response headers by + // injectAnalogRouteRuleHeaders for routeRules with \`ssr: false\`. Nitro + // applies routeRule headers to the response before the renderer fires, + // so we can short-circuit by reading them here. + if (event.res.headers.get('x-analog-no-ssr') === 'true') { + return TEMPLATE; + } + const service = ssr.default ?? ssr; + return service.fetch(event.req); +}); +`; +} + +/** + * Resolves \`#analog/ssr\` to the SSR fetch handler. The shape returned by + * this function is bundler-agnostic: works in Vite-built main bundles and + * Rolldown-built prerender bundles alike. + * + * - Dev: dispatch through nitro/vite's env runner (\`fetchViteEnv\`); the SSR + * service module isn't on disk yet, so we delegate to the runner. + * - Build / prerender: re-export the built SSR entry directly from the + * filesystem. By the time Nitro's bundlers ask for \`#analog/ssr\`, Vite has + * already produced \`/vite/services/ssr/.mjs\`. + */ +function generateSsrServiceVirtual(nitro: Nitro): string { + if (nitro.options.dev) { + return ` +import { fetchViteEnv } from 'nitro/vite/runtime'; +export default { + async fetch(req) { + return fetchViteEnv('ssr', req); + }, +}; +`; + } + + const ssrDir = resolve(nitro.options.buildDir, 'vite/services/ssr'); + if (!existsSync(ssrDir)) { + return `export default { async fetch() { throw new Error('Analog SSR service directory missing: ${ssrDir}'); } };`; + } + const entries = readdirSync(ssrDir).filter((f) => f.endsWith('.mjs')); + if (entries.length === 0) { + return `export default { async fetch() { throw new Error('No Analog SSR entry file built in: ${ssrDir}'); } };`; + } + // Prefer 'main.server.mjs' if present; otherwise take the only entry. + const entry = entries.find((f) => f === 'main.server.mjs') ?? entries[0]; + const entryPath = resolve(ssrDir, entry); + return `export { default } from ${JSON.stringify(entryPath)};`; +} + +/** + * Packages Analog forces external in the Nitro server bundle. Each entry is + * here for a specific reason — see comments. + */ +const ANALOG_NITRO_EXTERNALS = [ + // rxjs ships per-entry CJS/ESM facades that confuse the Nitro/Rolldown + // resolver during bundling. + 'rxjs', + // node-fetch-native's polyfill subpath rewrites global fetch and isn't + // safe to inline into the Nitro bundle. + 'node-fetch-native/dist/polyfill', + // sharp ships platform-specific native binaries under @img/sharp-*. pnpm + // creates symlinks for ALL optional platform deps but only installs the + // matching one, leaving broken symlinks that crash Nitro's externals + // plugin with ENOENT during realpath(). Externalizing sharp avoids + // bundling it; the user's app resolves it from node_modules at runtime. + 'sharp', +]; + +function applyAnalogNitroExternals(rollupConfig: { external?: unknown }): void { + // Rolldown's `external` only accepts `Array`; promote + // whatever shape Nitro gave us (regex, single string, undefined) to an + // array and append Analog's entries as regex patterns that also match + // sub-paths (e.g. `sharp` matches `sharp/lib/foo`). + const prev = rollupConfig.external; + const existing: Array = + prev === undefined + ? [] + : Array.isArray(prev) + ? (prev as Array) + : prev instanceof RegExp + ? [prev] + : typeof prev === 'string' + ? [prev] + : []; + + const escapeRegExp = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + + for (const entry of ANALOG_NITRO_EXTERNALS) { + const pattern = new RegExp(`^${escapeRegExp(entry)}(?:/|$)`); + if (!existing.some((p) => String(p) === String(pattern))) { + existing.push(pattern); + } + } + + rollupConfig.external = existing; +} + +/** + * Workarounds for Nitro v3 + Rolldown bundler interaction quirks. Each + * is narrowly scoped and can be removed once the upstream bug is fixed: + * + * 1. `output.codeSplitting` — Nitro 3.0.x sets this; Rolldown rejects it + * as an unknown key. + * 2. `output.manualChunks` — Nitro's default manual chunking crashes + * Nitro's prerender rebundle. + * 3. `output.chunkFileNames` — Nitro's chunk-name function produces + * route-derived `[token]` patterns which Rollup/Rolldown interprets as + * placeholders; we rewrite non-standard tokens to `_token_`. + */ +function sanitizeNitroBundlerConfig(rollupConfig: { output?: unknown }): void { + const output = rollupConfig.output; + if (!output || Array.isArray(output) || typeof output !== 'object') return; + const out = output as Record; + + if ('codeSplitting' in out) delete out['codeSplitting']; + if ('manualChunks' in out) delete out['manualChunks']; + + const VALID_ROLLUP_PLACEHOLDER = /^\[(?:name|hash|format|ext)\]$/; + const chunkFileNames = out['chunkFileNames']; + if (typeof chunkFileNames === 'function') { + const originalFn = chunkFileNames as (...args: unknown[]) => unknown; + out['chunkFileNames'] = (...args: unknown[]) => { + const result = originalFn(...args); + if (typeof result !== 'string') return result; + return result.replace(/\[[^\]]+\]/g, (match: string) => + VALID_ROLLUP_PLACEHOLDER.test(match) + ? match + : `_${match.slice(1, -1)}_`, + ); + }; + } +} + +/** + * Walks Nitro's resolved routeRules and stamps `x-analog-no-ssr: true` onto + * any rule with `ssr: false`. Kept as a response-header hint for downstream + * consumers (CDN, edge logic); the actual SSR short-circuit happens inside + * the SSR renderer virtual above. + */ +function injectAnalogRouteRuleHeaders(nitro: Nitro): void { + const routeRules = nitro.options.routeRules as + | Record }> + | undefined; + if (!routeRules) return; + + for (const rule of Object.values(routeRules)) { + if (rule?.ssr === false) { + rule.headers = { ...rule.headers, 'x-analog-no-ssr': 'true' }; + } + } +} + +/** + * Builds the SSR service entry source. The wrapper imports the user's + * `main.server.ts` Angular renderer and adapts it to the `{ fetch(req) }` + * shape that nitro/vite's service mechanism expects. + */ +function generateSsrEntryWrapper( + entryServer: string, + template: string, +): string { + return ` +// Import \`serverFetch\` from the root \`nitro\` entry rather than \`nitro/app\`. +// The /app subpath creates a fresh \`useNitroApp()\` instance scoped to the +// importing bundle, which in our setup is the standalone SSR vite bundle — +// it has no route handlers, so every fetch 404s. The root entry instead +// reads \`globalThis.__nitro__.{default,prerender}\`, which the surrounding +// Nitro server (prerender pass or production runtime) has already +// populated with the real app + handlers. +import { serverFetch as nitroServerFetch } from 'nitro'; +import { createFetch } from 'ofetch'; +import renderer from ${JSON.stringify(entryServer)}; + +const TEMPLATE = ${JSON.stringify(template)}; + +const normalizeRequestPath = (url) => + url.replace(/\\/index\\.html(?=$|[?#])/, '/'); + +// In-process fetch wired into Nitro's request pipeline. Angular's HttpClient +// (via withFetch()) and Analog's injectLoad() call this during SSR/prerender +// so they hit the running app's page-endpoint and API routes without going +// through the network — the prerender pipeline doesn't have a listening +// socket. Without this, every SSR data fetch ECONNREFUSEs and Angular's +// router fails to resolve any data-bound route, producing an empty +// in the prerendered HTML. +const ssrFetch = (resource, init) => { + let url = typeof resource === 'string' + ? resource + : resource instanceof URL + ? resource.href + : resource.url; + // Relative URLs from injectAPIPrefix() etc. need a host for Nitro's + // Request constructor to accept them. + if (typeof url === 'string' && url.startsWith('/')) { + url = 'http://localhost' + url; + } + return nitroServerFetch(url, init); +}; + +// Wrap in ofetch so consumers that expect \`$fetch.raw()\` (the router's +// request-context interceptor short-circuits SSR HttpClient calls through +// \`globalThis.$fetch.raw\`) can call it. Set on globalThis so router code +// running inside the Angular renderer can find it. +const ssrOFetch = createFetch({ fetch: ssrFetch }); +if (typeof globalThis.$fetch === 'undefined') { + globalThis.$fetch = ssrOFetch; +} + +export default { + async fetch(req) { + const url = new URL(req.url); + const requestPath = normalizeRequestPath(url.pathname); + // Preserve the query string so Angular's router + injectQuery() and + // server data loaders that read from req.url see the full path+query. + const requestUrl = requestPath + url.search; + + if (req.headers.get('x-analog-no-ssr') === 'true') { + return new Response(TEMPLATE, { + status: 200, + headers: { 'content-type': 'text/html; charset=utf-8' }, + }); + } + + const reqShim = { + headers: Object.fromEntries(req.headers.entries()), + url: requestUrl, + originalUrl: requestUrl, + connection: {}, + }; + + try { + const html = await renderer(requestUrl, TEMPLATE, { + req: reqShim, + // Pass the ofetch-wrapped fetch — INTERNAL_FETCH is consumed by the + // router's request-context interceptor via \`serverFetch.raw(...)\`, + // which is ofetch's response-shape API. Plain fetch lacks \`.raw\` + // and throws TypeError during prerender/SSR. + fetch: ssrOFetch, + }); + return new Response(html, { + status: 200, + headers: { 'content-type': 'text/html; charset=utf-8' }, + }); + } catch (err) { + console.error('[analog ssr]', err); + return new Response(TEMPLATE, { + status: 500, + headers: { 'content-type': 'text/html; charset=utf-8' }, + }); + } + }, +}; +`; +} + +async function wirePrerender( + nitro: Nitro, + options: Options, + context: NitroPluginContext, + apiPrefix: string, +): Promise { + const prerender = options.prerender; + if (!prerender && !options.i18n) return; + + const { + routes: collected, + sitemaps: routeSitemaps, + routeSourceFiles, + } = await collectRoutes(prerender?.routes, context, apiPrefix); + + const expanded = options.i18n + ? expandRoutesWithLocales(collected, { + defaultLocale: options.i18n.defaultLocale, + locales: options.i18n.locales, + }) + : collected; + + const nitroPrerender = (nitro.options.prerender ??= {}) as Record< + string, + any + >; + nitroPrerender.routes ??= []; + nitroPrerender.routes.push(...expanded); + if (prerender?.discover ?? false) { + nitroPrerender.crawlLinks = true; + } + + if (prerender?.postRenderingHooks?.length) { + addPostRenderingHooks(nitro, prerender.postRenderingHooks); + } + + if (Object.keys(routeSourceFiles).length > 0) { + // Mirror the legacy `@analogjs/vite-plugin-nitro` behavior: after + // prerender completes, write the route's source content alongside the + // prerendered HTML at `/.md`. Drives the + // `outputSourceFile` option on both `PrerenderRouteConfig` (string path + // to source markdown) and `PrerenderContentDir` (per-file callback). + nitro.hooks.hook('prerender:done', async () => { + const publicDir = resolve(nitro.options.output.publicDir); + const { mkdirSync, writeFileSync } = await import('node:fs'); + const { dirname, join } = await import('node:path'); + for (const [route, content] of Object.entries(routeSourceFiles)) { + const outputPath = join(publicDir, `${route}.md`); + mkdirSync(dirname(outputPath), { recursive: true }); + writeFileSync(outputPath, content, 'utf8'); + } + }); + } + + const sitemapConfig = prerender?.sitemap; + if (sitemapConfig) { + nitro.hooks.hook('prerender:done', async (result) => { + const prerenderedRoutes = (result?.prerenderedRoutes ?? []).map( + (r: PrerenderRoute) => r.route, + ); + const publicDir = resolve(nitro.options.output.publicDir); + await buildSitemap( + {} as any, + sitemapConfig, + prerenderedRoutes, + publicDir, + routeSitemaps, + { apiPrefix }, + ); + }); + } +} + +async function collectRoutes( + routesInput: Options['prerender'] extends infer P + ? P extends { routes?: infer R } + ? R + : never + : never, + context: NitroPluginContext, + apiPrefix: string, +): Promise<{ + routes: string[]; + sitemaps: Record; + routeSourceFiles: Record; +}> { + const out: string[] = []; + const sitemaps: Record = {}; + const routeSourceFiles: Record = {}; + + if (!routesInput) return { routes: out, sitemaps, routeSourceFiles }; + + const inputs = Array.isArray(routesInput) + ? routesInput + : typeof routesInput === 'function' + ? await routesInput() + : []; + + for (const entry of inputs) { + if (!entry) continue; + + if (typeof entry === 'string') { + out.push(entry); + continue; + } + + if ('contentDir' in entry) { + const dir = entry as PrerenderContentDir; + const files = getMatchingContentFilesWithFrontMatter( + context.workspaceRoot, + context.rootDir, + dir.contentDir, + !!dir.recursive, + ); + for (const file of files) { + const route = dir.transform(file); + if (route === false) continue; + out.push(route); + if (dir.sitemap) { + sitemaps[route] = + typeof dir.sitemap === 'function' + ? ( + dir.sitemap as ( + f: PrerenderContentFile, + ) => PrerenderSitemapConfig + )(file) + : dir.sitemap; + } + if (dir.outputSourceFile) { + const sourceContent = dir.outputSourceFile(file); + if (typeof sourceContent === 'string') { + routeSourceFiles[route] = sourceContent; + } + } + } + continue; + } + + if ('route' in entry) { + const cfg = entry as PrerenderRouteConfig; + out.push(cfg.route); + if (cfg.sitemap) { + sitemaps[cfg.route] = cfg.sitemap; + } + if (cfg.outputSourceFile) { + const sourcePath = resolve( + context.workspaceRoot, + context.rootDir, + cfg.outputSourceFile, + ); + if (existsSync(sourcePath)) { + routeSourceFiles[cfg.route] = readFileSync(sourcePath, 'utf8'); + } + } + if (cfg.staticData) { + // Mirror the legacy plugin: when staticData is requested, also + // prerender the page's data-fetching endpoint so the JSON payload + // is available statically. + const prefix = apiPrefix.startsWith('/') ? apiPrefix : `/${apiPrefix}`; + const route = cfg.route.startsWith('/') ? cfg.route : `/${cfg.route}`; + out.push(`${prefix}/_analog/pages${route}`); + } + } + } + + return { routes: out, sitemaps, routeSourceFiles }; +} diff --git a/packages/platform/src/lib/nitro/angular-linker-plugin.spec.ts b/packages/platform/src/lib/nitro/angular-linker-plugin.spec.ts new file mode 100644 index 000000000..ea29e1d1b --- /dev/null +++ b/packages/platform/src/lib/nitro/angular-linker-plugin.spec.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from 'vitest'; + +import { angularLinkerPlugin } from './angular-linker-plugin'; + +describe('angularLinkerPlugin', () => { + const plugin = angularLinkerPlugin(); + + it('exposes a Rolldown plugin shape', () => { + expect(plugin.name).toBe('analogjs-platform-angular-linker'); + expect(typeof plugin.transform).toBe('function'); + }); + + it('skips non-JS files', async () => { + const result = await plugin.transform('export const x = 1;', '/foo.ts'); + expect(result).toBeUndefined(); + }); + + it('skips JS files that do not contain partial Angular declarations', async () => { + const result = await plugin.transform( + 'export const greeting = "hello";', + '/foo.mjs', + ); + expect(result).toBeUndefined(); + }); +}); diff --git a/packages/platform/src/lib/nitro/angular-linker-plugin.ts b/packages/platform/src/lib/nitro/angular-linker-plugin.ts new file mode 100644 index 000000000..c56f78eb0 --- /dev/null +++ b/packages/platform/src/lib/nitro/angular-linker-plugin.ts @@ -0,0 +1,65 @@ +/** + * Rolldown plugin that runs the Angular Linker against partially-compiled + * Angular npm packages. + * + * Wired into `ssr.optimizeDeps.rolldownOptions.plugins` so the SSR / + * `nitro` environment's dep optimizer turns `ɵɵngDeclare*` partial + * declarations into fully-compiled definitions. Without this, the + * server bundle would need JIT (eval) at runtime — forbidden on + * `workerd` / edge runtimes and unnecessary anywhere else. + * + * Loaded lazily so apps that never trigger the SSR optimizer don't + * incur the babel + compiler-cli/linker cost. + */ +export function angularLinkerPlugin() { + let linkerBabelPlugin: unknown; + let needsLinkingFn: ((id: string, code: string) => boolean) | undefined; + let transformAsyncFn: + | (( + code: string, + options: Record, + ) => Promise<{ code?: string; map?: unknown } | null>) + | undefined; + + async function ensureLoaded() { + if (linkerBabelPlugin && needsLinkingFn && transformAsyncFn) return; + + const linker = await import('@angular/compiler-cli/linker'); + needsLinkingFn = linker.needsLinking; + + const linkerBabel = await import('@angular/compiler-cli/linker/babel'); + linkerBabelPlugin = + (linkerBabel as { default?: unknown }).default ?? linkerBabel; + + // @ts-expect-error — @babel/core ships without bundled type declarations + const babel = await import('@babel/core'); + transformAsyncFn = babel.transformAsync; + } + + return { + name: 'analogjs-platform-angular-linker', + async transform(code: string, id: string) { + if (!id.endsWith('.mjs') && !id.endsWith('.js')) return; + + // Cheap pre-check before pulling babel/compiler-cli into memory. + if (!code.includes('ɵɵngDeclare')) return; + + await ensureLoaded(); + if (!needsLinkingFn!(id, code)) return; + + const result = await transformAsyncFn!(code, { + filename: id, + plugins: [linkerBabelPlugin], + sourceMaps: true, + compact: false, + configFile: false, + babelrc: false, + }); + + if (result?.code) { + return { code: result.code, map: result.map ?? null }; + } + return; + }, + }; +} diff --git a/packages/platform/src/lib/nitro/build-sitemap.spec.ts b/packages/platform/src/lib/nitro/build-sitemap.spec.ts new file mode 100644 index 000000000..5d16b7477 --- /dev/null +++ b/packages/platform/src/lib/nitro/build-sitemap.spec.ts @@ -0,0 +1,222 @@ +import { existsSync, mkdirSync, writeFileSync } from 'node:fs'; +import { buildSitemap } from './build-sitemap'; + +vi.mock('node:fs', () => ({ + existsSync: vi.fn(() => true), + mkdirSync: vi.fn(), + writeFileSync: vi.fn(), +})); + +describe('build sitemap', () => { + const config = { root: 'root' }; + const existsSyncMock = vi.mocked(existsSync); + const mkdirSyncMock = vi.mocked(mkdirSync); + const writeFileSyncMock = vi.mocked(writeFileSync); + + afterEach(() => { + vi.restoreAllMocks(); + existsSyncMock.mockReturnValue(true); + mkdirSyncMock.mockReset(); + writeFileSyncMock.mockReset(); + }); + + it('should not perform functionality if no predefined routes are present', async () => { + await buildSitemap(config, { host: 'https://host.com' }, [], '', {}); + + expect(writeFileSyncMock).not.toHaveBeenCalled(); + }); + + it('should preserve route sitemap metadata when the host has a trailing slash', async () => { + existsSyncMock.mockReturnValue(true); + + await buildSitemap( + config, + { host: 'https://host.com/' }, + ['/blog'], + '/tmp/analog/public', + { + '/blog': { + lastmod: '2024-01-15', + changefreq: 'weekly', + priority: 0.8, + }, + }, + ); + + expect(writeFileSyncMock).toHaveBeenCalledWith( + expect.stringContaining('/tmp/analog/public/sitemap.xml'), + expect.stringContaining('https://host.com/blog'), + ); + expect(writeFileSyncMock.mock.calls[0]?.[1]).toContain( + '2024-01-15', + ); + expect(writeFileSyncMock.mock.calls[0]?.[1]).toContain( + 'weekly', + ); + expect(writeFileSyncMock.mock.calls[0]?.[1]).toContain( + '0.8', + ); + }); + + it('should apply include defaults transform exclude and internal route filtering', async () => { + existsSyncMock.mockReturnValue(true); + + await buildSitemap( + config, + { + host: 'https://host.com', + defaults: { + changefreq: 'monthly', + priority: 0.4, + }, + include: async () => [ + '/extra', + { + route: '/docs/hello world', + lastmod: '2024-01-01', + }, + ], + exclude: ['/drafts/**', /^\/admin/], + transform: (entry) => + entry.route === '/extra' + ? { + route: '/extra-updated', + priority: 0.9, + } + : { + route: entry.route, + }, + }, + [ + '/products', + '/products', + '/drafts/preview', + '/api/_analog/pages/products', + ], + '/tmp/analog/public', + {}, + ); + + const xml = writeFileSyncMock.mock.calls[0]?.[1] ?? ''; + expect(xml).toContain('https://host.com/products'); + expect(xml).toContain('monthly'); + expect(xml).toContain('0.4'); + expect(xml).toContain('https://host.com/extra-updated'); + expect(xml).toContain('0.9'); + expect(xml).toContain('https://host.com/docs/hello%20world'); + expect(xml).not.toContain('/drafts/preview'); + expect(xml).not.toContain('/api/_analog/pages/products'); + }); + + it('should support predicate exclude rules and transform returning false', async () => { + existsSyncMock.mockReturnValue(true); + + await buildSitemap( + config, + { + host: 'https://host.com', + exclude: [async (entry) => entry.route === '/private'], + transform: (entry) => + entry.route === '/skip-me' + ? false + : { + route: entry.route, + }, + }, + ['/public', '/private', '/skip-me'], + '/tmp/analog/public', + {}, + ); + + const xml = writeFileSyncMock.mock.calls[0]?.[1] ?? ''; + expect(xml).toContain('https://host.com/public'); + expect(xml).not.toContain('/private'); + expect(xml).not.toContain('/skip-me'); + expect(xml).not.toContain(''); + }); + + it('should resolve callable per-route sitemap metadata', async () => { + existsSyncMock.mockReturnValue(true); + + await buildSitemap( + config, + { host: 'https://host.com/' }, + ['/blog'], + '/tmp/analog/public', + { + '/blog': () => ({ + lastmod: '2024-04-01', + changefreq: 'daily', + }), + }, + ); + + const xml = writeFileSyncMock.mock.calls[0]?.[1] ?? ''; + expect(xml).toContain('https://host.com/blog'); + expect(xml).toContain('2024-04-01'); + expect(xml).toContain('daily'); + }); + + it('should filter internal routes when a custom api prefix is configured', async () => { + existsSyncMock.mockReturnValue(true); + + await buildSitemap( + config, + { host: 'https://host.com' }, + ['/shop', '/functions/_analog/pages/shop'], + '/tmp/analog/public', + {}, + { apiPrefix: 'functions' }, + ); + + const xml = writeFileSyncMock.mock.calls[0]?.[1] ?? ''; + expect(xml).toContain('https://host.com/shop'); + expect(xml).not.toContain('/functions/_analog/pages/shop'); + }); + + it('should create the output directory when it does not exist', async () => { + existsSyncMock.mockReturnValue(false); + + await buildSitemap( + config, + { host: 'https://host.com' }, + ['/'], + '/tmp/generated/public', + {}, + ); + + expect(mkdirSyncMock).toHaveBeenCalledWith('/tmp/generated/public', { + recursive: true, + }); + expect(writeFileSyncMock).toHaveBeenCalled(); + }); + + it('should refuse to write to the current working directory', async () => { + existsSyncMock.mockReturnValue(true); + const errorSpy = vi + .spyOn(console, 'error') + .mockImplementation(() => undefined); + + await buildSitemap(config, { host: 'https://host.com' }, ['/'], '', {}); + + expect(writeFileSyncMock).not.toHaveBeenCalled(); + expect(errorSpy).toHaveBeenCalledWith( + expect.stringContaining('Unable to write file at'), + expect.any(Error), + ); + }); + + it('should reject invalid sitemap hosts before writing output', async () => { + await expect( + buildSitemap( + config, + { host: 'not-a-valid-url' }, + ['/'], + '/tmp/analog/public', + {}, + ), + ).rejects.toThrow(); + + expect(writeFileSyncMock).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/platform/src/lib/nitro/build-sitemap.ts b/packages/platform/src/lib/nitro/build-sitemap.ts new file mode 100644 index 000000000..cb329b93d --- /dev/null +++ b/packages/platform/src/lib/nitro/build-sitemap.ts @@ -0,0 +1,372 @@ +import { existsSync, mkdirSync, writeFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { create } from 'xmlbuilder2'; +import type { XMLBuilder } from 'xmlbuilder2/lib/interfaces'; +import { UserConfig } from 'vite'; +import type { + I18nPrerenderOptions, + PrerenderSitemapConfig, + SitemapConfig, + SitemapEntry, + SitemapExcludeRule, + SitemapRouteDefinition, + SitemapRouteInput, + SitemapRouteSource, +} from './types.js'; + +type RouteSitemapConfig = + | PrerenderSitemapConfig + | (() => PrerenderSitemapConfig) + | undefined; + +export type PagesJson = SitemapEntry; + +export interface BuildSitemapOptions { + apiPrefix?: string; +} + +export async function buildSitemap( + _config: UserConfig, + sitemapConfig: SitemapConfig, + routes: (string | undefined)[] | (() => Promise<(string | undefined)[]>), + outputDir: string, + routeSitemaps: Record, + buildOptions: BuildSitemapOptions = {}, +): Promise { + const host = normalizeSitemapHost(sitemapConfig.host); + const routeList = await collectSitemapRoutes(routes, sitemapConfig.include); + const sitemapData = await resolveSitemapEntries( + routeList, + host, + routeSitemaps, + sitemapConfig, + buildOptions, + ); + + if (!sitemapData.length) { + return; + } + + const sitemap = createXml('urlset'); + + for (const item of sitemapData) { + const page = sitemap.ele('url'); + page.ele('loc').txt(item.loc); + + if (item.lastmod) { + page.ele('lastmod').txt(item.lastmod); + } + + if (item.changefreq) { + page.ele('changefreq').txt(item.changefreq); + } + + if (item.priority !== undefined) { + page.ele('priority').txt(String(item.priority)); + } + } + + const resolvedOutputDir = resolve(outputDir); + const mapPath = resolve(resolvedOutputDir, 'sitemap.xml'); + try { + if (!resolvedOutputDir || resolvedOutputDir === resolve()) { + throw new Error( + 'Refusing to write the sitemap to the current working directory. Expected the Nitro public output directory instead.', + ); + } + + if (!existsSync(resolvedOutputDir)) { + mkdirSync(resolvedOutputDir, { recursive: true }); + } + console.log(`Writing sitemap at ${mapPath}`); + writeFileSync(mapPath, sitemap.end({ prettyPrint: true })); + } catch (e) { + console.error(`Unable to write file at ${mapPath}`, e); + } +} + +async function resolveSitemapEntries( + routes: SitemapRouteInput[], + host: string, + routeSitemaps: Record, + sitemapConfig: SitemapConfig, + buildOptions: BuildSitemapOptions, +): Promise { + const defaults = sitemapConfig.defaults ?? {}; + const seen = new Set(); + const entries: SitemapEntry[] = []; + + for (const route of routes) { + const entry = await toSitemapEntry( + route, + host, + routeSitemaps, + defaults, + sitemapConfig.transform, + ); + + if (!entry) { + continue; + } + + if ( + isInternalSitemapRoute(entry.route, buildOptions.apiPrefix) || + (await isExcludedSitemapRoute(entry, sitemapConfig.exclude)) + ) { + continue; + } + + if (seen.has(entry.loc)) { + continue; + } + + seen.add(entry.loc); + entries.push(entry); + } + + return entries; +} + +async function toSitemapEntry( + route: SitemapRouteInput, + host: string, + routeSitemaps: Record, + defaults: PrerenderSitemapConfig, + transform: SitemapConfig['transform'], +): Promise { + const normalizedRoute = normalizeSitemapRoute( + typeof route === 'string' ? route : route?.route, + ); + if (!normalizedRoute) { + return undefined; + } + + const baseEntry = createSitemapEntry( + { + ...defaults, + ...resolveRouteSitemapConfig(routeSitemaps[normalizedRoute]), + ...(typeof route === 'object' ? route : {}), + route: normalizedRoute, + }, + host, + ); + + if (!transform) { + return baseEntry; + } + + const transformed = await transform(baseEntry); + if (!transformed) { + return undefined; + } + + return createSitemapEntry( + { + ...baseEntry, + ...transformed, + }, + host, + ); +} + +function createSitemapEntry( + routeDefinition: SitemapRouteDefinition, + host: string, +): SitemapEntry { + const route = normalizeSitemapRoute(routeDefinition.route) ?? '/'; + + return { + route, + loc: new URL(route, ensureTrailingSlash(host)).toString(), + lastmod: routeDefinition.lastmod, + changefreq: routeDefinition.changefreq, + priority: routeDefinition.priority, + }; +} + +function resolveRouteSitemapConfig( + config: RouteSitemapConfig, +): PrerenderSitemapConfig { + if (!config) { + return {}; + } + + return typeof config === 'function' ? config() : config; +} + +function normalizeSitemapHost(host: string): string { + const resolvedHost = new URL(host); + resolvedHost.hash = ''; + return resolvedHost.toString(); +} + +function ensureTrailingSlash(host: string): string { + return host.endsWith('/') ? host : `${host}/`; +} + +function normalizeSitemapRoute(route: string | undefined): string | undefined { + if (!route) { + return undefined; + } + + const trimmedRoute = route.trim(); + if (!trimmedRoute) { + return undefined; + } + + const pathWithQuery = trimmedRoute.split('#', 1)[0] ?? ''; + const [pathname, search] = pathWithQuery.split('?', 2); + const normalizedPathname = pathname + ? `/${pathname.replace(/^\/+/, '').replace(/\/{2,}/g, '/')}` + : '/'; + + return search ? `${normalizedPathname}?${search}` : normalizedPathname; +} + +function isInternalSitemapRoute(route: string, apiPrefix = 'api'): boolean { + const normalizedApiPrefix = normalizeSitemapRoute(`/${apiPrefix}`) ?? '/api'; + return ( + route === `${normalizedApiPrefix}/_analog/pages` || + route.startsWith(`${normalizedApiPrefix}/_analog/pages/`) + ); +} + +async function isExcludedSitemapRoute( + entry: SitemapEntry, + excludeRules: SitemapExcludeRule[] | undefined, +): Promise { + if (!excludeRules?.length) { + return false; + } + + for (const rule of excludeRules) { + if (typeof rule === 'function') { + if (await rule(entry)) { + return true; + } + continue; + } + + if (rule instanceof RegExp) { + if (rule.test(entry.route)) { + return true; + } + continue; + } + + if (toGlobRegExp(rule).test(entry.route)) { + return true; + } + } + + return false; +} + +function toGlobRegExp(pattern: string): RegExp { + const doubleStarToken = '__ANALOG_DOUBLE_STAR__'; + const singleStarToken = '__ANALOG_SINGLE_STAR__'; + const escapedPattern = pattern + .replace(/\*\*/g, doubleStarToken) + .replace(/\*/g, singleStarToken) + .replace(/[.+^${}()|[\]\\]/g, '\\$&'); + const regexPattern = escapedPattern + .replace(new RegExp(doubleStarToken, 'g'), '.*') + .replace(new RegExp(singleStarToken, 'g'), '[^/]*'); + return new RegExp(`^${regexPattern}$`); +} + +async function collectSitemapRoutes( + routes: (string | undefined)[] | (() => Promise<(string | undefined)[]>), + include?: SitemapRouteSource, +): Promise { + const routeList = await resolveRouteInputs(routes); + const includedRoutes = include ? await resolveRouteInputs(include) : []; + return [...routeList, ...includedRoutes]; +} + +async function resolveRouteInputs( + routes: + | SitemapRouteSource + | (string | undefined)[] + | (() => Promise<(string | undefined)[]>), +): Promise { + let routeList: SitemapRouteInput[]; + + if (typeof routes === 'function') { + routeList = await routes(); + } else if (Array.isArray(routes)) { + routeList = routes; + } else { + routeList = []; + } + + return routeList.filter(Boolean); +} + +/** + * Generates hreflang alternate URLs for a given page URL. + * For a URL like `https://example.com/fr/about`, it produces alternates + * for all configured locales. + */ +export function getHreflangAlternates( + pageUrl: string, + host: string, + i18n: I18nPrerenderOptions, +): { locale: string; href: string }[] { + const alternates: { locale: string; href: string }[] = []; + const normalizedHost = host.replace(/\/+$/, ''); + + const path = pageUrl.replace(normalizedHost, ''); + const basePath = stripLocalePrefix(path, i18n.locales); + + for (const locale of i18n.locales) { + const localizedPath = + basePath === '/' || basePath === '' + ? `/${locale}` + : `/${locale}${basePath}`; + alternates.push({ + locale, + href: `${normalizedHost}${localizedPath}`, + }); + } + + const defaultPath = + basePath === '/' || basePath === '' + ? `/${i18n.defaultLocale}` + : `/${i18n.defaultLocale}${basePath}`; + alternates.push({ + locale: 'x-default', + href: `${normalizedHost}${defaultPath}`, + }); + + return alternates; +} + +/** + * Strips a locale prefix from a URL path. + * E.g., '/fr/about' -> '/about', '/en' -> '/' + */ +export function stripLocalePrefix(path: string, locales: string[]): string { + const segments = path.split('/').filter(Boolean); + if (segments.length > 0 && locales.includes(segments[0])) { + const rest = segments.slice(1).join('/'); + return rest ? `/${rest}` : '/'; + } + return path || '/'; +} + +function createXml( + elementName: 'urlset' | 'sitemapindex', + includeXhtml = false, +): XMLBuilder { + const attrs: Record = { + xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9', + }; + if (includeXhtml) { + attrs['xmlns:xhtml'] = 'https://www.w3.org/1999/xhtml'; + } + + return create({ version: '1.0', encoding: 'UTF-8' }) + .ele(elementName, attrs) + .com(`This file was automatically generated by Analog.`); +} diff --git a/packages/platform/src/lib/nitro/debug.ts b/packages/platform/src/lib/nitro/debug.ts new file mode 100644 index 000000000..29643cb3b --- /dev/null +++ b/packages/platform/src/lib/nitro/debug.ts @@ -0,0 +1,8 @@ +import { createDebug } from 'obug'; + +export const debugNitro = createDebug('analog:nitro'); +export const debugSsr = createDebug('analog:nitro:ssr'); +export const debugPrerender = createDebug('analog:nitro:prerender'); + +/** All Nitro-related debug instances, for external wrapping (e.g. file logging). */ +export const nitroDebugInstances = [debugNitro, debugSsr, debugPrerender]; diff --git a/packages/platform/src/lib/nitro/get-content-files.spec.ts b/packages/platform/src/lib/nitro/get-content-files.spec.ts new file mode 100644 index 000000000..473cbe0d9 --- /dev/null +++ b/packages/platform/src/lib/nitro/get-content-files.spec.ts @@ -0,0 +1,77 @@ +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; + +import { getMatchingContentFilesWithFrontMatter } from './get-content-files'; + +describe('getMatchingContentFilesWithFrontMatter', () => { + let workspaceRoot: string; + const rootDir = '.'; + const contentDir = '/src/content/docs'; + + beforeEach(() => { + workspaceRoot = mkdtempSync(join(tmpdir(), 'analog-content-')); + mkdirSync(join(workspaceRoot, 'src/content/docs/erste-schritte'), { + recursive: true, + }); + mkdirSync(join(workspaceRoot, 'src/content/docs/assets'), { + recursive: true, + }); + writeFileSync( + join(workspaceRoot, 'src/content/docs/intro.md'), + '---\ntitle: Intro\n---\n# Intro', + ); + writeFileSync( + join(workspaceRoot, 'src/content/docs/erste-schritte/willkommen.md'), + '---\ntitle: Willkommen\n---\n# Willkommen', + ); + writeFileSync( + join(workspaceRoot, 'src/content/docs/assets/hochladen.md'), + '---\ntitle: Hochladen\n---\n# Hochladen', + ); + }); + + afterEach(() => { + rmSync(workspaceRoot, { recursive: true, force: true }); + }); + + it('returns only top-level files by default', () => { + const files = getMatchingContentFilesWithFrontMatter( + workspaceRoot, + rootDir, + contentDir, + ); + + expect(files.map((f) => f.name).sort()).toEqual(['intro']); + }); + + it('returns nested files when recursive is enabled', () => { + const files = getMatchingContentFilesWithFrontMatter( + workspaceRoot, + rootDir, + contentDir, + true, + ); + + expect(files.map((f) => f.name).sort()).toEqual([ + 'hochladen', + 'intro', + 'willkommen', + ]); + }); + + it('exposes the directory relative to contentDir as relativePath', () => { + const files = getMatchingContentFilesWithFrontMatter( + workspaceRoot, + rootDir, + contentDir, + true, + ); + + const byName = Object.fromEntries(files.map((f) => [f.name, f])); + expect(byName['intro'].relativePath).toBe(''); + expect(byName['willkommen'].relativePath).toBe('erste-schritte'); + expect(byName['hochladen'].relativePath).toBe('assets'); + }); +}); diff --git a/packages/platform/src/lib/nitro/get-content-files.ts b/packages/platform/src/lib/nitro/get-content-files.ts new file mode 100644 index 000000000..eb6925f74 --- /dev/null +++ b/packages/platform/src/lib/nitro/get-content-files.ts @@ -0,0 +1,75 @@ +import { readFileSync } from 'node:fs'; +import { basename, join, relative, resolve } from 'node:path'; +import { normalizePath } from 'vite'; +import { createRequire } from 'node:module'; +import { globSync } from 'tinyglobby'; + +import type { PrerenderContentFile } from './types.js'; + +const require = createRequire(import.meta.url); + +/** + * Discovers content files with front matter and extracts metadata for prerendering. + * + * Globs the resolved content directory, reads each match, parses YAML/TOML + * front matter via `front-matter`, and returns `PrerenderContentFile` + * entries used by `PrerenderContentDir.transform()` to map files to routes. + * + * When `recursive` is enabled, `relativePath` on each result captures the + * file's directory relative to `contentDir` so transforms can disambiguate + * identically-named files across subdirectories. + */ +export function getMatchingContentFilesWithFrontMatter( + workspaceRoot: string, + rootDir: string, + glob: string, + recursive = false, +): PrerenderContentFile[] { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const fm = require('front-matter'); + + const root = normalizePath(resolve(workspaceRoot, rootDir)); + const resolvedDir = normalizePath(relative(root, join(root, glob))); + + const pattern = recursive + ? `${root}/${resolvedDir}/**/*` + : `${root}/${resolvedDir}/*`; + const contentFiles: string[] = globSync([pattern], { + dot: true, + absolute: true, + onlyFiles: true, + }); + + const dirPrefix = `${root}/${resolvedDir}`; + + const mappedFilesWithFm: PrerenderContentFile[] = contentFiles.map((f) => { + const fileContents = readFileSync(f, 'utf8'); + const raw = fm(fileContents); + + // Split the basename on the LAST dot so file names that contain + // additional dots (e.g. locale suffixes like `post.en.md`) keep the + // inner dots in `name` and only the trailing segment becomes the + // extension. The previous regex stopped at the first dot and + // discarded everything between it and the extension. + const filename = basename(normalizePath(f)); + const dot = filename.lastIndexOf('.'); + const name = dot === -1 ? filename : filename.slice(0, dot); + const extension = dot === -1 ? '' : filename.slice(dot + 1); + + const relativeDir = normalizePath(relative(dirPrefix, f)); + const lastSlash = relativeDir.lastIndexOf('/'); + const relativePath = + lastSlash === -1 ? '' : relativeDir.slice(0, lastSlash); + + return { + name, + extension, + path: resolvedDir, + attributes: raw.attributes as { attributes: Record }, + content: fileContents, + relativePath, + }; + }); + + return mappedFilesWithFm; +} diff --git a/packages/platform/src/lib/nitro/get-page-handlers.ts b/packages/platform/src/lib/nitro/get-page-handlers.ts new file mode 100644 index 000000000..e69f65dfe --- /dev/null +++ b/packages/platform/src/lib/nitro/get-page-handlers.ts @@ -0,0 +1,70 @@ +import { resolve } from 'node:path'; +import { globSync } from 'tinyglobby'; + +import type { NitroEventHandler } from 'nitro/types'; +import { normalizePath } from 'vite'; + +type GetHandlersArgs = { + workspaceRoot: string; + sourceRoot: string; + rootDir: string; + additionalPagesDirs?: string[]; + hasAPIDir?: boolean; +}; + +/** + * Discovers and generates Nitro event handlers for server-side page routes. + * + * Discovers all `.server.ts` files under `app/pages/**` and any additional + * pages directories, then maps each file to a Nitro route pattern under + * `/_analog/pages/...` (prefixed with `/api` when the project has an API dir). + * + * Route transformation examples: + * - index.server.ts → /_analog/pages/index + * - users/[id].server.ts → /_analog/pages/users/:id + * - products/[...slug].server.ts → /_analog/pages/products/**:slug + * - (auth)/login.server.ts → /_analog/pages/-auth-/login + */ +export function getPageHandlers({ + workspaceRoot, + sourceRoot, + rootDir, + additionalPagesDirs, + hasAPIDir, +}: GetHandlersArgs): NitroEventHandler[] { + const root = normalizePath(resolve(workspaceRoot, rootDir)); + + const endpointFiles: string[] = globSync( + [ + `${root}/${sourceRoot}/app/pages/**/*.server.ts`, + ...(additionalPagesDirs || []).map( + (dir) => `${workspaceRoot}${dir}/**/*.server.ts`, + ), + ], + { dot: true, absolute: true }, + ); + + const handlers: NitroEventHandler[] = endpointFiles.map((endpointFile) => { + const normalized = normalizePath(endpointFile); + const route = normalized + .replace(/^(.*?)\/pages/, '/pages') + .replace(/\.server\.ts$/, '') + .replace(/\[\.{3}(.+)\]/g, '**:$1') + .replace(/\[\.{3}(\w+)\]/g, '**:$1') + // Strip Angular Router group syntax `(group)` from any segment, not + // just trailing ones. Routes like `(auth)/login.server.ts` need to + // become `/-auth-/login`, otherwise the literal parens leak through + // and the handler is mounted under an invalid Nitro path. + .replace(/\/\(([^/]+)\)/g, '/-$1-') + .replace(/\[(\w+)\]/g, ':$1') + .replace(/\./g, '/'); + + return { + handler: endpointFile, + route: `${hasAPIDir ? '/api' : ''}/_analog${route}`, + lazy: true, + }; + }); + + return handlers; +} diff --git a/packages/platform/src/lib/nitro/i18n-prerender.spec.ts b/packages/platform/src/lib/nitro/i18n-prerender.spec.ts new file mode 100644 index 000000000..b1ad7f33f --- /dev/null +++ b/packages/platform/src/lib/nitro/i18n-prerender.spec.ts @@ -0,0 +1,186 @@ +import { describe, expect, it } from 'vitest'; +import { + expandRoutesWithLocales, + detectLocaleFromRoute, + setHtmlLang, +} from './i18n-prerender'; +import { getHreflangAlternates, stripLocalePrefix } from './build-sitemap'; +import { I18nPrerenderOptions } from './types'; + +const i18n: I18nPrerenderOptions = { + defaultLocale: 'en', + locales: ['en', 'fr', 'de'], +}; + +describe('expandRoutesWithLocales', () => { + it('should expand a single route to all locales', () => { + const result = expandRoutesWithLocales(['/about'], i18n); + + expect(result).toContain('/en/about'); + expect(result).toContain('/fr/about'); + expect(result).toContain('/de/about'); + }); + + it('should handle the root route', () => { + const result = expandRoutesWithLocales(['/'], i18n); + + expect(result).toContain('/en'); + expect(result).toContain('/fr'); + expect(result).toContain('/de'); + }); + + it('should keep the unprefixed root route for the default locale', () => { + const result = expandRoutesWithLocales(['/'], i18n); + + expect(result).toContain('/'); + }); + + it('should not prefix API routes', () => { + const result = expandRoutesWithLocales( + ['/about', '/api/v1/users', '/api/_analog/pages/about'], + i18n, + ); + + expect(result).toContain('/api/v1/users'); + expect(result).toContain('/api/_analog/pages/about'); + expect(result).not.toContain('/en/api/v1/users'); + }); + + it('should expand multiple routes', () => { + const result = expandRoutesWithLocales(['/about', '/contact'], i18n); + + expect(result).toContain('/en/about'); + expect(result).toContain('/fr/about'); + expect(result).toContain('/de/about'); + expect(result).toContain('/en/contact'); + expect(result).toContain('/fr/contact'); + expect(result).toContain('/de/contact'); + }); + + it('should not duplicate routes', () => { + const result = expandRoutesWithLocales(['/about'], i18n); + const aboutRoutes = result.filter((r) => r === '/about'); + + expect(aboutRoutes.length).toBeLessThanOrEqual(1); + }); +}); + +describe('detectLocaleFromRoute', () => { + it('should detect locale from route prefix', () => { + expect(detectLocaleFromRoute('/fr/about', i18n)).toBe('fr'); + expect(detectLocaleFromRoute('/de/contact', i18n)).toBe('de'); + expect(detectLocaleFromRoute('/en', i18n)).toBe('en'); + }); + + it('should return defaultLocale for routes without locale prefix', () => { + expect(detectLocaleFromRoute('/about', i18n)).toBe('en'); + expect(detectLocaleFromRoute('/', i18n)).toBe('en'); + }); + + it('should not match non-configured locales', () => { + expect(detectLocaleFromRoute('/es/about', i18n)).toBe('en'); + }); +}); + +describe('setHtmlLang', () => { + it('should add lang attribute to html tag', () => { + const html = ''; + const result = setHtmlLang(html, 'fr'); + + expect(result).toBe(''); + }); + + it('should replace existing lang attribute', () => { + const html = ''; + const result = setHtmlLang(html, 'de'); + + expect(result).toBe(''); + }); + + it('should preserve other attributes on html tag', () => { + const html = ''; + const result = setHtmlLang(html, 'fr'); + + expect(result).toContain('lang="fr"'); + expect(result).toContain('class="dark"'); + expect(result).toContain('dir="ltr"'); + }); +}); + +describe('getHreflangAlternates', () => { + it('should generate alternates for all locales plus x-default', () => { + const alternates = getHreflangAlternates( + 'https://example.com/fr/about', + 'https://example.com', + i18n, + ); + + expect(alternates).toContainEqual({ + locale: 'en', + href: 'https://example.com/en/about', + }); + expect(alternates).toContainEqual({ + locale: 'fr', + href: 'https://example.com/fr/about', + }); + expect(alternates).toContainEqual({ + locale: 'de', + href: 'https://example.com/de/about', + }); + expect(alternates).toContainEqual({ + locale: 'x-default', + href: 'https://example.com/en/about', + }); + }); + + it('should handle root locale paths', () => { + const alternates = getHreflangAlternates( + 'https://example.com/fr', + 'https://example.com', + i18n, + ); + + expect(alternates).toContainEqual({ + locale: 'en', + href: 'https://example.com/en', + }); + expect(alternates).toContainEqual({ + locale: 'fr', + href: 'https://example.com/fr', + }); + }); + + it('should handle host with trailing slash', () => { + const alternates = getHreflangAlternates( + 'https://example.com/en/about', + 'https://example.com/', + i18n, + ); + + expect(alternates).toContainEqual({ + locale: 'en', + href: 'https://example.com/en/about', + }); + }); +}); + +describe('stripLocalePrefix', () => { + it('should strip locale from path', () => { + expect(stripLocalePrefix('/fr/about', ['en', 'fr'])).toBe('/about'); + expect(stripLocalePrefix('/en/products/123', ['en', 'fr'])).toBe( + '/products/123', + ); + }); + + it('should return root for locale-only path', () => { + expect(stripLocalePrefix('/fr', ['en', 'fr'])).toBe('/'); + }); + + it('should return path unchanged if no locale prefix', () => { + expect(stripLocalePrefix('/about', ['en', 'fr'])).toBe('/about'); + }); + + it('should return root for empty path', () => { + expect(stripLocalePrefix('', ['en', 'fr'])).toBe('/'); + }); +}); diff --git a/packages/platform/src/lib/nitro/i18n-prerender.ts b/packages/platform/src/lib/nitro/i18n-prerender.ts new file mode 100644 index 000000000..388d4b2a0 --- /dev/null +++ b/packages/platform/src/lib/nitro/i18n-prerender.ts @@ -0,0 +1,101 @@ +import type { PrerenderRoute } from 'nitro/types'; +import type { I18nPrerenderOptions } from './types.js'; + +/** + * Expands a list of routes to include locale-prefixed variants. + * + * For each route and each locale, generates a prefixed route: + * '/' + locale + route + * + * The default locale's routes are included both with and without the prefix + * so that `/about` and `/en/about` both render. + */ +export function expandRoutesWithLocales( + routes: string[], + i18n: I18nPrerenderOptions, +): string[] { + const expanded: string[] = []; + + for (const route of routes) { + // Skip locale expansion for internal analog endpoints and API routes. + // `startsWith('/api/')` alone misses the bare `/api` path, which + // would otherwise get locale-prefixed and produce phantom routes like + // `/en/api`. + if ( + route.includes('/_analog/') || + route === '/api' || + route.startsWith('/api/') + ) { + expanded.push(route); + continue; + } + + for (const locale of i18n.locales) { + const prefix = `/${locale}`; + const localizedRoute = route === '/' ? prefix : `${prefix}${route}`; + expanded.push(localizedRoute); + } + + if (!expanded.includes(route)) { + expanded.push(route); + } + } + + return expanded; +} + +/** + * Creates a post-rendering hook that injects the `lang` attribute + * into the `` tag of prerendered pages based on the route's + * locale prefix. + */ +export function createI18nPostRenderingHook( + i18n: I18nPrerenderOptions, +): (route: PrerenderRoute) => Promise { + return async (route: PrerenderRoute) => { + if (!route.contents || typeof route.contents !== 'string') { + return; + } + + const locale = detectLocaleFromRoute(route.route, i18n); + if (!locale) { + return; + } + + route.contents = setHtmlLang(route.contents, locale); + }; +} + +/** + * Detects the locale from a prerendered route path by checking + * the first path segment against the configured locales. + */ +export function detectLocaleFromRoute( + route: string, + i18n: I18nPrerenderOptions, +): string { + const segments = route.split('/').filter(Boolean); + const firstSegment = segments[0]; + + if (firstSegment && i18n.locales.includes(firstSegment)) { + return firstSegment; + } + + return i18n.defaultLocale; +} + +/** + * Sets the `lang` attribute on the `` tag in an HTML string. + * If a `lang` attribute already exists, it is replaced. + * If no `lang` attribute exists, it is added. + */ +export function setHtmlLang(html: string, locale: string): string { + if (/]*\slang\s*=\s*["'][^"']*["']/i.test(html)) { + return html.replace( + /(]*\s)lang\s*=\s*["'][^"']*["']/i, + `$1lang="${locale}"`, + ); + } + + return html.replace(/ { + const plugin = pageEndpointsPlugin(); + + it('uses Nitro runtime $fetch instead of a private nitro import', async () => { + const result = await plugin.transform?.( + `export const load = () => ({ ok: true });`, + '/src/app/pages/index.server.ts', + ); + + expect(result).toBeDefined(); + expect(result?.code).toContain( + 'export default defineHandler(async(event) => {', + ); + expect(result?.code).toContain(`import { createFetch } from 'ofetch';`); + expect(result?.code).toContain('fetchWithEvent'); + expect(result?.code).toContain('const serverFetch = createFetch'); + expect(result?.code).toContain('fetch: serverFetch'); + expect(result?.code).not.toContain(`nitro/deps/ofetch`); + }); + + it('generates a default load when only action is exported', async () => { + const result = await plugin.transform?.( + `export const action = () => ({ saved: true });`, + '/src/app/pages/index.server.ts', + ); + + expect(result).toBeDefined(); + expect(result?.code).toContain('export const load = () =>'); + expect(result?.code).toContain( + 'export const action = () => ({ saved: true })', + ); + }); + + it('uses both exports when load and action are provided', async () => { + const result = await plugin.transform?.( + `export const load = () => ({ ok: true });\nexport const action = () => ({ saved: true });`, + '/src/app/pages/index.server.ts', + ); + + expect(result).toBeDefined(); + expect(result?.code).toContain('export const load = () => ({ ok: true })'); + expect(result?.code).toContain( + 'export const action = () => ({ saved: true })', + ); + expect(result?.code).not.toContain('return {};'); + }); + + it('generates default load and action when neither is exported', async () => { + const result = await plugin.transform?.( + `export const helper = () => 42;`, + '/src/app/pages/index.server.ts', + ); + + expect(result).toBeDefined(); + expect(result?.code).toContain('export const load = () =>'); + expect(result?.code).toContain('export const action = () =>'); + const stubs = (result?.code.match(/return \{\};/g) || []).length; + expect(stubs).toBe(2); + }); + + it('skips files that are not .server.ts', async () => { + const result = await plugin.transform?.( + `export const load = () => ({ ok: true });`, + '/src/app/pages/index.ts', + ); + + expect(result).toBeUndefined(); + }); + + it('skips .server.ts files outside /pages/', async () => { + const result = await plugin.transform?.( + `export const load = () => ({ ok: true });`, + '/src/app/services/auth.server.ts', + ); + + expect(result).toBeUndefined(); + }); +}); diff --git a/packages/platform/src/lib/nitro/page-endpoints-plugin.ts b/packages/platform/src/lib/nitro/page-endpoints-plugin.ts new file mode 100644 index 000000000..3cf2e3267 --- /dev/null +++ b/packages/platform/src/lib/nitro/page-endpoints-plugin.ts @@ -0,0 +1,98 @@ +import { parseSync } from 'oxc-parser'; +import { normalizePath } from 'vite'; +import { SERVER_FETCH_FACTORY_SNIPPET } from './renderers.js'; + +export function pageEndpointsPlugin() { + return { + name: 'analogjs-platform-rollup-page-endpoint', + async transform( + _code: string, + id: string, + ): Promise<{ code: string; map: null } | undefined> { + if (normalizePath(id).includes('/pages/') && id.endsWith('.server.ts')) { + const result = parseSync(id, _code, { + sourceType: 'module', + lang: 'ts', + }); + + const fileExports: string[] = result.module.staticExports.flatMap((e) => + e.entries + .filter((entry) => entry.exportName.name !== null) + .map((entry) => entry.exportName.name as string), + ); + + // In h3 v2 / Nitro v3, event.node is undefined during prerendering + // (which uses the fetch-based pipeline, not Node.js http). We use + // optional chaining so that page endpoints work in both Node.js + // server and fetch-based prerender contexts. + // + // Page loaders expect Nitro-style `$fetch` semantics (parsed data plus + // internal relative-route support), so we construct a request-local + // fetch using `createFetch` from ofetch + `fetchWithEvent` from h3. + const code = ` + import { defineHandler, fetchWithEvent } from 'nitro/h3'; + import { createFetch } from 'ofetch'; + + ${ + fileExports.includes('load') + ? _code + : ` + ${_code} + export const load = () => { + return {}; + }` + } + + ${ + fileExports.includes('action') + ? '' + : ` + export const action = () => { + return {}; + } + ` + } + + export default defineHandler(async(event) => { + ${SERVER_FETCH_FACTORY_SNIPPET} + + if (event.method === 'GET') { + try { + return await load({ + params: event.context.params, + req: event.node?.req, + res: event.node?.res, + fetch: serverFetch, + event + }); + } catch(e) { + console.error(\` An error occurred: \${e}\`) + throw e; + } + } else { + try { + return await action({ + params: event.context.params, + req: event.node?.req, + res: event.node?.res, + fetch: serverFetch, + event + }); + } catch(e) { + console.error(\` An error occurred: \${e}\`) + throw e; + } + } + }); + `; + + return { + code, + map: null, + }; + } + + return; + }, + }; +} diff --git a/packages/platform/src/lib/nitro/post-rendering-hook.spec.ts b/packages/platform/src/lib/nitro/post-rendering-hook.spec.ts new file mode 100644 index 000000000..a9e4439d5 --- /dev/null +++ b/packages/platform/src/lib/nitro/post-rendering-hook.spec.ts @@ -0,0 +1,33 @@ +import type { Nitro } from 'nitro/types'; +import { vi } from 'vitest'; + +import { addPostRenderingHooks } from './post-rendering-hook'; + +describe('postRenderingHook', () => { + const genRoute = { + route: 'test/testRoute', + contents: 'This is a test.', + }; + + const nitroMock = { + hooks: { + hook: vi.fn((name: string, callback: (route: any) => void) => + callback(genRoute), + ), + }, + } as unknown as Nitro; + + const mockFunc1 = vi.fn(); + const mockFunc2 = vi.fn(); + + it('should not attempt to call nitro mocks if no callbacks provided', () => { + addPostRenderingHooks(nitroMock, []); + expect(nitroMock.hooks.hook).not.toHaveBeenCalled(); + }); + + it('should call provided hooks', () => { + addPostRenderingHooks(nitroMock, [mockFunc1, mockFunc2]); + expect(mockFunc1).toHaveBeenCalledWith(genRoute); + expect(mockFunc2).toHaveBeenCalled(); + }); +}); diff --git a/packages/platform/src/lib/nitro/post-rendering-hook.ts b/packages/platform/src/lib/nitro/post-rendering-hook.ts new file mode 100644 index 000000000..4423c6f83 --- /dev/null +++ b/packages/platform/src/lib/nitro/post-rendering-hook.ts @@ -0,0 +1,12 @@ +import type { Nitro, PrerenderRoute } from 'nitro/types'; + +export function addPostRenderingHooks( + nitro: Nitro, + hooks: ((pr: PrerenderRoute) => Promise | void)[], +): void { + for (const hook of hooks) { + nitro.hooks.hook('prerender:generate', async (route: PrerenderRoute) => { + await hook(route); + }); + } +} diff --git a/packages/platform/src/lib/nitro/renderers.spec.ts b/packages/platform/src/lib/nitro/renderers.spec.ts new file mode 100644 index 000000000..b21878a5f --- /dev/null +++ b/packages/platform/src/lib/nitro/renderers.spec.ts @@ -0,0 +1,41 @@ +import { describe, expect, it } from 'vitest'; + +import { apiMiddleware, clientRenderer, ssrRenderer } from './renderers'; + +describe('renderers virtual modules', () => { + it('emits an SSR renderer that serves HTML responses', () => { + const moduleSource = ssrRenderer(); + + expect(moduleSource).toContain("import template from '#analog/index';"); + expect(moduleSource).not.toContain('readFileSync('); + expect(moduleSource).toContain( + "event.res.headers.set('content-type', 'text/html; charset=utf-8');", + ); + expect(moduleSource).toContain( + 'const requestPath = normalizeHtmlRequestUrl(event.path);', + ); + expect(moduleSource).toContain('const req = event.node?.req'); + expect(moduleSource).toContain( + 'const html = await renderer(requestPath, template, { req, res, fetch: serverFetch });', + ); + expect(moduleSource).toContain("import renderer from '#analog/ssr';"); + }); + + it('emits a client renderer that serves HTML responses', () => { + const moduleSource = clientRenderer(); + + expect(moduleSource).toContain("import template from '#analog/index';"); + expect(moduleSource).not.toContain('readFileSync('); + expect(moduleSource).toContain( + "event.res.headers.set('content-type', 'text/html; charset=utf-8');", + ); + }); + + it('uses event-bound forwarding for API middleware', () => { + expect(apiMiddleware).toContain( + "import { defineHandler, fetchWithEvent, proxyRequest } from 'nitro/h3';", + ); + expect(apiMiddleware).toContain('return fetchWithEvent(event, reqUrl'); + expect(apiMiddleware).toContain('return proxyRequest(event, reqUrl);'); + }); +}); diff --git a/packages/platform/src/lib/nitro/renderers.ts b/packages/platform/src/lib/nitro/renderers.ts new file mode 100644 index 000000000..b4b003b4e --- /dev/null +++ b/packages/platform/src/lib/nitro/renderers.ts @@ -0,0 +1,146 @@ +/** + * Code snippet emitted into virtual modules to create a request-scoped + * fetch using ofetch's `createFetch` + h3's `fetchWithEvent`. + * + * Shared between the SSR renderer and page-endpoint virtual modules so + * the fetch-wiring logic stays in sync. + * + * The emitted variable is named `serverFetch` — callers should reference it + * by that name. + */ +export const SERVER_FETCH_FACTORY_SNIPPET = ` + const serverFetch = createFetch({ + fetch: (resource, init) => { + const url = resource instanceof Request ? resource.url : resource.toString(); + return fetchWithEvent(event, url, init); + } + });`; + +/** + * SSR renderer virtual module content. + * + * This code runs inside Nitro's server runtime (Node.js context) where + * event.node is always populated. In h3 v2, event.node is typed as optional, + * so we use h3's first-class event properties (event.path, event.method) where + * possible and apply optional chaining when accessing the Node.js context for + * the Angular renderer which requires raw req/res objects. + * + * h3 v2 idiomatic APIs used: + * - defineHandler (replaces defineEventHandler / eventHandler) + * - event.path (replaces event.node.req.url) + * - getResponseHeader compat shim (still available in h3 v2) + */ +export function ssrRenderer() { + return ` +import { createFetch } from 'ofetch'; +import { defineHandler, fetchWithEvent } from 'nitro/h3'; +// @ts-ignore +import renderer from '#analog/ssr'; +import template from '#analog/index'; + +const normalizeHtmlRequestUrl = (url) => + url.replace(/\\/index\\.html(?=$|[?#])/, '/'); + +export default defineHandler(async (event) => { + event.res.headers.set('content-type', 'text/html; charset=utf-8'); + const noSSR = event.res.headers.get('x-analog-no-ssr'); + const requestPath = normalizeHtmlRequestUrl(event.path); + + if (noSSR === 'true') { + return template; + } + + // event.path is the canonical h3 v2 way to access the request URL. + // event.node?.req and event.node?.res are needed by the Angular SSR renderer + // which operates on raw Node.js request/response objects. + // During prerendering (Nitro v3 fetch-based pipeline), event.node is undefined. + // The Angular renderer requires a req object with at least { headers, url }, + // so we provide a minimal stub to avoid runtime errors in prerender context. + const req = event.node?.req + ? { + ...event.node.req, + url: requestPath, + originalUrl: requestPath, + } + : { + headers: { host: 'localhost' }, + url: requestPath, + originalUrl: requestPath, + connection: {}, + }; + const res = event.node?.res; +${SERVER_FETCH_FACTORY_SNIPPET} + + const html = await renderer(requestPath, template, { req, res, fetch: serverFetch }); + + return html; +});`; +} + +/** + * Client-only renderer virtual module content. + * + * Used when SSR is disabled — simply serves the static index.html template + * for every route, letting the client-side Angular router handle navigation. + */ +export function clientRenderer() { + return ` +import { defineHandler } from 'nitro/h3'; +import template from '#analog/index'; + +export default defineHandler(async (event) => { + event.res.headers.set('content-type', 'text/html; charset=utf-8'); + return template; +}); +`; +} + +/** + * API middleware virtual module content. + * + * Intercepts requests matching the configured API prefix and either: + * - Uses event-bound internal forwarding for GET requests (except .xml routes) + * - Uses request proxying for all other methods to forward the full request + * + * h3 v2 idiomatic APIs used: + * - defineHandler (replaces defineEventHandler / eventHandler) + * - event.path (replaces event.node.req.url) + * - event.method (replaces event.node.req.method) + * - proxyRequest is retained internally because it preserves Nitro route + * matching for event-bound server requests during SSR/prerender + * - Object.fromEntries(event.req.headers.entries()) replaces direct event.node.req.headers access + * + * `fetchWithEvent` keeps the active event context while forwarding to a + * rewritten path, which avoids falling through to the HTML renderer when + * SSR code makes relative API requests. + */ +export const apiMiddleware = ` +import { defineHandler, fetchWithEvent, proxyRequest } from 'nitro/h3'; +import { useRuntimeConfig } from 'nitro/runtime-config'; + +export default defineHandler(async (event) => { + const prefix = useRuntimeConfig().prefix; + const apiPrefix = \`\${prefix}/\${useRuntimeConfig().apiPrefix}\`; + + // Match the configured prefix as a full path segment. A bare + // startsWith would false-match /apiary against an apiPrefix of /api. + if ( + event.path === apiPrefix || + event.path?.startsWith(apiPrefix + '/') + ) { + const reqUrl = event.path?.replace(apiPrefix, ''); + + if ( + event.method === 'GET' && + // in the case of XML routes, we want to proxy the request so that nitro gets the correct headers + // and can render the XML correctly as a static asset + !event.path?.endsWith('.xml') + ) { + return fetchWithEvent(event, reqUrl, { + headers: Object.fromEntries(event.req.headers.entries()), + }); + } + + return proxyRequest(event, reqUrl); + } +});`; diff --git a/packages/platform/src/lib/nitro/types.ts b/packages/platform/src/lib/nitro/types.ts new file mode 100644 index 000000000..706105539 --- /dev/null +++ b/packages/platform/src/lib/nitro/types.ts @@ -0,0 +1,165 @@ +import type { PrerenderRoute } from 'nitro/types'; + +export interface I18nPrerenderOptions { + /** + * The default/source locale for the application. + */ + defaultLocale: string; + + /** + * List of supported locale identifiers. + * Each route will be prerendered once per locale with a locale prefix. + */ + locales: string[]; +} + +export interface PrerenderOptions { + /** + * Add additional routes to prerender through crawling page links. + */ + discover?: boolean; + + /** + * List of routes to prerender resolved statically or dynamically. + */ + routes?: + | (string | PrerenderContentDir | PrerenderRouteConfig)[] + | (() => Promise< + (string | PrerenderContentDir | PrerenderRouteConfig | undefined)[] + >); + sitemap?: SitemapConfig; + /** List of functions that run for each route after pre-rendering is complete. */ + postRenderingHooks?: ((routes: PrerenderRoute) => Promise)[]; +} + +export type SitemapPriority = number | `${number}`; + +export interface SitemapRouteDefinition { + route: string; + lastmod?: string; + changefreq?: + | 'always' + | 'hourly' + | 'daily' + | 'weekly' + | 'monthly' + | 'yearly' + | 'never'; + priority?: SitemapPriority; +} + +export interface SitemapEntry extends SitemapRouteDefinition { + loc: string; +} + +export type SitemapRouteInput = string | SitemapRouteDefinition | undefined; +export type SitemapRouteSource = + | SitemapRouteInput[] + | (() => Promise); +export type SitemapExcludeRule = + | string + | RegExp + | ((entry: SitemapEntry) => boolean | Promise); +export type SitemapTransform = ( + entry: SitemapEntry, +) => SitemapRouteDefinition | false | Promise; + +export interface SitemapConfig { + host: string; + include?: SitemapRouteSource; + exclude?: SitemapExcludeRule[]; + defaults?: PrerenderSitemapConfig; + transform?: SitemapTransform; +} + +export interface PrerenderContentDir { + /** + * The directory where files should be grabbed from. + * @example `/src/contents/blog` + */ + contentDir: string; + /** + * Transform the matching content files path into a route. + * The function is called for each matching content file within the specified contentDir. + * @param file information of the matching file (`path`, `name`, `extension`, `attributes`, `content`) + * @returns a string with the route should be returned (e. g. `/blog/`) or the value `false`, when the route should not be prerendered. + */ + transform: (file: PrerenderContentFile) => string | false; + + /** + * Customize the sitemap definition for the prerendered route + * + * https://www.sitemaps.org/protocol.html#xmlTagDefinitions + */ + sitemap?: + | PrerenderSitemapConfig + | ((file: PrerenderContentFile) => PrerenderSitemapConfig); + + /** + * Output the source markdown content alongside the prerendered route. + * The source file will be accessible at the route path with a .md extension. + * @param file information of the matching file including its content + * @returns the markdown content string to output, or `false` to skip outputting for this file + */ + outputSourceFile?: (file: PrerenderContentFile) => string | false; + + /** + * Recurse into subdirectories of `contentDir` when discovering files. + * When enabled, the matching file's directory relative to `contentDir` + * is exposed via `PrerenderContentFile.relativePath` so transforms can + * disambiguate identically-named files across subdirectories. + * @default false + */ + recursive?: boolean; +} + +/** + * @param path the path to the content file + * @param name the basename of the matching content file without the file extension + * @param extension the file extension + * @param attributes the frontmatter attributes extracted from the frontmatter section of the file + * @param content the raw file content including frontmatter + * @param relativePath when `recursive` is enabled, the directory of the file relative to `contentDir` (empty string for files at the top level) + * @returns a string with the route should be returned (e. g. `/blog/`) or the value `false`, when the route should not be prerendered. + */ +export interface PrerenderContentFile { + path: string; + attributes: Record; + name: string; + extension: string; + content: string; + relativePath?: string; +} + +export interface PrerenderSitemapConfig { + lastmod?: string; + changefreq?: + | 'always' + | 'hourly' + | 'daily' + | 'weekly' + | 'monthly' + | 'yearly' + | 'never'; + priority?: SitemapPriority; +} + +export interface PrerenderRouteConfig { + route: string; + /** + * Customize the sitemap definition for the prerendered route + * + * https://www.sitemaps.org/protocol.html#xmlTagDefinitions + */ + sitemap?: PrerenderSitemapConfig | (() => PrerenderSitemapConfig); + /** + * Prerender static data for the prerendered route + */ + staticData?: boolean; + /** + * Path to the source markdown file to output alongside the prerendered route. + * The source file will be accessible at the route path with a .md extension. + * @example 'src/content/overview.md' + */ + outputSourceFile?: string; +} diff --git a/packages/platform/src/lib/options.ts b/packages/platform/src/lib/options.ts index a54b80d72..8729171e5 100644 --- a/packages/platform/src/lib/options.ts +++ b/packages/platform/src/lib/options.ts @@ -1,5 +1,4 @@ -import type { PluginOptions } from '@analogjs/vite-plugin-angular'; -import type { NitroConfig, PrerenderRoute } from 'nitro/types'; +import type { PrerenderRoute } from 'nitro/types'; import type { SitemapConfig, SitemapEntry, @@ -13,7 +12,7 @@ import type { PrerenderContentFile, PrerenderSitemapConfig, PrerenderRouteConfig, -} from '@analogjs/vite-plugin-nitro'; +} from './nitro/types.js'; import type { ContentPluginOptions } from './content-plugin.js'; import type { DebugOption } from './utils/debug.js'; @@ -80,58 +79,29 @@ export interface I18nOptions { export interface Options { ssr?: boolean; - ssrBuildDir?: string; /** * Prerender the static pages without producing the server output. */ static?: boolean; prerender?: PrerenderOptions; entryServer?: string; - /** - * Pass configuration options to the internal `@analogjs/vite-plugin-angular` - * plugin. Set to `false` to disable the internal vite plugin (e.g. when - * using an alternative compiler like `@oxc-angular/vite`). - * - * `vite.build` uses Vite's native config shape and is forwarded to the - * internal Nitro/Vite build pipeline, while the remaining fields are passed - * to `@analogjs/vite-plugin-angular`. - * - * When `false`, the following top-level options are ignored because they - * are only forwarded to the internal Angular plugin: `jit`, - * `disableTypeChecking`, `liveReload`, `inlineStylesExtension`, - * `fileReplacements`, and `include`. - * - * Use this to configure the embedded Angular integration itself, not as the - * primary home for Analog-owned experimental features. - */ - vite?: PluginOptions | false; - nitro?: NitroConfig; apiPrefix?: string; - jit?: boolean; index?: string; workspaceRoot?: string; content?: ContentPluginOptions; /** - * Extension applied for inline styles - */ - inlineStylesExtension?: string; - /** - * Enables Analog's Angular live-reload/HMR pipeline during development/watch mode. - * - * This is separate from Vite's `server.hmr` option, which configures the - * HMR client transport. - * - * Defaults to `true` for watch mode. - */ - liveReload?: boolean; - /** - * Enable debug logging for specific scopes. + * Enable debug logging for the `analog:platform:*` and `analog:nitro:*` + * scopes. * - * - `true` → enables all `analog:*` scopes (platform + angular + nitro) + * - `true` → enables all platform + nitro scopes * - `string[]` → enables listed namespaces * - `{ scopes?, mode? }` → object form with optional `mode: 'build' | 'dev'` * to restrict output to a specific Vite command (omit for both) * + * Angular scopes (`analog:angular:*`) are owned by + * `@analogjs/vite-plugin-angular` — pass `debug` to `angular()` directly + * to enable them. + * * Also responds to the `DEBUG` env var (Node.js) or `localStorage.debug` * (browser), using the `obug` convention. */ @@ -160,41 +130,12 @@ export interface Options { * @default false */ discoverRoutes?: boolean; - /** - * Additional files to include in compilation - */ - include?: string[]; - /** - * Toggles internal API middleware. - * If disabled, a proxy request is used to route /api - * requests to / in the production server build. - */ - useAPIMiddleware?: boolean; - /** - * Disable type checking diagnostics by the Angular compiler - */ - disableTypeChecking?: boolean; /** * Configuration for runtime i18n support. * When set, enables locale detection on SSR and provides * the LOCALE injection token. */ i18n?: I18nOptions; - /** - * Opt into the fast compile path. Skips Angular's template type-checking - * and routes compilation through an internal single-pass transform. - */ - fastCompile?: boolean; - /** - * Compilation output mode used when `fastCompile` is enabled. - * - `'full'` (default): Emit final Ivy definitions for application builds. - * - `'partial'`: Emit partial declarations for library publishing. - */ - fastCompileMode?: 'full' | 'partial'; - /** - * File replacements - */ - fileReplacements?: PluginOptions['fileReplacements']; /** * Experimental features. These APIs are subject to change. * @@ -204,19 +145,6 @@ export interface Options { * a single Analog-first authoring surface. */ experimental?: { - /** - * Use Angular's experimental compilation API. - * - * This is forwarded to `@analogjs/vite-plugin-angular`'s - * `experimental.useAngularCompilationAPI`. - * - * Also accepted at `vite.experimental.useAngularCompilationAPI` - * for backwards compatibility. - * - * Has no effect when `vite` is set to `false`. - */ - useAngularCompilationAPI?: boolean; - /** * Enable typed route table generation for type-safe navigation. * @@ -249,73 +177,6 @@ export interface Options { */ stylePipeline?: StylePipelineOptions | false; }; - - /** - * First-class Tailwind CSS v4 integration for Angular component styles. - * - * Angular's compiler processes component CSS through Vite's `preprocessCSS()`, - * which runs `@tailwindcss/vite` — but each component stylesheet is processed - * in isolation without access to the root Tailwind configuration (prefix, @theme, - * @custom-variant, @plugin definitions). This causes errors like: - * - * "Cannot apply utility class `sa:grid` because the `sa` variant does not exist" - * - * The `tailwindCss` option solves this by auto-injecting a `@reference` directive - * into every component CSS file that uses Tailwind utilities, pointing it to the - * root Tailwind stylesheet so `@tailwindcss/vite` can resolve the full configuration. - * - * @example Basic usage — reference a root Tailwind CSS file: - * ```ts - * import { resolve } from 'node:path'; - * - * angular({ - * tailwindCss: { - * rootStylesheet: resolve(__dirname, 'src/styles/tailwind.css'), - * }, - * }) - * ``` - * - * @example With prefix detection — only inject for files using specific prefixes: - * ```ts - * angular({ - * tailwindCss: { - * rootStylesheet: resolve(__dirname, 'src/styles/tailwind.css'), - * // Only inject @reference into files that use these prefixed classes - * prefixes: ['sa:', 'tw:'], - * }, - * }) - * ``` - * - * @example AnalogJS platform — passed through the `vite` option: - * ```ts - * analog({ - * vite: { - * tailwindCss: { - * rootStylesheet: resolve(__dirname, '../../../libs/meritos/tailwind.config.css'), - * }, - * }, - * }) - * ``` - */ - tailwindCss?: { - /** - * Absolute path to the root Tailwind CSS file that contains `@import "tailwindcss"`, - * `@theme`, `@custom-variant`, and `@plugin` definitions. - * - * A `@reference` directive pointing to this file will be auto-injected into - * component CSS files that use Tailwind utilities. - */ - rootStylesheet: string; - /** - * Optional list of class prefixes to detect (e.g. `['sa:', 'tw:']`). - * When provided, `@reference` is only injected into component CSS files that - * contain at least one of these prefixes. When omitted, `@reference` is injected - * into all component CSS files that contain `@apply` or `@` directives. - * - * @default undefined — inject into all component CSS files with `@apply` - */ - prefixes?: string[]; - }; } export interface TypedRouterOptions { diff --git a/packages/platform/src/lib/platform-plugin.spec.ts b/packages/platform/src/lib/platform-plugin.spec.ts index 6791294ee..079a0ba5c 100644 --- a/packages/platform/src/lib/platform-plugin.spec.ts +++ b/packages/platform/src/lib/platform-plugin.spec.ts @@ -1,8 +1,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; const { - viteNitroPluginSpy, - angularSpy, + analogNitroPluginSpy, ssrBuildPluginSpy, injectHTMLPluginSpy, depsPluginSpy, @@ -16,8 +15,7 @@ const { stylePipelineFactorySpy, stylePipelinePluginSpy, } = vi.hoisted(() => ({ - viteNitroPluginSpy: vi.fn(() => []), - angularSpy: vi.fn(() => []), + analogNitroPluginSpy: vi.fn(() => ({ name: '@analogjs/nitro' })), ssrBuildPluginSpy: vi.fn(() => []), injectHTMLPluginSpy: vi.fn(() => []), depsPluginSpy: vi.fn(() => []), @@ -36,16 +34,8 @@ const { stylePipelinePluginSpy: { name: 'community-style-pipeline' }, })); -vi.mock('@analogjs/vite-plugin-nitro', () => ({ - nitro: viteNitroPluginSpy, - default: viteNitroPluginSpy, -})); -vi.mock('@analogjs/vite-plugin-nitro/internal', () => ({ - debugInstances: [], -})); -vi.mock('@analogjs/vite-plugin-angular', () => ({ - angular: angularSpy, - default: angularSpy, +vi.mock('./nitro/analog-nitro-plugin.js', () => ({ + analogNitroPlugin: analogNitroPluginSpy, })); vi.mock('./ssr/ssr-build-plugin.js', () => ({ ssrBuildPlugin: ssrBuildPluginSpy, @@ -94,8 +84,7 @@ import { platformPlugin } from './platform-plugin.js'; describe('platformPlugin', () => { beforeEach(() => { vi.clearAllMocks(); - viteNitroPluginSpy.mockReturnValue([]); - angularSpy.mockReturnValue([]); + analogNitroPluginSpy.mockReturnValue({ name: '@analogjs/nitro' }); ssrBuildPluginSpy.mockReturnValue([]); injectHTMLPluginSpy.mockReturnValue([]); depsPluginSpy.mockReturnValue([]); @@ -112,7 +101,9 @@ describe('platformPlugin', () => { it('defaults ssr to true and passes that value to the composed plugins', () => { platformPlugin(); - expect(viteNitroPluginSpy).toHaveBeenCalledWith({ ssr: true }, undefined); + expect(analogNitroPluginSpy).toHaveBeenCalledWith( + expect.objectContaining({ ssr: true }), + ); expect(ssrBuildPluginSpy).toHaveBeenCalled(); expect(injectHTMLPluginSpy).toHaveBeenCalled(); }); @@ -120,68 +111,13 @@ describe('platformPlugin', () => { it('passes through ssr false without wiring SSR-only plugins', () => { platformPlugin({ ssr: false }); - expect(viteNitroPluginSpy).toHaveBeenCalledWith({ ssr: false }, undefined); + expect(analogNitroPluginSpy).toHaveBeenCalledWith( + expect.objectContaining({ ssr: false }), + ); expect(ssrBuildPluginSpy).not.toHaveBeenCalled(); expect(injectHTMLPluginSpy).not.toHaveBeenCalled(); }); - it('forwards experimental.useAngularCompilationAPI to the Angular vite plugin', () => { - platformPlugin({ - experimental: { - useAngularCompilationAPI: true, - }, - }); - - expect(angularSpy).toHaveBeenCalledWith( - expect.objectContaining({ - experimental: { - useAngularCompilationAPI: true, - }, - }), - ); - }); - - it('does not force semantic type checking onto the dev hot path by default', () => { - platformPlugin(); - - expect(angularSpy).toHaveBeenCalledWith( - expect.objectContaining({ - disableTypeChecking: undefined, - }), - ); - }); - - it('does not call the Angular vite plugin when vite is set to false', () => { - platformPlugin({ vite: false }); - - expect(angularSpy).not.toHaveBeenCalled(); - }); - - it('still includes non-Angular plugins when vite is set to false', () => { - const plugins = platformPlugin({ vite: false }); - - expect(viteNitroPluginSpy).toHaveBeenCalledWith( - expect.objectContaining({ ssr: true }), - undefined, - ); - expect(routeGenerationPluginSpy).toHaveBeenCalled(); - expect(serverModePluginSpy).toHaveBeenCalled(); - expect(clearClientPageEndpointsPluginSpy).toHaveBeenCalled(); - expect(plugins.length).toBeGreaterThan(0); - }); - - it('does not crash when vite is false and useAngularCompilationAPI is true', () => { - const plugins = platformPlugin({ - vite: false, - experimental: { - useAngularCompilationAPI: true, - }, - }); - - expect(angularSpy).not.toHaveBeenCalled(); - expect(plugins.length).toBeGreaterThan(0); - }); - it('merges discovered library routes when discoverRoutes is true', () => { discoverLibraryRoutesSpy.mockReturnValue({ additionalPagesDirs: ['/libs/shared/feature'], @@ -197,11 +133,10 @@ describe('platformPlugin', () => { additionalPagesDirs: ['/libs/shared/feature'], }), ); - expect(viteNitroPluginSpy).toHaveBeenCalledWith( + expect(analogNitroPluginSpy).toHaveBeenCalledWith( expect.objectContaining({ additionalAPIDirs: ['/libs/shared/feature/src/api'], }), - undefined, ); expect(contentPluginSpy).toHaveBeenCalledWith( undefined, @@ -254,26 +189,4 @@ describe('platformPlugin', () => { ); expect(stylePipelineFactorySpy).not.toHaveBeenCalled(); }); - - it('forwards angular style-pipeline plugins to the Angular vite plugin', () => { - const angularStylePipelinePlugin = { - name: 'community-angular-style-pipeline', - }; - - platformPlugin({ - experimental: { - stylePipeline: { - angularPlugins: [angularStylePipelinePlugin], - }, - }, - }); - - expect(angularSpy).toHaveBeenCalledWith( - expect.objectContaining({ - stylePipeline: { - plugins: [angularStylePipelinePlugin], - }, - }), - ); - }); }); diff --git a/packages/platform/src/lib/platform-plugin.ts b/packages/platform/src/lib/platform-plugin.ts index e456c2bbc..97c367f97 100644 --- a/packages/platform/src/lib/platform-plugin.ts +++ b/packages/platform/src/lib/platform-plugin.ts @@ -1,7 +1,5 @@ import { Plugin } from 'vite'; -import viteNitroPlugin from '@analogjs/vite-plugin-nitro'; -import angular from '@analogjs/vite-plugin-angular'; -import { mapValues, union } from 'es-toolkit'; +import { union } from 'es-toolkit'; import { Options } from './options.js'; import { @@ -20,22 +18,12 @@ import { serverModePlugin } from '../server-mode-plugin.js'; import { routeGenerationPlugin } from './route-generation-plugin.js'; import { resolveStylePipelinePlugins } from './style-pipeline.js'; import { i18nComponentRegistryPlugin } from './i18n-component-registry-plugin.js'; - -// Bridge Plugin types from external @analogjs packages that resolve a different vite instance -function externalPlugins(plugins: unknown): Plugin[] { - return plugins as Plugin[]; -} +import { analogNitroPlugin } from './nitro/analog-nitro-plugin.js'; export function platformPlugin(opts: Options = {}): Plugin[] { applyDebugOption(opts.debug, opts.workspaceRoot); const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST']; - const viteOptions = opts?.vite === false ? undefined : opts?.vite; - const { - experimental: viteExperimental, - hmr: _removedViteHmrOption, - ...forwardedViteOptions - } = viteOptions ?? {}; const { ...platformOptions } = { ssr: true, ...opts, @@ -60,28 +48,10 @@ export function platformPlugin(opts: Options = {}): Plugin[] { ); } - const useAngularCompilationAPI = - platformOptions.experimental?.useAngularCompilationAPI ?? - viteExperimental?.useAngularCompilationAPI; debugPlatform('experimental options resolved', { - useAngularCompilationAPI: !!useAngularCompilationAPI, typedRouter: platformOptions.experimental?.typedRouter, stylePipeline: !!platformOptions.experimental?.stylePipeline, }); - let nitroOptions = platformOptions?.nitro; - - if (nitroOptions?.routeRules) { - nitroOptions = { - ...nitroOptions, - routeRules: mapValues(nitroOptions.routeRules, (rule) => ({ - ...rule, - headers: { - ...rule.headers, - 'x-analog-no-ssr': rule?.ssr === false ? 'true' : undefined, - } as any, - })), - }; - } return [ { @@ -90,7 +60,7 @@ export function platformPlugin(opts: Options = {}): Plugin[] { activateDeferredDebug(command); }, }, - ...externalPlugins(viteNitroPlugin(platformOptions as any, nitroOptions)), + analogNitroPlugin(platformOptions), ...(platformOptions.ssr ? [...ssrBuildPlugin(), ...injectHTMLPlugin()] : []), @@ -102,42 +72,6 @@ export function platformPlugin(opts: Options = {}): Plugin[] { ...routerPlugin(platformOptions), routeGenerationPlugin(platformOptions), ...contentPlugin(platformOptions?.content, platformOptions), - ...(opts?.vite === false - ? [] - : externalPlugins( - angular({ - jit: platformOptions.jit, - workspaceRoot: platformOptions.workspaceRoot, - // Let the Angular plugin keep its own dev-friendly default unless the - // app explicitly opts into stricter serve-time diagnostics. - disableTypeChecking: platformOptions.disableTypeChecking, - include: [ - ...(platformOptions.include ?? []), - ...(platformOptions.additionalPagesDirs ?? []).map( - (pageDir) => `${pageDir}/**/*.page.ts`, - ), - ], - additionalContentDirs: platformOptions.additionalContentDirs, - liveReload: platformOptions.liveReload, - inlineStylesExtension: platformOptions.inlineStylesExtension, - fileReplacements: platformOptions.fileReplacements, - fastCompile: platformOptions.fastCompile, - fastCompileMode: platformOptions.fastCompileMode, - debug: platformOptions.debug, - stylePipeline: platformOptions.experimental?.stylePipeline - ?.angularPlugins?.length - ? { - plugins: - platformOptions.experimental.stylePipeline.angularPlugins, - } - : undefined, - ...forwardedViteOptions, - experimental: { - ...(viteExperimental ?? {}), - useAngularCompilationAPI, - }, - }), - )), ...(platformOptions.i18n ? [i18nComponentRegistryPlugin()] : []), ...serverModePlugin(), ...clearClientPageEndpointsPlugin(), diff --git a/packages/platform/src/lib/style-pipeline.spec.ts b/packages/platform/src/lib/style-pipeline.spec.ts index 2df6d5f39..9a85685c9 100644 --- a/packages/platform/src/lib/style-pipeline.spec.ts +++ b/packages/platform/src/lib/style-pipeline.spec.ts @@ -13,11 +13,9 @@ describe('style-pipeline', () => { expect( defineStylePipeline({ plugins: [plugin], - angularPlugins: [], }), ).toEqual({ plugins: [plugin], - angularPlugins: [], }); }); diff --git a/packages/platform/src/lib/style-pipeline.ts b/packages/platform/src/lib/style-pipeline.ts index 93ff133bd..2219c3788 100644 --- a/packages/platform/src/lib/style-pipeline.ts +++ b/packages/platform/src/lib/style-pipeline.ts @@ -64,7 +64,6 @@ export type StylePipelinePluginEntry = export interface StylePipelineOptions { plugins?: StylePipelinePluginEntry[]; - angularPlugins?: AngularStylePipelinePlugin[]; } export function defineStylePipeline( diff --git a/packages/platform/src/lib/utils/debug.spec.ts b/packages/platform/src/lib/utils/debug.spec.ts index ca811e14c..846ad8f49 100644 --- a/packages/platform/src/lib/utils/debug.spec.ts +++ b/packages/platform/src/lib/utils/debug.spec.ts @@ -10,8 +10,8 @@ vi.mock('obug', () => ({ enable: vi.fn(), })); -vi.mock('@analogjs/vite-plugin-nitro/internal', () => ({ - debugInstances: [], +vi.mock('../nitro/debug.js', () => ({ + nitroDebugInstances: [], })); vi.mock('./debug-log-file.js', () => ({ diff --git a/packages/platform/src/lib/utils/debug.ts b/packages/platform/src/lib/utils/debug.ts index 416e8f9b5..2b5dae72c 100644 --- a/packages/platform/src/lib/utils/debug.ts +++ b/packages/platform/src/lib/utils/debug.ts @@ -1,5 +1,5 @@ import { createDebug } from 'obug'; -import { debugInstances as nitroDebugInstances } from '@analogjs/vite-plugin-nitro/internal'; +import { nitroDebugInstances } from '../nitro/debug.js'; import { createDebugHarness } from './debug-harness.js'; export const debugPlatform = createDebug('analog:platform'); diff --git a/packages/storybook-angular/src/lib/preset.ts b/packages/storybook-angular/src/lib/preset.ts index 3946cefbc..cbd24b5a5 100644 --- a/packages/storybook-angular/src/lib/preset.ts +++ b/packages/storybook-angular/src/lib/preset.ts @@ -72,10 +72,13 @@ async function resolveExperimentalZoneless( } export const viteFinal = async (config: any, options: any): Promise => { - // Remove any loaded analogjs plugins from a vite.config.(m)ts file + // Remove any loaded analogjs plugins from a vite.config.(m)ts file. + // Anonymous plugin entries (no `name` property) and falsy entries from + // conditional plugin arrays must pass through untouched — only filter + // plugins whose name explicitly contains "analogjs". config.plugins = (config.plugins ?? []) .flat() - .filter((plugin: any) => !plugin.name.includes('analogjs')); + .filter((plugin: any) => !plugin?.name?.includes?.('analogjs')); // @ts-expect-error - untyped storybook presets API const framework = await options.presets.apply('framework'); diff --git a/packages/vite-plugin-angular/package.json b/packages/vite-plugin-angular/package.json index 95bef33be..903cc563e 100644 --- a/packages/vite-plugin-angular/package.json +++ b/packages/vite-plugin-angular/package.json @@ -93,6 +93,16 @@ "import": "./dist/src/index.js", "require": "./dist/src/index.js", "default": "./dist/src/index.js" + }, + "./builders/vite": { + "import": "./dist/src/lib/tools/src/builders/vite/vite-build.impl.js", + "require": "./dist/src/lib/tools/src/builders/vite/vite-build.impl.js", + "default": "./dist/src/lib/tools/src/builders/vite/vite-build.impl.js" + }, + "./builders/vite-dev-server": { + "import": "./dist/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js", + "require": "./dist/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js", + "default": "./dist/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js" } }, "publishConfig": { diff --git a/packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts b/packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts index 4bb0362bb..30cf8fbc7 100644 --- a/packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts +++ b/packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts @@ -340,7 +340,10 @@ export function angular(options?: PluginOptions): Plugin[] { */ const pluginOptions = { tsconfigGetter: createTsConfigGetter(options?.tsconfig), - workspaceRoot: options?.workspaceRoot ?? process.cwd(), + workspaceRoot: + options?.workspaceRoot ?? + process.env['NX_WORKSPACE_ROOT'] ?? + process.cwd(), inlineStylesExtension: options?.inlineStylesExtension ?? 'css', advanced: { tsTransformers: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6854a17bc..4c545501c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,6 +54,9 @@ catalogs: '@astrojs/react': specifier: ^5.0.2 version: 5.0.3 + '@babel/core': + specifier: ^7.28.6 + version: 7.29.0 '@commitlint/cli': specifier: ^20.5.0 version: 20.5.0 @@ -325,8 +328,8 @@ catalogs: specifier: 21.2.2 version: 21.2.2 nitro: - specifier: 3.0.260415-beta - version: 3.0.260415-beta + specifier: 3.0.260522-beta + version: 3.0.260522-beta nx: specifier: 22.7.0-beta.12 version: 22.7.0-beta.12 @@ -648,10 +651,10 @@ importers: version: 3.1.1(@types/react@19.2.14)(react@19.2.5) '@nx/angular': specifier: 'catalog:' - version: 22.7.0-beta.12(bbf4031437ab82b6be657ea8be05b0c3) + version: 22.7.0-beta.12(05b4503607f205d03d993da8e423f9be) '@nx/devkit': specifier: 'catalog:' - version: 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + version: 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@standard-schema/spec': specifier: 'catalog:' version: 1.1.0 @@ -730,7 +733,7 @@ importers: version: 0.2102.7(chokidar@5.0.0) '@angular-devkit/build-angular': specifier: 'catalog:' - version: 21.2.7(0d8d439723faf789318b03d836c4657d) + version: 21.2.7(b8f20a26ea5ae043ece601bbe8d4f9d0) '@angular-devkit/core': specifier: 'catalog:' version: 21.2.7(chokidar@5.0.0) @@ -748,7 +751,7 @@ importers: version: 21.3.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) '@angular/build': specifier: 'catalog:' - version: 21.2.7(6919e34d293f380cbe3efb02122eac30) + version: 21.2.7(0b8bb98daa82125a57df7497f4fcef59) '@angular/cli': specifier: 'catalog:' version: 21.2.7(@types/node@25.6.0)(chokidar@5.0.0) @@ -781,31 +784,31 @@ importers: version: 5.2.0 '@nx/eslint': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@nx/eslint-plugin': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@typescript-eslint/parser@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2))(eslint-config-prettier@10.1.8(eslint@10.2.0(jiti@2.6.1)))(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@typescript-eslint/parser@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2))(eslint-config-prettier@10.1.8(eslint@10.2.0(jiti@2.6.1)))(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) '@nx/js': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@nx/playwright': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@playwright/test@1.59.1)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@playwright/test@1.59.1)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@nx/plugin': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@types/node@25.6.0)(@zkochan/js-yaml@0.0.7)(babel-plugin-macros@3.1.0)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@types/node@25.6.0)(@zkochan/js-yaml@0.0.7)(babel-plugin-macros@3.1.0)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) '@nx/storybook': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(storybook@10.3.5(@testing-library/dom@10.4.1)(prettier@3.8.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.2) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(storybook@10.3.5(@testing-library/dom@10.4.1)(prettier@3.8.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.2) '@nx/vite': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) '@nx/vitest': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) '@nx/web': specifier: 'catalog:' - version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + version: 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@oxc-angular/vite': specifier: 'catalog:' version: 0.0.23(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) @@ -838,13 +841,13 @@ importers: version: 10.3.5(@vitest/browser-playwright@4.1.4)(@vitest/browser@4.1.4)(@vitest/runner@4.1.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(prettier@3.8.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vitest@4.1.4) '@storybook/angular': specifier: 'catalog:' - version: 10.3.5(f55f33330bfbd6fb184961c0aca35221) + version: 10.3.5(56fe732b02a35e211a39a35ea47e2513) '@storybook/builder-vite': specifier: catalog:peerStorybook10 version: 10.3.5(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.3.5(@testing-library/dom@10.4.1)(prettier@3.8.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@swc-node/register': specifier: 'catalog:' - version: 1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2) + version: 1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2) '@swc/core': specifier: 'catalog:' version: 1.15.24(@swc/helpers@0.5.21) @@ -994,10 +997,10 @@ importers: version: 21.2.2(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(tailwindcss@4.2.2)(tslib@2.8.1)(typescript@6.0.2) nitro: specifier: 'catalog:' - version: 3.0.260415-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) nx: specifier: 'catalog:' - version: 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + version: 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) obug: specifier: 'catalog:' version: 2.1.1 @@ -1006,13 +1009,13 @@ importers: version: 2.0.0-alpha.3 oxc-parser: specifier: 'catalog:' - version: 0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + version: 0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) oxc-resolver: specifier: 'catalog:' - version: 11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + version: 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) oxc-transform: specifier: 'catalog:' - version: 0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + version: 0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) oxlint: specifier: 'catalog:' version: 1.60.0(oxlint-tsgolint@0.20.0) @@ -1039,7 +1042,7 @@ importers: version: 1.0.0-rc.15 rolldown-plugin-dts: specifier: 'catalog:' - version: 0.23.2(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2))(rolldown@1.0.0-rc.15)(typescript@6.0.2) + version: 0.23.2(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rolldown@1.0.0-rc.15)(typescript@6.0.2) rollup: specifier: 'catalog:' version: 4.60.1 @@ -1093,7 +1096,7 @@ importers: version: 28.0.0 tsdown: specifier: 'catalog:' - version: 0.21.8(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2))(synckit@0.11.12)(typescript@6.0.2) + version: 0.21.8(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(synckit@0.11.12)(typescript@6.0.2) typescript: specifier: 'catalog:' version: 6.0.2 @@ -1111,7 +1114,7 @@ importers: version: 12.0.0-beta.1(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(ws@8.20.0) vite-tsconfig-paths: specifier: 'catalog:' - version: 7.0.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) + version: 7.0.0-alpha.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) vitefu: specifier: 'catalog:' version: 1.1.3(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) @@ -1152,6 +1155,9 @@ importers: '@analogjs/vitest-angular': specifier: workspace:* version: link:../../packages/vitest-angular + nitro: + specifier: 'catalog:' + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) apps/analog-app-e2e: {} @@ -1184,6 +1190,12 @@ importers: '@analogjs/platform': specifier: workspace:* version: link:../../packages/platform + '@analogjs/vite-plugin-angular': + specifier: workspace:* + version: link:../../packages/vite-plugin-angular + nitro: + specifier: 'catalog:' + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) apps/blog-app-e2e: {} @@ -1248,6 +1260,9 @@ importers: '@analogjs/vite-plugin-angular': specifier: workspace:* version: link:../../packages/vite-plugin-angular + nitro: + specifier: 'catalog:' + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) apps/tailwind-debug-app: dependencies: @@ -1264,6 +1279,9 @@ importers: '@analogjs/vitest-angular': specifier: workspace:* version: link:../../packages/vitest-angular + nitro: + specifier: 'catalog:' + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) apps/tailwind-debug-app-e2e: {} @@ -1276,6 +1294,9 @@ importers: '@analogjs/platform': specifier: workspace:* version: link:../../packages/platform + '@analogjs/vite-plugin-angular': + specifier: workspace:* + version: link:../../packages/vite-plugin-angular '@analogjs/vitest-angular': specifier: workspace:* version: link:../../packages/vitest-angular @@ -1285,6 +1306,9 @@ importers: daisyui: specifier: ^5.5.19 version: 5.5.19 + nitro: + specifier: 'catalog:' + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) tailwindcss: specifier: 'catalog:' version: 4.2.2 @@ -1341,7 +1365,7 @@ importers: version: 21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)) '@angular/build': specifier: catalog:peerAngular20Plus - version: 21.2.7(6919e34d293f380cbe3efb02122eac30) + version: 21.2.7(0b8bb98daa82125a57df7497f4fcef59) '@angular/common': specifier: 21.2.8 version: 21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) @@ -1392,7 +1416,7 @@ importers: version: 21.2.8(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.8(@angular/animations@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) '@nx/devkit': specifier: catalog:peerCompat - version: 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + version: 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@standard-schema/spec': specifier: 'catalog:' version: 1.1.0 @@ -1444,10 +1468,10 @@ importers: dependencies: '@nx/devkit': specifier: catalog:peerCompat - version: 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + version: 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) tsdown: specifier: 'catalog:' - version: 0.21.8(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2))(synckit@0.11.12)(typescript@6.0.2) + version: 0.21.8(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(synckit@0.11.12)(typescript@6.0.2) vite: specifier: catalog:peerCompat version: 8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3) @@ -1467,6 +1491,12 @@ importers: '@analogjs/platform': specifier: workspace:* version: link:../platform + '@analogjs/vite-plugin-angular': + specifier: workspace:* + version: link:../vite-plugin-angular + nitro: + specifier: 'catalog:' + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) packages/nx-plugin: devDependencies: @@ -1479,18 +1509,18 @@ importers: '@analogjs/vite-plugin-angular': specifier: workspace:* version: link:../vite-plugin-angular - '@analogjs/vite-plugin-nitro': - specifier: workspace:* - version: link:../vite-plugin-nitro + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 '@nx/angular': specifier: catalog:peerCompat - version: 22.6.5(41fc5ff660d836e7ccf859f85688b300) + version: 22.6.5(2ab26fa366bc8886b2297d83f6c4af1d) '@nx/devkit': specifier: catalog:peerCompat - version: 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + version: 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@nx/vite': specifier: catalog:peerCompat - version: 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) + version: 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) es-toolkit: specifier: 'catalog:' version: 1.45.1 @@ -1514,10 +1544,16 @@ importers: version: 1.2.1(marked@18.0.0)(shiki@4.0.2) nitro: specifier: 'catalog:' - version: 3.0.260415-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) obug: specifier: 'catalog:' version: 2.1.1 + ofetch: + specifier: 'catalog:' + version: 2.0.0-alpha.3 + oxc-parser: + specifier: 'catalog:' + version: 0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) rolldown: specifier: 'catalog:' version: 1.0.0-rc.15 @@ -1533,6 +1569,9 @@ importers: vitefu: specifier: 'catalog:' version: 1.1.3(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) + xmlbuilder2: + specifier: 'catalog:' + version: 4.0.3 packages/router: dependencies: @@ -1575,10 +1614,10 @@ importers: dependencies: '@analogjs/vite-plugin-angular': specifier: catalog:peerVitestAngular - version: 2.4.7(@angular-devkit/build-angular@21.2.7(0d8d439723faf789318b03d836c4657d))(@angular/build@21.2.7(6919e34d293f380cbe3efb02122eac30)) + version: 2.4.7(@angular-devkit/build-angular@21.2.7(b8f20a26ea5ae043ece601bbe8d4f9d0))(@angular/build@21.2.7(0b8bb98daa82125a57df7497f4fcef59)) '@storybook/angular': specifier: catalog:peerStorybook10 - version: 10.3.5(f55f33330bfbd6fb184961c0aca35221) + version: 10.3.5(56fe732b02a35e211a39a35ea47e2513) '@storybook/builder-vite': specifier: catalog:peerStorybook10 version: 10.3.5(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.3.5(@testing-library/dom@10.4.1)(prettier@3.8.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) @@ -1596,10 +1635,10 @@ importers: dependencies: '@angular-devkit/build-angular': specifier: catalog:peerAngularBuilders - version: 21.2.7(0d8d439723faf789318b03d836c4657d) + version: 21.2.7(065a2e44cfc0f80119d956b5460fd850) '@angular/build': specifier: catalog:peerAngularBuilders - version: 21.2.7(6919e34d293f380cbe3efb02122eac30) + version: 21.2.7(b690019c48ff0abf542b789736446534) es-toolkit: specifier: 'catalog:' version: 1.45.1 @@ -1611,10 +1650,10 @@ importers: version: 2.1.1 oxc-parser: specifier: 'catalog:' - version: 0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + version: 0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) oxc-resolver: specifier: 'catalog:' - version: 11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + version: 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) rolldown: specifier: 'catalog:' version: 1.0.0-rc.15 @@ -1631,7 +1670,7 @@ importers: version: 6.1.7 nitro: specifier: 'catalog:' - version: 3.0.260415-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) + version: 3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) obug: specifier: 'catalog:' version: 2.1.1 @@ -1640,7 +1679,7 @@ importers: version: 2.0.0-alpha.3 oxc-parser: specifier: 'catalog:' - version: 0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + version: 0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) radix3: specifier: 'catalog:' version: 1.1.2 @@ -1655,7 +1694,7 @@ importers: dependencies: '@analogjs/vite-plugin-angular': specifier: catalog:peerVitestAngular - version: 2.4.7(@angular-devkit/build-angular@21.2.7(0d8d439723faf789318b03d836c4657d))(@angular/build@21.2.7(6919e34d293f380cbe3efb02122eac30)) + version: 2.4.7(@angular-devkit/build-angular@21.2.7(b8f20a26ea5ae043ece601bbe8d4f9d0))(@angular/build@21.2.7(0b8bb98daa82125a57df7497f4fcef59)) '@angular-devkit/architect': specifier: catalog:peerVitestAngular version: 0.2102.7(chokidar@5.0.0) @@ -1664,7 +1703,7 @@ importers: version: 21.2.7(chokidar@5.0.0) oxc-transform: specifier: 'catalog:' - version: 0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + version: 0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) vitest: specifier: catalog:peerVitestAngular version: 4.1.4(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(@vitest/ui@4.1.4)(happy-dom@20.8.9)(jsdom@29.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) @@ -3652,12 +3691,18 @@ packages: resolution: {integrity: sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==} engines: {node: '>=0.8.0'} + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.4.5': resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} '@emnapi/core@1.9.2': resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} @@ -4983,6 +5028,12 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@netlify/functions@5.2.0': resolution: {integrity: sha512-Pj93qeQd1tkQ5xm9gWJZmBf/1riLYqYHc0OzFukrJomrj82Ott53Rr/Q88H1ms5cF+P5QXRKWmA2JSxSybKfjA==} engines: {node: '>=18.0.0'} @@ -5599,6 +5650,9 @@ packages: '@oxc-project/types@0.124.0': resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} + '@oxc-project/types@0.132.0': + resolution: {integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==} + '@oxc-resolver/binding-android-arm-eabi@11.19.1': resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==} cpu: [arm] @@ -6162,6 +6216,12 @@ packages: cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.0.2': + resolution: {integrity: sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6174,6 +6234,12 @@ packages: cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.0.2': + resolution: {integrity: sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.0.0-rc.15': resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6186,6 +6252,12 @@ packages: cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.0.2': + resolution: {integrity: sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6198,6 +6270,12 @@ packages: cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.0.2': + resolution: {integrity: sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6210,6 +6288,12 @@ packages: cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.0.2': + resolution: {integrity: sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6224,6 +6308,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-arm64-gnu@1.0.2': + resolution: {integrity: sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6238,6 +6329,13 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-arm64-musl@1.0.2': + resolution: {integrity: sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6245,6 +6343,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-ppc64-gnu@1.0.2': + resolution: {integrity: sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6252,6 +6357,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.0.2': + resolution: {integrity: sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6266,6 +6378,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.0.2': + resolution: {integrity: sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6280,6 +6399,13 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-x64-musl@1.0.2': + resolution: {integrity: sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6292,6 +6418,12 @@ packages: cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.0.2': + resolution: {integrity: sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} engines: {node: '>=14.0.0'} @@ -6302,6 +6434,11 @@ packages: engines: {node: '>=14.0.0'} cpu: [wasm32] + '@rolldown/binding-wasm32-wasi@1.0.2': + resolution: {integrity: sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6314,6 +6451,12 @@ packages: cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.0.2': + resolution: {integrity: sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6326,6 +6469,12 @@ packages: cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.2': + resolution: {integrity: sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/pluginutils@1.0.0-rc.15': resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} @@ -6335,6 +6484,9 @@ packages: '@rolldown/pluginutils@1.0.0-rc.4': resolution: {integrity: sha512-1BrrmTu0TWfOP1riA8uakjFc9bpIUGzVKETsOtzY39pPga8zELGDl8eu1Dx7/gjM5CAz14UknsUMpBO8L+YntQ==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + '@rollup/plugin-json@6.1.0': resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} @@ -9897,15 +10049,18 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - env-runner@0.1.7: - resolution: {integrity: sha512-i7h96jxETJYhXy5grgHNJ9xNzCzWIn9Ck/VkkYgOlE4gOqknsLX3CmlVb5LmwNex8sOoLFVZLz+TIw/+b5rktA==} + env-runner@0.1.9: + resolution: {integrity: sha512-W9AiZlPx0uXtghAJiTBkeZOgyQdecVvoln3cHoOEZswPq0cVMi+WBhUQjdUn+JcZFAFgOt+i5fcO7C2zniZoCg==} hasBin: true peerDependencies: - '@netlify/runtime': ^4 - miniflare: ^4.20260317.3 + '@netlify/runtime': ^4.1.23 + '@vercel/queue': ^0.2.0 + miniflare: ^4.20260515.0 peerDependenciesMeta: '@netlify/runtime': optional: true + '@vercel/queue': + optional: true miniflare: optional: true @@ -10663,8 +10818,8 @@ packages: h3@1.15.11: resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} - h3@2.0.1-rc.20: - resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} + h3@2.0.1-rc.22: + resolution: {integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==} engines: {node: '>=20.11.1'} hasBin: true peerDependencies: @@ -10915,8 +11070,8 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - httpxy@0.5.0: - resolution: {integrity: sha512-qwX7QX/rK2visT10/b7bSeZWQOMlSm3svTD0pZpU+vJjNUP0YHtNv4c3z+MO+MSnGuRFWJFdCZiV+7F7dXIOzg==} + httpxy@0.5.3: + resolution: {integrity: sha512-SMS9V6Sn7VWaS11lYhoAr0ceoaiolTWf4jYdJn0NJhCdKMu9R2H9Fh0LBDWBHQF6HRLI1PmaePYsjanSpE5PEw==} human-signals@1.1.1: resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} @@ -12475,8 +12630,8 @@ packages: nerf-dart@1.0.0: resolution: {integrity: sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==} - nf3@0.3.16: - resolution: {integrity: sha512-Gs0xRPpUm2nDkqbi40NJ9g7qDIcjcJzgExiydnq6LAyqhI2jfno8wG3NKTL+IiJsx799UHOb1CnSd4Wg4SG4Pw==} + nf3@0.3.17: + resolution: {integrity: sha512-N9zEWySuJFw+gR0lhS5863YsvNeudOdqRyFvNb+jMXbeTJOdrjDqkCpDginIZfUm0LzT1t1nCRiDeqQm/8kirQ==} ng-packagr@21.2.2: resolution: {integrity: sha512-VO0y7RU3Ik8E14QdrryVyVbTAyqO2MK9W9GrG4e/4N8+ti+DWiBSQmw0tIhnV67lEjQwCccPA3ZBoIn3B1vJ1Q==} @@ -12491,16 +12646,16 @@ packages: tailwindcss: optional: true - nitro@3.0.260415-beta: - resolution: {integrity: sha512-J0ntJERWtIdvweZdmkCiF8eOFvP9fIAJR2gpeIDrHbAlYavK41WQfADo/YoZ/LF7RMTZBiPaH/pt2s/nPru9Iw==} + nitro@3.0.260522-beta: + resolution: {integrity: sha512-L/z2eOWgkiQHc65kv+SEMgau505afSRF7NJlbooaaZEZscFrNSD7rXZzeVubQlgIzPbhOG8o73bk9soIiGTHRA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@vercel/queue': ^0.1.4 + '@vercel/queue': ^0.2.0 dotenv: '*' giget: '*' jiti: ^2.6.1 - rollup: ^4.60.1 + rollup: ^4.60.3 vite: ^7 || ^8 xml2js: ^0.6.2 zephyr-agent: ^0.2.0 @@ -14370,6 +14525,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.0.2: + resolution: {integrity: sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup-plugin-dts@6.4.1: resolution: {integrity: sha512-l//F3Zf7ID5GoOfLfD8kroBjQKEKpy1qfhtAdnpibFZMffPaylrg1CoDC2vGkPeTeyxUe4bVFCln2EFuL7IGGg==} engines: {node: '>=20'} @@ -16793,13 +16953,13 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@analogjs/vite-plugin-angular@2.4.7(@angular-devkit/build-angular@21.2.7(0d8d439723faf789318b03d836c4657d))(@angular/build@21.2.7(6919e34d293f380cbe3efb02122eac30))': + '@analogjs/vite-plugin-angular@2.4.7(@angular-devkit/build-angular@21.2.7(b8f20a26ea5ae043ece601bbe8d4f9d0))(@angular/build@21.2.7(0b8bb98daa82125a57df7497f4fcef59))': dependencies: tinyglobby: 0.2.16 ts-morph: 21.0.1 optionalDependencies: - '@angular-devkit/build-angular': 21.2.7(0d8d439723faf789318b03d836c4657d) - '@angular/build': 21.2.7(6919e34d293f380cbe3efb02122eac30) + '@angular-devkit/build-angular': 21.2.7(b8f20a26ea5ae043ece601bbe8d4f9d0) + '@angular/build': 21.2.7(0b8bb98daa82125a57df7497f4fcef59) '@angular-devkit/architect@0.2102.7(chokidar@5.0.0)': dependencies: @@ -16808,13 +16968,13 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@21.2.7(0d8d439723faf789318b03d836c4657d)': + '@angular-devkit/build-angular@21.2.7(065a2e44cfc0f80119d956b5460fd850)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2102.7(chokidar@5.0.0) - '@angular-devkit/build-webpack': 0.2102.7(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + '@angular-devkit/build-webpack': 0.2102.7(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@angular-devkit/core': 21.2.7(chokidar@5.0.0) - '@angular/build': 21.2.7(be30e769aef7c15f3ae11d69182ce8ae) + '@angular/build': 21.2.7(9643f421a1d0ee4251e74315a0e70414) '@angular/compiler-cli': 21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2) '@babel/core': 7.29.0 '@babel/generator': 7.29.1 @@ -16826,35 +16986,35 @@ snapshots: '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@babel/runtime': 7.28.6 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 21.2.7(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + '@ngtools/webpack': 21.2.7(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) ansi-colors: 4.1.3 autoprefixer: 10.4.27(postcss@8.5.6) - babel-loader: 10.0.0(@babel/core@7.29.0)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + babel-loader: 10.0.0(@babel/core@7.29.0)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) browserslist: 4.28.2 - copy-webpack-plugin: 14.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) - css-loader: 7.1.3(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + copy-webpack-plugin: 14.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + css-loader: 7.1.3(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) esbuild-wasm: 0.27.3 http-proxy-middleware: 3.0.5 istanbul-lib-instrument: 6.0.3 jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 less: 4.4.2 - less-loader: 12.3.1(@rspack/core@1.7.11(@swc/helpers@0.5.21))(less@4.4.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) - license-webpack-plugin: 4.0.2(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + less-loader: 12.3.1(@rspack/core@1.7.11(@swc/helpers@0.5.21))(less@4.4.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + license-webpack-plugin: 4.0.2(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.10.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + mini-css-extract-plugin: 2.10.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) open: 11.0.0 ora: 9.3.0 picomatch: 4.0.4 piscina: 5.1.4 postcss: 8.5.6 - postcss-loader: 8.2.0(@rspack/core@1.7.11(@swc/helpers@0.5.21))(postcss@8.5.6)(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + postcss-loader: 8.2.0(@rspack/core@1.7.11(@swc/helpers@0.5.21))(postcss@8.5.6)(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) resolve-url-loader: 5.0.0 rxjs: 7.8.2 sass: 1.97.3 - sass-loader: 16.0.7(@rspack/core@1.7.11(@swc/helpers@0.5.21))(sass-embedded@1.99.0)(sass@1.97.3)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + sass-loader: 16.0.7(@rspack/core@1.7.11(@swc/helpers@0.5.21))(sass-embedded@1.99.0)(sass@1.97.3)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) semver: 7.7.4 - source-map-loader: 5.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + source-map-loader: 5.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) source-map-support: 0.5.21 terser: 5.46.0 tinyglobby: 0.2.15 @@ -16862,10 +17022,10 @@ snapshots: tslib: 2.8.1 typescript: 6.0.2 webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) - webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) optionalDependencies: '@angular/core': 21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1) '@angular/localize': 21.2.8(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(@angular/compiler@21.2.8) @@ -16900,13 +17060,13 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-angular@21.2.7(7a6d932c692adf7b91035f989a2c47b9)': + '@angular-devkit/build-angular@21.2.7(19efef94e4c51e719ac157ec3cc75c84)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2102.7(chokidar@5.0.0) - '@angular-devkit/build-webpack': 0.2102.7(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + '@angular-devkit/build-webpack': 0.2102.7(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@angular-devkit/core': 21.2.7(chokidar@5.0.0) - '@angular/build': 21.2.7(be30e769aef7c15f3ae11d69182ce8ae) + '@angular/build': 21.2.7(9643f421a1d0ee4251e74315a0e70414) '@angular/compiler-cli': 21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2) '@babel/core': 7.29.0 '@babel/generator': 7.29.1 @@ -16918,12 +17078,12 @@ snapshots: '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@babel/runtime': 7.28.6 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 21.2.7(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + '@ngtools/webpack': 21.2.7(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) ansi-colors: 4.1.3 autoprefixer: 10.4.27(postcss@8.5.6) - babel-loader: 10.0.0(@babel/core@7.29.0)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + babel-loader: 10.0.0(@babel/core@7.29.0)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) browserslist: 4.28.2 - copy-webpack-plugin: 14.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + copy-webpack-plugin: 14.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) css-loader: 7.1.3(@rspack/core@1.6.8(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) esbuild-wasm: 0.27.3 http-proxy-middleware: 3.0.5 @@ -16932,9 +17092,9 @@ snapshots: karma-source-map-support: 1.4.0 less: 4.4.2 less-loader: 12.3.1(@rspack/core@1.6.8(@swc/helpers@0.5.21))(less@4.4.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) - license-webpack-plugin: 4.0.2(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + license-webpack-plugin: 4.0.2(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.10.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + mini-css-extract-plugin: 2.10.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) open: 11.0.0 ora: 9.3.0 picomatch: 4.0.4 @@ -16946,7 +17106,7 @@ snapshots: sass: 1.97.3 sass-loader: 16.0.7(@rspack/core@1.6.8(@swc/helpers@0.5.21))(sass-embedded@1.99.0)(sass@1.97.3)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) semver: 7.7.4 - source-map-loader: 5.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + source-map-loader: 5.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) source-map-support: 0.5.21 terser: 5.46.0 tinyglobby: 0.2.15 @@ -16954,8 +17114,8 @@ snapshots: tslib: 2.8.1 typescript: 6.0.2 webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) - webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) webpack-merge: 6.0.1 webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) optionalDependencies: @@ -16993,12 +17153,104 @@ snapshots: - yaml optional: true - '@angular-devkit/build-webpack@0.2102.7(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3))': + '@angular-devkit/build-angular@21.2.7(b8f20a26ea5ae043ece601bbe8d4f9d0)': dependencies: + '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2102.7(chokidar@5.0.0) + '@angular-devkit/build-webpack': 0.2102.7(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + '@angular-devkit/core': 21.2.7(chokidar@5.0.0) + '@angular/build': 21.2.7(9643f421a1d0ee4251e74315a0e70414) + '@angular/compiler-cli': 21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2) + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) + '@babel/runtime': 7.28.6 + '@discoveryjs/json-ext': 0.6.3 + '@ngtools/webpack': 21.2.7(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + ansi-colors: 4.1.3 + autoprefixer: 10.4.27(postcss@8.5.6) + babel-loader: 10.0.0(@babel/core@7.29.0)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + browserslist: 4.28.2 + copy-webpack-plugin: 14.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + css-loader: 7.1.3(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + esbuild-wasm: 0.27.3 + http-proxy-middleware: 3.0.5 + istanbul-lib-instrument: 6.0.3 + jsonc-parser: 3.3.1 + karma-source-map-support: 1.4.0 + less: 4.4.2 + less-loader: 12.3.1(@rspack/core@1.7.11(@swc/helpers@0.5.21))(less@4.4.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + license-webpack-plugin: 4.0.2(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + loader-utils: 3.3.1 + mini-css-extract-plugin: 2.10.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + open: 11.0.0 + ora: 9.3.0 + picomatch: 4.0.4 + piscina: 5.1.4 + postcss: 8.5.6 + postcss-loader: 8.2.0(@rspack/core@1.7.11(@swc/helpers@0.5.21))(postcss@8.5.6)(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + resolve-url-loader: 5.0.0 rxjs: 7.8.2 + sass: 1.97.3 + sass-loader: 16.0.7(@rspack/core@1.7.11(@swc/helpers@0.5.21))(sass-embedded@1.99.0)(sass@1.97.3)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + semver: 7.7.4 + source-map-loader: 5.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + source-map-support: 0.5.21 + terser: 5.46.0 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + tslib: 2.8.1 + typescript: 6.0.2 webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) - webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + webpack-merge: 6.0.1 + webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + optionalDependencies: + '@angular/core': 21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/localize': 21.2.8(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(@angular/compiler@21.2.8) + '@angular/platform-browser': 21.2.8(@angular/animations@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)) + '@angular/platform-server': 21.2.8(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/compiler@21.2.8)(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.8(@angular/animations@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) + '@angular/ssr': 21.2.7(9c898ff27dabd87c2e39c7d23b6394cf) + esbuild: 0.27.3 + ng-packagr: 21.2.2(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(tailwindcss@4.2.2)(tslib@2.8.1)(typescript@6.0.2) + tailwindcss: 4.2.2 + transitivePeerDependencies: + - '@angular/compiler' + - '@emnapi/core' + - '@emnapi/runtime' + - '@rspack/core' + - '@swc/core' + - '@types/node' + - bufferutil + - chokidar + - debug + - html-webpack-plugin + - jiti + - lightningcss + - node-sass + - sass-embedded + - stylus + - sugarss + - supports-color + - tsx + - uglify-js + - utf-8-validate + - vitest + - webpack-cli + - yaml + + '@angular-devkit/build-webpack@0.2102.7(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7))': + dependencies: + '@angular-devkit/architect': 0.2102.7(chokidar@5.0.0) + rxjs: 7.8.2 + webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) transitivePeerDependencies: - chokidar @@ -17114,7 +17366,7 @@ snapshots: '@angular/core': 21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1) tslib: 2.8.1 - '@angular/build@21.2.7(6919e34d293f380cbe3efb02122eac30)': + '@angular/build@21.2.7(0b8bb98daa82125a57df7497f4fcef59)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2102.7(chokidar@5.0.0) @@ -17137,7 +17389,7 @@ snapshots: parse5-html-rewriting-stream: 8.0.0 picomatch: 4.0.4 piscina: 5.1.4 - rolldown: 1.0.0-rc.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + rolldown: 1.0.0-rc.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) sass: 1.97.3 semver: 7.7.4 source-map-support: 0.5.21 @@ -17174,7 +17426,7 @@ snapshots: - tsx - yaml - '@angular/build@21.2.7(be30e769aef7c15f3ae11d69182ce8ae)': + '@angular/build@21.2.7(9643f421a1d0ee4251e74315a0e70414)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2102.7(chokidar@5.0.0) @@ -17197,7 +17449,7 @@ snapshots: parse5-html-rewriting-stream: 8.0.0 picomatch: 4.0.4 piscina: 5.1.4 - rolldown: 1.0.0-rc.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + rolldown: 1.0.0-rc.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) sass: 1.97.3 semver: 7.7.4 source-map-support: 0.5.21 @@ -17234,6 +17486,66 @@ snapshots: - tsx - yaml + '@angular/build@21.2.7(b690019c48ff0abf542b789736446534)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@angular-devkit/architect': 0.2102.7(chokidar@5.0.0) + '@angular/compiler': 21.2.8 + '@angular/compiler-cli': 21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2) + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-split-export-declaration': 7.24.7 + '@inquirer/confirm': 5.1.21(@types/node@25.6.0) + '@vitejs/plugin-basic-ssl': 2.1.4(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)) + beasties: 0.4.1 + browserslist: 4.28.2 + esbuild: 0.27.3 + https-proxy-agent: 7.0.6 + istanbul-lib-instrument: 6.0.3 + jsonc-parser: 3.3.1 + listr2: 9.0.5 + magic-string: 0.30.21 + mrmime: 2.0.1 + parse5-html-rewriting-stream: 8.0.0 + picomatch: 4.0.4 + piscina: 5.1.4 + rolldown: 1.0.0-rc.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + sass: 1.97.3 + semver: 7.7.4 + source-map-support: 0.5.21 + tinyglobby: 0.2.15 + tslib: 2.8.1 + typescript: 6.0.2 + undici: 7.24.4 + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3) + watchpack: 2.5.1 + optionalDependencies: + '@angular/core': 21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/localize': 21.2.8(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(@angular/compiler@21.2.8) + '@angular/platform-browser': 21.2.8(@angular/animations@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)) + '@angular/platform-server': 21.2.8(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/compiler@21.2.8)(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.8(@angular/animations@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) + '@angular/ssr': 21.2.7(9c898ff27dabd87c2e39c7d23b6394cf) + less: 4.4.2 + lmdb: 3.5.1 + ng-packagr: 21.2.2(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(tailwindcss@4.2.2)(tslib@2.8.1)(typescript@6.0.2) + postcss: 8.5.6 + tailwindcss: 4.2.2 + vitest: 4.1.4(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(@vitest/ui@4.1.4)(happy-dom@20.8.9)(jsdom@29.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + - '@types/node' + - chokidar + - jiti + - lightningcss + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + '@angular/cdk@21.2.6(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.8(@angular/animations@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2)': dependencies: '@angular/common': 21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) @@ -20406,6 +20718,12 @@ snapshots: dependencies: '@types/hammerjs': 2.0.46 + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + '@emnapi/core@1.4.5': dependencies: '@emnapi/wasi-threads': 1.0.4 @@ -20416,6 +20734,11 @@ snapshots: '@emnapi/wasi-threads': 1.2.1 tslib: 2.8.1 + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.4.5': dependencies: tslib: 2.8.1 @@ -21735,6 +22058,13 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@napi-rs/wasm-runtime@1.1.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.1 + optional: true + '@napi-rs/wasm-runtime@1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': dependencies: '@emnapi/core': 1.9.2 @@ -21742,13 +22072,20 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.1 + optional: true + '@netlify/functions@5.2.0': dependencies: '@netlify/types': 2.6.0 '@netlify/types@2.6.0': {} - '@ngtools/webpack@21.2.7(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3))': + '@ngtools/webpack@21.2.7(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7))': dependencies: '@angular/compiler-cli': 21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2) typescript: 6.0.2 @@ -21826,18 +22163,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@nx/angular@22.6.5(41fc5ff660d836e7ccf859f85688b300)': + '@nx/angular@22.6.5(2ab26fa366bc8886b2297d83f6c4af1d)': dependencies: '@angular-devkit/core': 21.2.7(chokidar@5.0.0) '@angular-devkit/schematics': 21.2.7(chokidar@5.0.0) - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/eslint': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/module-federation': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(node-fetch@2.7.0(encoding@0.1.13))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@nx/rspack': 22.6.5(10ec6bc8cf7172a1e8f69047189d0c0c) - '@nx/web': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/webpack': 22.6.5(@babel/traverse@7.29.0)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(lightningcss@1.32.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) - '@nx/workspace': 22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/eslint': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/module-federation': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(node-fetch@2.7.0(encoding@0.1.13))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@nx/rspack': 22.6.5(0f8f61c24ac41c470a42fabffc547d6a) + '@nx/web': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/webpack': 22.6.5(@babel/traverse@7.29.0)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(lightningcss@1.32.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) + '@nx/workspace': 22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) '@schematics/angular': 21.2.7(chokidar@5.0.0) '@typescript-eslint/type-utils': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) @@ -21850,8 +22187,8 @@ snapshots: tslib: 2.8.1 webpack-merge: 5.10.0 optionalDependencies: - '@angular-devkit/build-angular': 21.2.7(7a6d932c692adf7b91035f989a2c47b9) - '@angular/build': 21.2.7(6919e34d293f380cbe3efb02122eac30) + '@angular-devkit/build-angular': 21.2.7(19efef94e4c51e719ac157ec3cc75c84) + '@angular/build': 21.2.7(0b8bb98daa82125a57df7497f4fcef59) ng-packagr: 21.2.2(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(tailwindcss@4.2.2)(tslib@2.8.1)(typescript@6.0.2) transitivePeerDependencies: - '@babel/traverse' @@ -21888,18 +22225,18 @@ snapshots: - webpack-cli - webpack-hot-middleware - '@nx/angular@22.7.0-beta.12(bbf4031437ab82b6be657ea8be05b0c3)': + '@nx/angular@22.7.0-beta.12(05b4503607f205d03d993da8e423f9be)': dependencies: '@angular-devkit/core': 21.2.7(chokidar@5.0.0) '@angular-devkit/schematics': 21.2.7(chokidar@5.0.0) - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/module-federation': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@nx/rspack': 22.7.0-beta.12(48cd17b689492b71c69607744627af60) - '@nx/web': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/webpack': 22.7.0-beta.12(@babel/traverse@7.29.0)(@rspack/core@1.7.11(@swc/helpers@0.5.21))(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(lightningcss@1.32.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) - '@nx/workspace': 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/module-federation': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@nx/rspack': 22.7.0-beta.12(592fb373ea7864f3acebaf5cd4494711) + '@nx/web': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/webpack': 22.7.0-beta.12(@babel/traverse@7.29.0)(@rspack/core@1.7.11(@swc/helpers@0.5.21))(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(lightningcss@1.32.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) + '@nx/workspace': 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) '@schematics/angular': 21.2.7(chokidar@5.0.0) '@typescript-eslint/type-utils': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) @@ -21912,8 +22249,8 @@ snapshots: tslib: 2.8.1 webpack-merge: 5.10.0 optionalDependencies: - '@angular-devkit/build-angular': 21.2.7(0d8d439723faf789318b03d836c4657d) - '@angular/build': 21.2.7(6919e34d293f380cbe3efb02122eac30) + '@angular-devkit/build-angular': 21.2.7(b8f20a26ea5ae043ece601bbe8d4f9d0) + '@angular/build': 21.2.7(0b8bb98daa82125a57df7497f4fcef59) ng-packagr: 21.2.2(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(tailwindcss@4.2.2)(tslib@2.8.1)(typescript@6.0.2) transitivePeerDependencies: - '@babel/traverse' @@ -21950,11 +22287,11 @@ snapshots: - webpack-cli - webpack-hot-middleware - '@nx/cypress@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': + '@nx/cypress@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) detect-port: 1.6.1 semver: 7.7.4 @@ -21972,43 +22309,43 @@ snapshots: - typescript - verdaccio - '@nx/devkit@22.6.5(nx@22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/devkit@22.6.5(nx@22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: '@zkochan/js-yaml': 0.0.7 ejs: 5.0.1 enquirer: 2.3.6 minimatch: 10.2.4 - nx: 22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + nx: 22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) semver: 7.7.4 tslib: 2.8.1 yargs-parser: 21.1.1 - '@nx/devkit@22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/devkit@22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: '@zkochan/js-yaml': 0.0.7 ejs: 5.0.1 enquirer: 2.3.6 minimatch: 10.2.4 - nx: 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + nx: 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) semver: 7.7.4 tslib: 2.8.1 yargs-parser: 21.1.1 - '@nx/devkit@22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/devkit@22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: '@zkochan/js-yaml': 0.0.7 ejs: 5.0.1 enquirer: 2.3.6 minimatch: 10.2.4 - nx: 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + nx: 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) semver: 7.7.4 tslib: 2.8.1 yargs-parser: 21.1.1 - '@nx/eslint-plugin@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@typescript-eslint/parser@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2))(eslint-config-prettier@10.1.8(eslint@10.2.0(jiti@2.6.1)))(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': + '@nx/eslint-plugin@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@typescript-eslint/parser@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2))(eslint-config-prettier@10.1.8(eslint@10.2.0(jiti@2.6.1)))(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) '@typescript-eslint/parser': 8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) '@typescript-eslint/type-utils': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) @@ -22032,10 +22369,10 @@ snapshots: - typescript - verdaccio - '@nx/eslint@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/eslint@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) eslint: 10.2.0(jiti@2.6.1) semver: 7.7.4 tslib: 2.8.1 @@ -22051,10 +22388,10 @@ snapshots: - supports-color - verdaccio - '@nx/eslint@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/eslint@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) eslint: 10.2.0(jiti@2.6.1) semver: 7.7.4 tslib: 2.8.1 @@ -22070,12 +22407,12 @@ snapshots: - supports-color - verdaccio - '@nx/jest@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@types/node@25.6.0)(babel-plugin-macros@3.1.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': + '@nx/jest@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@types/node@25.6.0)(babel-plugin-macros@3.1.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': dependencies: '@jest/reporters': 30.3.0 '@jest/test-result': 30.3.0 - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) identity-obj-proxy: 3.0.0 jest-config: 30.3.0(@types/node@25.6.0)(babel-plugin-macros@3.1.0) @@ -22102,7 +22439,7 @@ snapshots: - typescript - verdaccio - '@nx/js@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/js@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) @@ -22111,8 +22448,8 @@ snapshots: '@babel/preset-env': 7.29.2(@babel/core@7.29.0) '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) '@babel/runtime': 7.29.2 - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/workspace': 22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/workspace': 22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) '@zkochan/js-yaml': 0.0.7 babel-plugin-const-enum: 1.2.0(@babel/core@7.29.0) babel-plugin-macros: 3.1.0 @@ -22138,7 +22475,7 @@ snapshots: - nx - supports-color - '@nx/js@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/js@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) @@ -22147,8 +22484,8 @@ snapshots: '@babel/preset-env': 7.29.2(@babel/core@7.29.0) '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) '@babel/runtime': 7.29.2 - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/workspace': 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/workspace': 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) '@zkochan/js-yaml': 0.0.7 babel-plugin-const-enum: 1.2.0(@babel/core@7.29.0) babel-plugin-macros: 3.1.0 @@ -22174,14 +22511,14 @@ snapshots: - nx - supports-color - '@nx/module-federation@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(node-fetch@2.7.0(encoding@0.1.13))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@nx/module-federation@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(node-fetch@2.7.0(encoding@0.1.13))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': dependencies: '@module-federation/enhanced': 2.3.2(@rspack/core@1.6.8(@swc/helpers@0.5.21))(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@module-federation/node': 2.7.40(@rspack/core@1.6.8(@swc/helpers@0.5.21))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@module-federation/sdk': 2.3.2(node-fetch@2.7.0(encoding@0.1.13)) - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/web': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/web': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@rspack/core': 1.6.8(@swc/helpers@0.5.21) express: 4.22.1 http-proxy-middleware: 3.0.5 @@ -22208,14 +22545,14 @@ snapshots: - vue-tsc - webpack-cli - '@nx/module-federation@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@nx/module-federation@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': dependencies: '@module-federation/enhanced': 2.3.2(@rspack/core@1.6.8(@swc/helpers@0.5.21))(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@module-federation/node': 2.7.40(@rspack/core@1.6.8(@swc/helpers@0.5.21))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@module-federation/sdk': 2.3.2(node-fetch@2.7.0(encoding@0.1.13)) - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/web': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/web': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@rspack/core': 1.6.8(@swc/helpers@0.5.21) express: 4.22.1 http-proxy-middleware: 3.0.5 @@ -22302,11 +22639,11 @@ snapshots: '@nx/nx-win32-x64-msvc@22.7.0-beta.12': optional: true - '@nx/playwright@22.7.0-beta.12(@babel/traverse@7.29.0)(@playwright/test@1.59.1)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/playwright@22.7.0-beta.12(@babel/traverse@7.29.0)(@playwright/test@1.59.1)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) minimatch: 10.2.4 tslib: 2.8.1 optionalDependencies: @@ -22322,12 +22659,12 @@ snapshots: - supports-color - verdaccio - '@nx/plugin@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@types/node@25.6.0)(@zkochan/js-yaml@0.0.7)(babel-plugin-macros@3.1.0)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': + '@nx/plugin@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@types/node@25.6.0)(@zkochan/js-yaml@0.0.7)(babel-plugin-macros@3.1.0)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/jest': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@types/node@25.6.0)(babel-plugin-macros@3.1.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/jest': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@types/node@25.6.0)(babel-plugin-macros@3.1.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) tslib: 2.8.1 transitivePeerDependencies: - '@babel/traverse' @@ -22346,14 +22683,14 @@ snapshots: - typescript - verdaccio - '@nx/rspack@22.6.5(10ec6bc8cf7172a1e8f69047189d0c0c)': + '@nx/rspack@22.6.5(0f8f61c24ac41c470a42fabffc547d6a)': dependencies: '@module-federation/enhanced': 2.3.2(@rspack/core@1.6.8(@swc/helpers@0.5.21))(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@module-federation/node': 2.7.40(@rspack/core@1.6.8(@swc/helpers@0.5.21))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/module-federation': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(node-fetch@2.7.0(encoding@0.1.13))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@nx/web': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/module-federation': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(node-fetch@2.7.0(encoding@0.1.13))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@nx/web': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) '@rspack/core': 1.6.8(@swc/helpers@0.5.21) '@rspack/dev-server': 1.2.1(@rspack/core@1.6.8(@swc/helpers@0.5.21))(tslib@2.8.1)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) @@ -22405,14 +22742,14 @@ snapshots: - webpack-cli - webpack-hot-middleware - '@nx/rspack@22.7.0-beta.12(48cd17b689492b71c69607744627af60)': + '@nx/rspack@22.7.0-beta.12(592fb373ea7864f3acebaf5cd4494711)': dependencies: '@module-federation/enhanced': 2.3.2(@rspack/core@1.7.11(@swc/helpers@0.5.21))(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) '@module-federation/node': 2.7.40(@rspack/core@1.7.11(@swc/helpers@0.5.21))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/module-federation': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@nx/web': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/module-federation': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)(esbuild@0.27.7)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@nx/web': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) '@rspack/core': 1.6.8(@swc/helpers@0.5.21) '@rspack/dev-server': 1.2.1(@rspack/core@1.6.8(@swc/helpers@0.5.21))(tslib@2.8.1)(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) @@ -22464,12 +22801,12 @@ snapshots: - webpack-cli - webpack-hot-middleware - '@nx/storybook@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(storybook@10.3.5(@testing-library/dom@10.4.1)(prettier@3.8.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.2)': + '@nx/storybook@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(storybook@10.3.5(@testing-library/dom@10.4.1)(prettier@3.8.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.2)': dependencies: - '@nx/cypress': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/cypress': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/eslint': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(@zkochan/js-yaml@0.0.7)(eslint@10.2.0(jiti@2.6.1))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) semver: 7.7.4 storybook: 10.3.5(@testing-library/dom@10.4.1)(prettier@3.8.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -22487,11 +22824,11 @@ snapshots: - typescript - verdaccio - '@nx/vite@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': + '@nx/vite@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': dependencies: - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/vitest': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/vitest': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) ajv: 8.18.0 enquirer: 2.3.6 @@ -22511,11 +22848,11 @@ snapshots: - typescript - verdaccio - '@nx/vite@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': + '@nx/vite@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/vitest': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/vitest': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) ajv: 8.18.0 enquirer: 2.3.6 @@ -22535,10 +22872,10 @@ snapshots: - typescript - verdaccio - '@nx/vitest@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': + '@nx/vitest@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': dependencies: - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) semver: 7.7.4 tslib: 2.8.1 @@ -22555,10 +22892,10 @@ snapshots: - typescript - verdaccio - '@nx/vitest@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': + '@nx/vitest@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) semver: 7.7.4 tslib: 2.8.1 @@ -22575,10 +22912,10 @@ snapshots: - typescript - verdaccio - '@nx/web@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/web@22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) detect-port: 1.6.1 http-server: 14.1.1 picocolors: 1.1.1 @@ -22592,10 +22929,10 @@ snapshots: - supports-color - verdaccio - '@nx/web@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': + '@nx/web@22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) detect-port: 1.6.1 http-server: 14.1.1 picocolors: 1.1.1 @@ -22609,11 +22946,11 @@ snapshots: - supports-color - verdaccio - '@nx/webpack@22.6.5(@babel/traverse@7.29.0)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(lightningcss@1.32.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': + '@nx/webpack@22.6.5(@babel/traverse@7.29.0)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(lightningcss@1.32.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': dependencies: '@babel/core': 7.29.0 - '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.6.5(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.6.5(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) ajv: 8.18.0 autoprefixer: 10.4.27(postcss@8.5.9) @@ -22670,11 +23007,11 @@ snapshots: - verdaccio - webpack-cli - '@nx/webpack@22.7.0-beta.12(@babel/traverse@7.29.0)(@rspack/core@1.7.11(@swc/helpers@0.5.21))(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(lightningcss@1.32.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': + '@nx/webpack@22.7.0-beta.12(@babel/traverse@7.29.0)(@rspack/core@1.7.11(@swc/helpers@0.5.21))(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(lightningcss@1.32.0)(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)))(typescript@6.0.2)': dependencies: '@babel/core': 7.29.0 - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) - '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/js': 22.7.0-beta.12(@babel/traverse@7.29.0)(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.2) ajv: 8.18.0 autoprefixer: 10.4.27(postcss@8.5.9) @@ -22731,13 +23068,13 @@ snapshots: - verdaccio - webpack-cli - '@nx/workspace@22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))': + '@nx/workspace@22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))': dependencies: - '@nx/devkit': 22.6.5(nx@22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.6.5(nx@22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@zkochan/js-yaml': 0.0.7 chalk: 4.1.2 enquirer: 2.3.6 - nx: 22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + nx: 22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) picomatch: 4.0.4 semver: 7.7.4 tslib: 2.8.1 @@ -22747,13 +23084,13 @@ snapshots: - '@swc/core' - debug - '@nx/workspace@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))': + '@nx/workspace@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))': dependencies: - '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) + '@nx/devkit': 22.7.0-beta.12(nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21))) '@zkochan/js-yaml': 0.0.7 chalk: 4.1.2 enquirer: 2.3.6 - nx: 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) + nx: 22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)) picomatch: 4.0.4 semver: 7.7.4 tslib: 2.8.1 @@ -22928,9 +23265,9 @@ snapshots: '@oxc-parser/binding-openharmony-arm64@0.124.0': optional: true - '@oxc-parser/binding-wasm32-wasi@0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + '@oxc-parser/binding-wasm32-wasi@0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -22951,6 +23288,8 @@ snapshots: '@oxc-project/types@0.124.0': {} + '@oxc-project/types@0.132.0': {} + '@oxc-resolver/binding-android-arm-eabi@11.19.1': optional: true @@ -22999,9 +23338,9 @@ snapshots: '@oxc-resolver/binding-openharmony-arm64@11.19.1': optional: true - '@oxc-resolver/binding-wasm32-wasi@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + '@oxc-resolver/binding-wasm32-wasi@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -23064,9 +23403,9 @@ snapshots: '@oxc-transform/binding-openharmony-arm64@0.124.0': optional: true - '@oxc-transform/binding-wasm32-wasi@0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + '@oxc-transform/binding-wasm32-wasi@0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -23350,66 +23689,102 @@ snapshots: '@rolldown/binding-android-arm64@1.0.0-rc.4': optional: true + '@rolldown/binding-android-arm64@1.0.2': + optional: true + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': optional: true '@rolldown/binding-darwin-arm64@1.0.0-rc.4': optional: true + '@rolldown/binding-darwin-arm64@1.0.2': + optional: true + '@rolldown/binding-darwin-x64@1.0.0-rc.15': optional: true '@rolldown/binding-darwin-x64@1.0.0-rc.4': optional: true + '@rolldown/binding-darwin-x64@1.0.2': + optional: true + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': optional: true '@rolldown/binding-freebsd-x64@1.0.0-rc.4': optional: true + '@rolldown/binding-freebsd-x64@1.0.2': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': optional: true '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.4': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.2': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': optional: true '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.4': optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.2': + optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': optional: true '@rolldown/binding-linux-arm64-musl@1.0.0-rc.4': optional: true + '@rolldown/binding-linux-arm64-musl@1.0.2': + optional: true + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-ppc64-gnu@1.0.2': + optional: true + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-s390x-gnu@1.0.2': + optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': optional: true '@rolldown/binding-linux-x64-gnu@1.0.0-rc.4': optional: true + '@rolldown/binding-linux-x64-gnu@1.0.2': + optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': optional: true '@rolldown/binding-linux-x64-musl@1.0.0-rc.4': optional: true + '@rolldown/binding-linux-x64-musl@1.0.2': + optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': optional: true '@rolldown/binding-openharmony-arm64@1.0.0-rc.4': optional: true + '@rolldown/binding-openharmony-arm64@1.0.2': + optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': dependencies: '@emnapi/core': 1.9.2 @@ -23417,32 +23792,47 @@ snapshots: '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + '@rolldown/binding-wasm32-wasi@1.0.0-rc.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' optional: true + '@rolldown/binding-wasm32-wasi@1.0.2': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': optional: true '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.4': optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.2': + optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': optional: true '@rolldown/binding-win32-x64-msvc@1.0.0-rc.4': optional: true + '@rolldown/binding-win32-x64-msvc@1.0.2': + optional: true + '@rolldown/pluginutils@1.0.0-rc.15': {} '@rolldown/pluginutils@1.0.0-rc.3': {} '@rolldown/pluginutils@1.0.0-rc.4': {} + '@rolldown/pluginutils@1.0.1': {} + '@rollup/plugin-json@6.1.0(rollup@4.60.1)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.60.1) @@ -23984,10 +24374,10 @@ snapshots: - react - react-dom - '@storybook/angular@10.3.5(f55f33330bfbd6fb184961c0aca35221)': + '@storybook/angular@10.3.5(56fe732b02a35e211a39a35ea47e2513)': dependencies: '@angular-devkit/architect': 0.2102.7(chokidar@5.0.0) - '@angular-devkit/build-angular': 21.2.7(0d8d439723faf789318b03d836c4657d) + '@angular-devkit/build-angular': 21.2.7(b8f20a26ea5ae043ece601bbe8d4f9d0) '@angular-devkit/core': 21.2.7(chokidar@5.0.0) '@angular/common': 21.2.8(@angular/core@21.2.8(@angular/compiler@21.2.8)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) '@angular/compiler': 21.2.8 @@ -24179,14 +24569,14 @@ snapshots: '@swc/core': 1.15.24(@swc/helpers@0.5.21) '@swc/types': 0.1.26 - '@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2)': + '@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2)': dependencies: '@swc-node/core': 1.14.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26) '@swc-node/sourcemap-support': 0.6.1 '@swc/core': 1.15.24(@swc/helpers@0.5.21) colorette: 2.0.20 debug: 4.4.3 - oxc-resolver: 11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + oxc-resolver: 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) pirates: 4.0.7 tslib: 2.8.1 typescript: 6.0.2 @@ -25143,6 +25533,10 @@ snapshots: dependencies: vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.3) + '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))': + dependencies: + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3) + '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))': dependencies: vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3) @@ -25159,6 +25553,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/browser-playwright@4.1.4(playwright@1.59.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': + dependencies: + '@vitest/browser': 4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) + '@vitest/mocker': 4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)) + playwright: 1.59.1 + tinyrainbow: 3.1.0 + vitest: 4.1.4(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(@vitest/ui@4.1.4)(happy-dom@20.8.9)(jsdom@29.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + optional: true + '@vitest/browser-playwright@4.1.4(playwright@1.59.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': dependencies: '@vitest/browser': 4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) @@ -25186,6 +25594,24 @@ snapshots: - utf-8-validate - vite + '@vitest/browser@4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': + dependencies: + '@blazediff/core': 1.9.1 + '@vitest/mocker': 4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)) + '@vitest/utils': 4.1.4 + magic-string: 0.30.21 + pngjs: 7.0.0 + sirv: 3.0.2 + tinyrainbow: 3.1.0 + vitest: 4.1.4(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(@vitest/ui@4.1.4)(happy-dom@20.8.9)(jsdom@29.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)) + ws: 8.20.0 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + optional: true + '@vitest/browser@4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4)': dependencies: '@blazediff/core': 1.9.1 @@ -25254,6 +25680,15 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 + '@vitest/mocker@4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))': + dependencies: + '@vitest/spy': 4.1.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3) + optional: true + '@vitest/mocker@4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.4 @@ -25904,7 +26339,7 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@10.0.0(@babel/core@7.29.0)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + babel-loader@10.0.0(@babel/core@7.29.0)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: '@babel/core': 7.29.0 find-up: 5.0.0 @@ -26693,7 +27128,7 @@ snapshots: serialize-javascript: 6.0.2 webpack: 5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7) - copy-webpack-plugin@14.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + copy-webpack-plugin@14.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 @@ -26871,7 +27306,7 @@ snapshots: webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) optional: true - css-loader@7.1.3(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + css-loader@7.1.3(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: icss-utils: 5.1.0(postcss@8.5.9) postcss: 8.5.9 @@ -27478,9 +27913,9 @@ snapshots: dset@3.1.4: {} - dts-resolver@2.1.3(oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)): + dts-resolver@2.1.3(oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)): optionalDependencies: - oxc-resolver: 11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + oxc-resolver: 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) dunder-proto@1.0.1: dependencies: @@ -27574,11 +28009,11 @@ snapshots: env-paths@2.2.1: {} - env-runner@0.1.7: + env-runner@0.1.9: dependencies: crossws: 0.4.5(srvx@0.11.15) exsolve: 1.0.8 - httpxy: 0.5.0 + httpxy: 0.5.3 srvx: 0.11.15 environment@1.1.0: {} @@ -28552,7 +28987,7 @@ snapshots: ufo: 1.6.3 uncrypto: 0.1.3 - h3@2.0.1-rc.20(crossws@0.4.5(srvx@0.11.15)): + h3@2.0.1-rc.22(crossws@0.4.5(srvx@0.11.15)): dependencies: rou3: 0.8.1 srvx: 0.11.15 @@ -28834,6 +29269,18 @@ snapshots: webpack: 5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7) optional: true + html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.18.1 + pretty-error: 4.0.0 + tapable: 2.3.2 + optionalDependencies: + '@rspack/core': 1.7.11(@swc/helpers@0.5.21) + webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) + optional: true + html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: '@types/html-minifier-terser': 6.1.0 @@ -28966,7 +29413,7 @@ snapshots: transitivePeerDependencies: - supports-color - httpxy@0.5.0: {} + httpxy@0.5.3: {} human-signals@1.1.1: {} @@ -29758,7 +30205,7 @@ snapshots: webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) optional: true - less-loader@12.3.1(@rspack/core@1.7.11(@swc/helpers@0.5.21))(less@4.4.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + less-loader@12.3.1(@rspack/core@1.7.11(@swc/helpers@0.5.21))(less@4.4.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: less: 4.4.2 optionalDependencies: @@ -29834,7 +30281,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + license-webpack-plugin@4.0.2(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: webpack-sources: 3.3.4 optionalDependencies: @@ -30765,7 +31212,7 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.10.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + mini-css-extract-plugin@2.10.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: schema-utils: 4.3.3 tapable: 2.3.2 @@ -30922,7 +31369,7 @@ snapshots: nerf-dart@1.0.0: {} - nf3@0.3.16: {} + nf3@0.3.17: {} ng-packagr@21.2.2(@angular/compiler-cli@21.2.8(@angular/compiler@21.2.8)(typescript@6.0.2))(tailwindcss@4.2.2)(tslib@2.8.1)(typescript@6.0.2): dependencies: @@ -30954,19 +31401,19 @@ snapshots: rollup: 4.60.1 tailwindcss: 4.2.2 - nitro@3.0.260415-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)): + nitro@3.0.260522-beta(chokidar@5.0.0)(dotenv@16.4.7)(jiti@2.6.1)(lru-cache@11.3.5)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)): dependencies: consola: 3.4.2 crossws: 0.4.5(srvx@0.11.15) db0: 0.3.4 - env-runner: 0.1.7 - h3: 2.0.1-rc.20(crossws@0.4.5(srvx@0.11.15)) + env-runner: 0.1.9 + h3: 2.0.1-rc.22(crossws@0.4.5(srvx@0.11.15)) hookable: 6.1.1 - nf3: 0.3.16 + nf3: 0.3.17 ocache: 0.1.4 ofetch: 2.0.0-alpha.3 ohash: 2.0.11 - rolldown: 1.0.0-rc.15 + rolldown: 1.0.2 srvx: 0.11.15 unenv: 2.0.0-rc.24 unstorage: 2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4)(lru-cache@11.3.5)(ofetch@2.0.0-alpha.3) @@ -31169,7 +31616,7 @@ snapshots: schema-utils: 3.3.0 webpack: 5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7) - nx@22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)): + nx@22.6.5(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 '@yarnpkg/lockfile': 1.1.0 @@ -31218,12 +31665,12 @@ snapshots: '@nx/nx-linux-x64-musl': 22.6.5 '@nx/nx-win32-arm64-msvc': 22.6.5 '@nx/nx-win32-x64-msvc': 22.6.5 - '@swc-node/register': 1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2) + '@swc-node/register': 1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2) '@swc/core': 1.15.24(@swc/helpers@0.5.21) transitivePeerDependencies: - debug - nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)): + nx@22.7.0-beta.12(@swc-node/register@1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2))(@swc/core@1.15.24(@swc/helpers@0.5.21)): dependencies: '@emnapi/core': 1.4.5 '@emnapi/runtime': 1.4.5 @@ -31346,7 +31793,7 @@ snapshots: '@nx/nx-linux-x64-musl': 22.7.0-beta.12 '@nx/nx-win32-arm64-msvc': 22.7.0-beta.12 '@nx/nx-win32-x64-msvc': 22.7.0-beta.12 - '@swc-node/register': 1.11.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2) + '@swc-node/register': 1.11.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@swc/core@1.15.24(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@6.0.2) '@swc/core': 1.15.24(@swc/helpers@0.5.21) transitivePeerDependencies: - debug @@ -31503,7 +31950,7 @@ snapshots: os-tmpdir@1.0.2: {} - oxc-parser@0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2): + oxc-parser@0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): dependencies: '@oxc-project/types': 0.124.0 optionalDependencies: @@ -31523,7 +31970,7 @@ snapshots: '@oxc-parser/binding-linux-x64-gnu': 0.124.0 '@oxc-parser/binding-linux-x64-musl': 0.124.0 '@oxc-parser/binding-openharmony-arm64': 0.124.0 - '@oxc-parser/binding-wasm32-wasi': 0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@oxc-parser/binding-wasm32-wasi': 0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) '@oxc-parser/binding-win32-arm64-msvc': 0.124.0 '@oxc-parser/binding-win32-ia32-msvc': 0.124.0 '@oxc-parser/binding-win32-x64-msvc': 0.124.0 @@ -31531,7 +31978,7 @@ snapshots: - '@emnapi/core' - '@emnapi/runtime' - oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2): + oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): optionalDependencies: '@oxc-resolver/binding-android-arm-eabi': 11.19.1 '@oxc-resolver/binding-android-arm64': 11.19.1 @@ -31549,7 +31996,7 @@ snapshots: '@oxc-resolver/binding-linux-x64-gnu': 11.19.1 '@oxc-resolver/binding-linux-x64-musl': 11.19.1 '@oxc-resolver/binding-openharmony-arm64': 11.19.1 - '@oxc-resolver/binding-wasm32-wasi': 11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@oxc-resolver/binding-wasm32-wasi': 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) '@oxc-resolver/binding-win32-arm64-msvc': 11.19.1 '@oxc-resolver/binding-win32-ia32-msvc': 11.19.1 '@oxc-resolver/binding-win32-x64-msvc': 11.19.1 @@ -31557,7 +32004,7 @@ snapshots: - '@emnapi/core' - '@emnapi/runtime' - oxc-transform@0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2): + oxc-transform@0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): optionalDependencies: '@oxc-transform/binding-android-arm-eabi': 0.124.0 '@oxc-transform/binding-android-arm64': 0.124.0 @@ -31575,7 +32022,7 @@ snapshots: '@oxc-transform/binding-linux-x64-gnu': 0.124.0 '@oxc-transform/binding-linux-x64-musl': 0.124.0 '@oxc-transform/binding-openharmony-arm64': 0.124.0 - '@oxc-transform/binding-wasm32-wasi': 0.124.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@oxc-transform/binding-wasm32-wasi': 0.124.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) '@oxc-transform/binding-win32-arm64-msvc': 0.124.0 '@oxc-transform/binding-win32-ia32-msvc': 0.124.0 '@oxc-transform/binding-win32-x64-msvc': 0.124.0 @@ -32190,7 +32637,7 @@ snapshots: - typescript optional: true - postcss-loader@8.2.0(@rspack/core@1.7.11(@swc/helpers@0.5.21))(postcss@8.5.6)(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + postcss-loader@8.2.0(@rspack/core@1.7.11(@swc/helpers@0.5.21))(postcss@8.5.6)(typescript@6.0.2)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: cosmiconfig: 9.0.1(typescript@6.0.2) jiti: 2.6.1 @@ -33207,7 +33654,7 @@ snapshots: robust-predicates@3.0.3: {} - rolldown-plugin-dts@0.23.2(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2))(rolldown@1.0.0-rc.15)(typescript@6.0.2): + rolldown-plugin-dts@0.23.2(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rolldown@1.0.0-rc.15)(typescript@6.0.2): dependencies: '@babel/generator': 8.0.0-rc.3 '@babel/helper-validator-identifier': 8.0.0-rc.3 @@ -33215,7 +33662,7 @@ snapshots: '@babel/types': 8.0.0-rc.3 ast-kit: 3.0.0-beta.1 birpc: 4.0.0 - dts-resolver: 2.1.3(oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)) + dts-resolver: 2.1.3(oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)) get-tsconfig: 4.13.7 obug: 2.1.1 picomatch: 4.0.4 @@ -33247,7 +33694,7 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 - rolldown@1.0.0-rc.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2): + rolldown@1.0.0-rc.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): dependencies: '@oxc-project/types': 0.113.0 '@rolldown/pluginutils': 1.0.0-rc.4 @@ -33262,13 +33709,34 @@ snapshots: '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.4 '@rolldown/binding-linux-x64-musl': 1.0.0-rc.4 '@rolldown/binding-openharmony-arm64': 1.0.0-rc.4 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.4 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.4 transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' + rolldown@1.0.2: + dependencies: + '@oxc-project/types': 0.132.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.2 + '@rolldown/binding-darwin-arm64': 1.0.2 + '@rolldown/binding-darwin-x64': 1.0.2 + '@rolldown/binding-freebsd-x64': 1.0.2 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.2 + '@rolldown/binding-linux-arm64-gnu': 1.0.2 + '@rolldown/binding-linux-arm64-musl': 1.0.2 + '@rolldown/binding-linux-ppc64-gnu': 1.0.2 + '@rolldown/binding-linux-s390x-gnu': 1.0.2 + '@rolldown/binding-linux-x64-gnu': 1.0.2 + '@rolldown/binding-linux-x64-musl': 1.0.2 + '@rolldown/binding-openharmony-arm64': 1.0.2 + '@rolldown/binding-wasm32-wasi': 1.0.2 + '@rolldown/binding-win32-arm64-msvc': 1.0.2 + '@rolldown/binding-win32-x64-msvc': 1.0.2 + rollup-plugin-dts@6.4.1(rollup@4.60.1)(typescript@6.0.2): dependencies: '@jridgewell/remapping': 2.3.5 @@ -33481,7 +33949,7 @@ snapshots: sass-embedded: 1.99.0 webpack: 5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7) - sass-loader@16.0.7(@rspack/core@1.7.11(@swc/helpers@0.5.21))(sass-embedded@1.99.0)(sass@1.97.3)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + sass-loader@16.0.7(@rspack/core@1.7.11(@swc/helpers@0.5.21))(sass-embedded@1.99.0)(sass@1.97.3)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: neo-async: 2.6.2 optionalDependencies: @@ -33938,7 +34406,7 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + source-map-loader@5.0.0(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 @@ -34526,7 +34994,7 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tsdown@0.21.8(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2))(synckit@0.11.12)(typescript@6.0.2): + tsdown@0.21.8(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(synckit@0.11.12)(typescript@6.0.2): dependencies: ansis: 4.2.0 cac: 7.0.0 @@ -34537,7 +35005,7 @@ snapshots: obug: 2.1.1 picomatch: 4.0.4 rolldown: 1.0.0-rc.15 - rolldown-plugin-dts: 0.23.2(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2))(rolldown@1.0.0-rc.15)(typescript@6.0.2) + rolldown-plugin-dts: 0.23.2(@typescript/native-preview@7.0.0-dev.20260412.1)(oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rolldown@1.0.0-rc.15)(typescript@6.0.2) semver: 7.7.4 tinyexec: 1.1.1 tinyglobby: 0.2.16 @@ -34954,10 +35422,10 @@ snapshots: - typescript - ws - vite-tsconfig-paths@7.0.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)): + vite-tsconfig-paths@7.0.0-alpha.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(typescript@6.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)): dependencies: debug: 4.4.3 - oxc-resolver: 11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + oxc-resolver: 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) tsconfck: 3.1.6(typescript@6.0.2) vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3) transitivePeerDependencies: @@ -34985,6 +35453,25 @@ snapshots: terser: 5.46.0 yaml: 2.8.3 + vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3): + dependencies: + esbuild: 0.27.7 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.9 + rollup: 4.60.1 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 25.6.0 + fsevents: 2.3.3 + jiti: 2.6.1 + less: 4.4.2 + lightningcss: 1.32.0 + sass: 1.97.3 + sass-embedded: 1.99.0 + terser: 5.46.1 + yaml: 2.8.3 + vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3): dependencies: esbuild: 0.27.7 @@ -35023,6 +35510,25 @@ snapshots: terser: 5.46.1 yaml: 2.8.3 + vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.9 + rolldown: 1.0.0-rc.15 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 25.6.0 + esbuild: 0.27.7 + fsevents: 2.3.3 + jiti: 2.6.1 + less: 4.4.2 + sass: 1.97.3 + sass-embedded: 1.99.0 + terser: 5.46.1 + yaml: 2.8.3 + optional: true + vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3): dependencies: lightningcss: 1.32.0 @@ -35067,6 +35573,39 @@ snapshots: optionalDependencies: vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3) + vitest@4.1.4(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(@vitest/ui@4.1.4)(happy-dom@20.8.9)(jsdom@29.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)): + dependencies: + '@vitest/expect': 4.1.4 + '@vitest/mocker': 4.1.4(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.4 + '@vitest/runner': 4.1.4 + '@vitest/snapshot': 4.1.4 + '@vitest/spy': 4.1.4 + '@vitest/utils': 4.1.4 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.0.0 + tinybench: 2.9.0 + tinyexec: 1.1.1 + tinyglobby: 0.2.16 + tinyrainbow: 3.1.0 + vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.6.0 + '@vitest/browser-playwright': 4.1.4(playwright@1.59.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.2)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.4) + '@vitest/coverage-v8': 4.1.4(@vitest/browser@4.1.4)(vitest@4.1.4) + '@vitest/ui': 4.1.4(vitest@4.1.4) + happy-dom: 20.8.9 + jsdom: 29.0.2 + transitivePeerDependencies: + - msw + optional: true + vitest@4.1.4(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(@vitest/ui@4.1.4)(happy-dom@20.8.9)(jsdom@29.0.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.97.3)(terser@5.46.1)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.4 @@ -35220,7 +35759,7 @@ snapshots: optionalDependencies: webpack: 5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7) - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: colorette: 2.0.20 memfs: 4.57.1(tslib@2.8.1) @@ -35246,7 +35785,7 @@ snapshots: transitivePeerDependencies: - tslib - webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): + webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -35274,7 +35813,7 @@ snapshots: serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) ws: 8.20.0 optionalDependencies: webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) @@ -35361,6 +35900,13 @@ snapshots: optionalDependencies: html-webpack-plugin: 5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)): + dependencies: + typed-assert: 1.0.9 + webpack: 5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3) + optionalDependencies: + html-webpack-plugin: 5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)) + webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.7.11(@swc/helpers@0.5.21))(webpack@5.106.1(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.7)))(webpack@5.105.2(@swc/core@1.15.24(@swc/helpers@0.5.21))(esbuild@0.27.3)): dependencies: typed-assert: 1.0.9 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 70ac3ef82..8a3f33f61 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -80,6 +80,7 @@ catalog: '@angular/cli': 21.2.7 '@angular/compiler-cli': 21.2.8 '@angular/language-service': 21.2.8 + '@babel/core': ^7.28.6 '@commitlint/cli': ^20.5.0 '@commitlint/config-conventional': ^20.5.0 '@compodoc/compodoc': ^1.2.1 @@ -138,7 +139,7 @@ catalog: mermaid: ^11.13.0 minimist: ^1.2.8 ng-packagr: 21.2.2 - nitro: 3.0.260415-beta + nitro: 3.0.260522-beta nx: 22.7.0-beta.12 obug: ^2.1.1 ofetch: 2.0.0-alpha.3 diff --git a/tools/scripts/build-release.mts b/tools/scripts/build-release.mts index ae4d333b4..b24f34baf 100644 --- a/tools/scripts/build-release.mts +++ b/tools/scripts/build-release.mts @@ -213,9 +213,26 @@ function runStep(step: Step): void { cwd: root, stdio: 'inherit', env: process.env, + shell: process.platform === 'win32', }); } +// Wire git hooks. Previously the prepare script ran +// `git config core.hookspath .githooks || true && node tools/scripts/build-release.mts`, +// but cmd.exe doesn't have a `true` builtin, so the entire chain short- +// circuits on Windows before the build steps run. Move the git-config +// step into the script so a missing/failed git invocation can't block +// the rest of the prepare work. +try { + execFileSync('git', ['config', 'core.hookspath', '.githooks'], { + cwd: root, + stdio: 'ignore', + shell: process.platform === 'win32', + }); +} catch { + // Not a git checkout, or git isn't available — skip silently. +} + for (const step of steps) { runStep(step); } diff --git a/tools/scripts/verify-package-artifacts.mts b/tools/scripts/verify-package-artifacts.mts index 8fc9ee5ab..a003c2e01 100644 --- a/tools/scripts/verify-package-artifacts.mts +++ b/tools/scripts/verify-package-artifacts.mts @@ -119,7 +119,8 @@ const packageConfigs: Record = { manifestFields: ['builders', 'executors', 'generators', 'schematics'], requiredPaths: [ 'packages/platform/dist/src/lib/nx-plugin', - 'packages/platform/dist/src/lib/nx-plugin/src/executors/vite/vite.impl.js', + 'packages/platform/dist/src/lib/nx-plugin/src/builders/vite/vite-build.js', + 'packages/platform/dist/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.js', 'packages/platform/dist/src/lib/nx-plugin/src/generators/preset/generator.js', ], },