@analogjs/platform 3.0.0-alpha.23 → 3.0.0-alpha.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/package.json +5 -4
  2. package/src/lib/content-plugin.js +6 -1
  3. package/src/lib/content-plugin.js.map +1 -1
  4. package/src/lib/deps-plugin.js +1 -0
  5. package/src/lib/deps-plugin.js.map +1 -1
  6. package/src/lib/discover-library-routes.js +1 -1
  7. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js +13 -0
  8. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js.map +1 -0
  9. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.js +8 -0
  10. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.js.map +1 -0
  11. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.js +9 -0
  12. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.js.map +1 -0
  13. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.js +4 -1
  14. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.js.map +1 -1
  15. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.d.ts +1 -0
  16. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.js +13 -0
  17. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.js.map +1 -1
  18. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.d.ts +7 -5
  19. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js +4 -0
  20. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js.map +1 -1
  21. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.d.ts +1 -1
  22. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.js +2 -0
  23. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.js.map +1 -1
  24. package/src/lib/nx-plugin/src/generators/page/generator.js +2 -1
  25. package/src/lib/nx-plugin/src/generators/page/generator.js.map +1 -1
  26. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.d.ts +5 -5
  27. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js +5 -5
  28. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js.map +1 -1
  29. package/src/lib/options.d.ts +8 -2
  30. package/src/lib/platform-plugin.js +13 -16
  31. package/src/lib/platform-plugin.js.map +1 -1
  32. package/src/lib/route-idiom-diagnostics.d.ts +13 -0
  33. package/src/lib/route-idiom-diagnostics.js +160 -0
  34. package/src/lib/route-idiom-diagnostics.js.map +1 -0
  35. package/src/lib/route-manifest.d.ts +0 -6
  36. package/src/lib/route-manifest.js.map +1 -1
  37. package/src/lib/router-plugin.js +41 -0
  38. package/src/lib/router-plugin.js.map +1 -1
  39. package/src/lib/tailwind-preprocessor.js +1 -1
  40. package/src/lib/typed-routes-plugin.js +1 -1
  41. package/src/lib/utils/debug-harness.d.ts +23 -0
  42. package/src/lib/utils/debug-harness.js +88 -0
  43. package/src/lib/utils/debug-harness.js.map +1 -0
  44. package/src/lib/utils/debug-log-file.d.ts +5 -0
  45. package/src/lib/utils/debug-log-file.js +56 -0
  46. package/src/lib/utils/debug-log-file.js.map +1 -0
  47. package/src/lib/utils/debug.d.ts +9 -28
  48. package/src/lib/utils/debug.js +18 -67
  49. package/src/lib/utils/debug.js.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/platform",
3
- "version": "3.0.0-alpha.23",
3
+ "version": "3.0.0-alpha.25",
4
4
  "description": "The fullstack meta-framework for Angular",
5
5
  "type": "module",
6
6
  "author": "Brandon Roberts <robertsbt@gmail.com>",
@@ -32,11 +32,12 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "front-matter": "^4.0.2",
35
+ "es-toolkit": "^1.45.1",
35
36
  "tinyglobby": "^0.2.15",
36
37
  "nitro": "3.0.260311-beta",
37
- "@analogjs/vite-plugin-angular": "^3.0.0-alpha.23",
38
- "@analogjs/vite-plugin-nitro": "^3.0.0-alpha.23",
39
- "rolldown": "^1.0.0-rc.12",
38
+ "@analogjs/vite-plugin-angular": "3.0.0-alpha.25",
39
+ "@analogjs/vite-plugin-nitro": "3.0.0-alpha.25",
40
+ "rolldown": "^1.0.0-rc.13",
40
41
  "obug": "^2.1.1",
41
42
  "vitefu": "^1.1.2"
42
43
  },
@@ -1,6 +1,6 @@
1
1
  import { getBundleOptionsKey } from "./utils/rolldown.js";
2
- import { readFileSync } from "node:fs";
3
2
  import { relative, resolve } from "node:path";
3
+ import { readFileSync } from "node:fs";
4
4
  import * as vite from "vite";
5
5
  import { globSync } from "tinyglobby";
6
6
  //#region packages/platform/src/lib/content-plugin.ts
@@ -84,6 +84,11 @@ function contentPlugin({ highlighter, markedOptions, shikiOptions, prismOptions
84
84
  }
85
85
  });
86
86
  });
87
+ server.ws.send("analog:debug-full-reload", {
88
+ plugin: "platform:content-plugin",
89
+ reason: "content-file-set-changed",
90
+ path: normalizedPath
91
+ });
87
92
  server.ws.send({ type: "full-reload" });
88
93
  }
89
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"content-plugin.js","names":[],"sources":["../../../src/lib/content-plugin.ts"],"sourcesContent":["import * as vite from 'vite';\nimport { readFileSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport { globSync } from 'tinyglobby';\n\nimport type { WithShikiHighlighterOptions } from './content/shiki/options.js';\nimport type { MarkedContentHighlighter } from './content/marked/marked-content-highlighter.js';\nimport type { WithPrismHighlighterOptions } from './content/prism/options.js';\nimport type { WithMarkedOptions } from './content/marked/index.js';\nimport type { Options } from './options.js';\nimport { getBundleOptionsKey } from './utils/rolldown.js';\n\ninterface Content {\n code: string;\n attributes: string;\n}\n\nexport type ContentPluginOptions = {\n highlighter?: 'shiki' | 'prism';\n markedOptions?: WithMarkedOptions;\n shikiOptions?: WithShikiHighlighterOptions;\n prismOptions?: WithPrismHighlighterOptions;\n};\n\n/**\n * Content plugin that provides markdown and content file processing for Analog.\n *\n * IMPORTANT: This plugin uses tinyglobby for file discovery.\n * Key pitfall with { dot: true }:\n * - Returns relative paths from cwd (e.g., \"apps/blog-app/src/content/...\")\n * - These paths CANNOT be used directly in ES module imports\n * - Relative paths without ./ or ../ are treated as package names\n * - Must convert to absolute paths for imports to work correctly\n */\nexport function contentPlugin(\n {\n highlighter,\n markedOptions,\n shikiOptions,\n prismOptions,\n }: ContentPluginOptions = {},\n options?: Options,\n): vite.Plugin[] {\n const cache = new Map<string, Content>();\n // The content list placeholder can be transformed several times during serve.\n // Caching the discovered markdown paths keeps those repeat passes cheap.\n let contentFilesListCache: string[] | undefined;\n\n let markedHighlighter: MarkedContentHighlighter;\n const workspaceRoot = vite.normalizePath(\n options?.workspaceRoot ?? process.env['NX_WORKSPACE_ROOT'] ?? process.cwd(),\n );\n let config: vite.UserConfig;\n let root: string;\n // Keep discovery and invalidation aligned by deriving both from the same\n // normalized content roots. That way external content dirs participate in\n // cache busting exactly the same way they participate in glob discovery.\n // Initialized once in the `config` hook after `root` is resolved — all\n // inputs (`root`, `workspaceRoot`, `options`) are stable after that point.\n let contentRootDirs: string[];\n const normalizeContentDir = (dir: string) => {\n const normalized = vite.normalizePath(\n dir.startsWith('/')\n ? `${workspaceRoot}${dir}`\n : resolve(workspaceRoot, dir),\n );\n return normalized.endsWith('/') ? normalized.slice(0, -1) : normalized;\n };\n const initContentRootDirs = () => {\n contentRootDirs = [\n vite.normalizePath(`${root}/src/content`),\n ...(options?.additionalContentDirs || []).map(normalizeContentDir),\n ];\n };\n const discoverContentFilesList = () => {\n contentFilesListCache ??= globSync(\n contentRootDirs.map((dir) => `${dir}/**/*.md`),\n { dot: true },\n );\n\n return contentFilesListCache;\n };\n const resolveContentModulePath = (module: string) =>\n vite.normalizePath(\n module.startsWith('/') ? module : `${workspaceRoot}/${module}`,\n );\n const getContentModuleKey = (module: string) => {\n const absolutePath = resolveContentModulePath(module);\n const relativeToRoot = vite.normalizePath(relative(root, absolutePath));\n // `startsWith(root)` is not safe here because sibling directories such as\n // `/apps/my-app-tools` also start with `/apps/my-app`. A relative path only\n // represents in-app content when it stays within `root`.\n const isInApp =\n !relativeToRoot.startsWith('..') && !relativeToRoot.startsWith('/');\n\n // Both branches prepend `/` so generated keys are always absolute-\n // looking (`/src/content/...` for in-app, `/libs/shared/...` for\n // workspace-external). Downstream consumers like content-files-token\n // rely on the leading `/` for slug extraction regexes.\n return isInApp\n ? `/${relativeToRoot}`\n : `/${vite.normalizePath(relative(workspaceRoot, absolutePath))}`;\n };\n\n const contentDiscoveryPlugins: vite.Plugin[] = [\n {\n name: 'analog-content-glob-routes',\n config(_config) {\n config = _config;\n root = vite.normalizePath(\n resolve(workspaceRoot, config.root || '.') || '.',\n );\n initContentRootDirs();\n },\n // Vite 8 / Rolldown \"filtered transform\" — the `filter.code` string\n // tells the bundler to skip this handler entirely for modules whose\n // source does not contain the substring, avoiding unnecessary JS→Rust\n // round-trips. The inner `code.includes()` guard is kept for Vite 7\n // compat where filters are not evaluated by the bundler.\n transform: {\n filter: {\n code: 'ANALOG_CONTENT_FILE_LIST',\n },\n handler(code) {\n if (code.includes('ANALOG_CONTENT_FILE_LIST')) {\n const contentFilesList = discoverContentFilesList();\n\n const eagerImports: string[] = [];\n\n contentFilesList.forEach((module, index) => {\n // CRITICAL: tinyglobby returns relative paths like \"apps/blog-app/src/content/file.md\"\n // These MUST be converted to absolute paths for ES module imports\n // Otherwise Node.js treats \"apps\" as a package name and throws \"Cannot find package 'apps'\"\n const absolutePath = resolveContentModulePath(module);\n eagerImports.push(\n `import { default as analog_module_${index} } from \"${absolutePath}?analog-content-list=true\";`,\n );\n });\n\n let result = code.replace(\n 'const ANALOG_CONTENT_FILE_LIST = {};',\n `\n let ANALOG_CONTENT_FILE_LIST = {${contentFilesList.map(\n (module, index) =>\n `\"${getContentModuleKey(module)}\": analog_module_${index}`,\n )}};\n `,\n );\n\n if (!code.includes('analog_module_')) {\n result = `${eagerImports.join('\\n')}\\n${result}`;\n }\n\n return {\n code: result,\n map: { mappings: '' },\n };\n }\n\n return;\n },\n },\n },\n {\n name: 'analogjs-invalidate-content-dirs',\n configureServer(server) {\n function invalidateContent(path: string) {\n const normalizedPath = vite.normalizePath(path);\n const isContentPath = contentRootDirs.some(\n (dir) =>\n normalizedPath === dir || normalizedPath.startsWith(`${dir}/`),\n );\n\n if (isContentPath) {\n // The file set only changes on add/remove because this watcher is\n // intentionally scoped to those events. Clear the list cache so the\n // next transform sees the updated directory contents.\n contentFilesListCache = undefined;\n server.moduleGraph.fileToModulesMap.forEach((mods) => {\n mods.forEach((mod) => {\n if (\n mod.id?.includes('analogjs') &&\n mod.id?.includes('content')\n ) {\n server.moduleGraph.invalidateModule(mod);\n\n mod.importers.forEach((imp) => {\n server.moduleGraph.invalidateModule(imp);\n });\n }\n });\n });\n\n server.ws.send({\n type: 'full-reload',\n });\n }\n }\n\n server.watcher.on('add', invalidateContent);\n server.watcher.on('unlink', invalidateContent);\n },\n },\n ];\n\n if (!highlighter) {\n return [\n {\n name: 'analogjs-external-content',\n config() {\n const bundleOptionsKey = getBundleOptionsKey();\n return {\n build: {\n [bundleOptionsKey]: {\n external: ['@analogjs/content'],\n },\n },\n };\n },\n },\n {\n name: 'analogjs-exclude-content-import',\n transform: {\n filter: {\n code: '@analogjs/content',\n },\n handler(code) {\n /**\n * Remove the package so it doesn't get\n * referenced when building for serverless\n * functions.\n */\n if (code.includes(`import('@analogjs/content')`)) {\n return {\n code: code.replace(\n `import('@analogjs/content')`,\n 'Promise.resolve({})',\n ),\n };\n }\n\n return;\n },\n },\n },\n ...contentDiscoveryPlugins,\n ];\n }\n\n return [\n {\n name: 'analogjs-content-frontmatter',\n // Filter by module ID so only `?analog-content-list=true` virtual\n // imports enter the handler. Returns `moduleSideEffects: false` so\n // Rolldown can tree-shake unused content list entries.\n transform: {\n filter: {\n id: /analog-content-list=true/,\n },\n async handler(code, id) {\n const cachedContent = cache.get(id);\n // There's no reason to run `readFileSync` and frontmatter parsing if the\n // `transform` hook is called with the same code. In such cases, we can simply\n // return the cached attributes, which is faster than repeatedly reading files\n // synchronously during the build process.\n if (cachedContent?.code === code) {\n return {\n code: `export default ${cachedContent.attributes}`,\n moduleSideEffects: false,\n };\n }\n\n const fm: any = await import('front-matter');\n // The `default` property will be available in CommonJS environment, for instance,\n // when running unit tests. It's safe to retrieve `default` first, since we still\n // fallback to the original implementation.\n const frontmatter = fm.default || fm;\n const fileContents = readFileSync(id.split('?')[0], 'utf8');\n const { attributes } = frontmatter(fileContents);\n const content = {\n code,\n attributes: JSON.stringify(attributes),\n };\n cache.set(id, content);\n\n return {\n code: `export default ${content.attributes}`,\n moduleSideEffects: false,\n };\n },\n },\n },\n {\n name: 'analogjs-content-file',\n enforce: 'post',\n async load(id) {\n if (!id.includes('analog-content-file=true')) {\n return;\n }\n\n if (!markedHighlighter) {\n if (highlighter === 'shiki') {\n const { getShikiHighlighter } =\n await import('./content/shiki/index.js');\n markedHighlighter = getShikiHighlighter(shikiOptions);\n } else {\n const { getPrismHighlighter } =\n await import('./content/prism/index.js');\n markedHighlighter = getPrismHighlighter();\n\n const langs = [\n 'bash',\n 'css',\n 'javascript',\n 'json',\n 'markup',\n 'typescript',\n ];\n\n if (\n Array.isArray(prismOptions?.additionalLangs) &&\n prismOptions?.additionalLangs?.length > 0\n ) {\n langs.push(...prismOptions.additionalLangs);\n }\n\n const loadLanguages = await import('prismjs/components/index.js');\n\n (\n loadLanguages as unknown as { default: (...args: any[]) => any }\n ).default(langs);\n }\n }\n\n const fm: any = await import('front-matter');\n // The `default` property will be available in CommonJS environment, for instance,\n // when running unit tests. It's safe to retrieve `default` first, since we still\n // fallback to the original implementation.\n const frontmatterFn = fm.default || fm;\n const fileContents = readFileSync(id.split('?')[0], 'utf8');\n const { body, frontmatter } = frontmatterFn(fileContents);\n\n // parse markdown and highlight\n const { getMarkedSetup } = await import('./content/marked/index.js');\n const markedSetupService = getMarkedSetup(\n { mangle: true, ...(markedOptions || {}) },\n markedHighlighter,\n );\n const mdContent = (await markedSetupService\n .getMarkedInstance()\n .parse(body)) as unknown as string;\n\n return `export default ${JSON.stringify(\n `---\\n${frontmatter}\\n---\\n\\n${mdContent}`,\n )}`;\n },\n },\n ...contentDiscoveryPlugins,\n ];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"content-plugin.js","names":[],"sources":["../../../src/lib/content-plugin.ts"],"sourcesContent":["import * as vite from 'vite';\nimport { readFileSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport { globSync } from 'tinyglobby';\n\nimport type { WithShikiHighlighterOptions } from './content/shiki/options.js';\nimport type { MarkedContentHighlighter } from './content/marked/marked-content-highlighter.js';\nimport type { WithPrismHighlighterOptions } from './content/prism/options.js';\nimport type { WithMarkedOptions } from './content/marked/index.js';\nimport type { Options } from './options.js';\nimport { getBundleOptionsKey } from './utils/rolldown.js';\n\ninterface Content {\n code: string;\n attributes: string;\n}\n\nexport type ContentPluginOptions = {\n highlighter?: 'shiki' | 'prism';\n markedOptions?: WithMarkedOptions;\n shikiOptions?: WithShikiHighlighterOptions;\n prismOptions?: WithPrismHighlighterOptions;\n};\n\n/**\n * Content plugin that provides markdown and content file processing for Analog.\n *\n * IMPORTANT: This plugin uses tinyglobby for file discovery.\n * Key pitfall with { dot: true }:\n * - Returns relative paths from cwd (e.g., \"apps/blog-app/src/content/...\")\n * - These paths CANNOT be used directly in ES module imports\n * - Relative paths without ./ or ../ are treated as package names\n * - Must convert to absolute paths for imports to work correctly\n */\nexport function contentPlugin(\n {\n highlighter,\n markedOptions,\n shikiOptions,\n prismOptions,\n }: ContentPluginOptions = {},\n options?: Options,\n): vite.Plugin[] {\n const cache = new Map<string, Content>();\n // The content list placeholder can be transformed several times during serve.\n // Caching the discovered markdown paths keeps those repeat passes cheap.\n let contentFilesListCache: string[] | undefined;\n\n let markedHighlighter: MarkedContentHighlighter;\n const workspaceRoot = vite.normalizePath(\n options?.workspaceRoot ?? process.env['NX_WORKSPACE_ROOT'] ?? process.cwd(),\n );\n let config: vite.UserConfig;\n let root: string;\n // Keep discovery and invalidation aligned by deriving both from the same\n // normalized content roots. That way external content dirs participate in\n // cache busting exactly the same way they participate in glob discovery.\n // Initialized once in the `config` hook after `root` is resolved — all\n // inputs (`root`, `workspaceRoot`, `options`) are stable after that point.\n let contentRootDirs: string[];\n const normalizeContentDir = (dir: string) => {\n const normalized = vite.normalizePath(\n dir.startsWith('/')\n ? `${workspaceRoot}${dir}`\n : resolve(workspaceRoot, dir),\n );\n return normalized.endsWith('/') ? normalized.slice(0, -1) : normalized;\n };\n const initContentRootDirs = () => {\n contentRootDirs = [\n vite.normalizePath(`${root}/src/content`),\n ...(options?.additionalContentDirs || []).map(normalizeContentDir),\n ];\n };\n const discoverContentFilesList = () => {\n contentFilesListCache ??= globSync(\n contentRootDirs.map((dir) => `${dir}/**/*.md`),\n { dot: true },\n );\n\n return contentFilesListCache;\n };\n const resolveContentModulePath = (module: string) =>\n vite.normalizePath(\n module.startsWith('/') ? module : `${workspaceRoot}/${module}`,\n );\n const getContentModuleKey = (module: string) => {\n const absolutePath = resolveContentModulePath(module);\n const relativeToRoot = vite.normalizePath(relative(root, absolutePath));\n // `startsWith(root)` is not safe here because sibling directories such as\n // `/apps/my-app-tools` also start with `/apps/my-app`. A relative path only\n // represents in-app content when it stays within `root`.\n const isInApp =\n !relativeToRoot.startsWith('..') && !relativeToRoot.startsWith('/');\n\n // Both branches prepend `/` so generated keys are always absolute-\n // looking (`/src/content/...` for in-app, `/libs/shared/...` for\n // workspace-external). Downstream consumers like content-files-token\n // rely on the leading `/` for slug extraction regexes.\n return isInApp\n ? `/${relativeToRoot}`\n : `/${vite.normalizePath(relative(workspaceRoot, absolutePath))}`;\n };\n\n const contentDiscoveryPlugins: vite.Plugin[] = [\n {\n name: 'analog-content-glob-routes',\n config(_config) {\n config = _config;\n root = vite.normalizePath(\n resolve(workspaceRoot, config.root || '.') || '.',\n );\n initContentRootDirs();\n },\n // Vite 8 / Rolldown \"filtered transform\" — the `filter.code` string\n // tells the bundler to skip this handler entirely for modules whose\n // source does not contain the substring, avoiding unnecessary JS→Rust\n // round-trips. The inner `code.includes()` guard is kept for Vite 7\n // compat where filters are not evaluated by the bundler.\n transform: {\n filter: {\n code: 'ANALOG_CONTENT_FILE_LIST',\n },\n handler(code) {\n if (code.includes('ANALOG_CONTENT_FILE_LIST')) {\n const contentFilesList = discoverContentFilesList();\n\n const eagerImports: string[] = [];\n\n contentFilesList.forEach((module, index) => {\n // CRITICAL: tinyglobby returns relative paths like \"apps/blog-app/src/content/file.md\"\n // These MUST be converted to absolute paths for ES module imports\n // Otherwise Node.js treats \"apps\" as a package name and throws \"Cannot find package 'apps'\"\n const absolutePath = resolveContentModulePath(module);\n eagerImports.push(\n `import { default as analog_module_${index} } from \"${absolutePath}?analog-content-list=true\";`,\n );\n });\n\n let result = code.replace(\n 'const ANALOG_CONTENT_FILE_LIST = {};',\n `\n let ANALOG_CONTENT_FILE_LIST = {${contentFilesList.map(\n (module, index) =>\n `\"${getContentModuleKey(module)}\": analog_module_${index}`,\n )}};\n `,\n );\n\n if (!code.includes('analog_module_')) {\n result = `${eagerImports.join('\\n')}\\n${result}`;\n }\n\n return {\n code: result,\n map: { mappings: '' },\n };\n }\n\n return;\n },\n },\n },\n {\n name: 'analogjs-invalidate-content-dirs',\n configureServer(server) {\n function invalidateContent(path: string) {\n const normalizedPath = vite.normalizePath(path);\n const isContentPath = contentRootDirs.some(\n (dir) =>\n normalizedPath === dir || normalizedPath.startsWith(`${dir}/`),\n );\n\n if (isContentPath) {\n // The file set only changes on add/remove because this watcher is\n // intentionally scoped to those events. Clear the list cache so the\n // next transform sees the updated directory contents.\n contentFilesListCache = undefined;\n server.moduleGraph.fileToModulesMap.forEach((mods) => {\n mods.forEach((mod) => {\n if (\n mod.id?.includes('analogjs') &&\n mod.id?.includes('content')\n ) {\n server.moduleGraph.invalidateModule(mod);\n\n mod.importers.forEach((imp) => {\n server.moduleGraph.invalidateModule(imp);\n });\n }\n });\n });\n\n server.ws.send('analog:debug-full-reload', {\n plugin: 'platform:content-plugin',\n reason: 'content-file-set-changed',\n path: normalizedPath,\n });\n server.ws.send({\n type: 'full-reload',\n });\n }\n }\n\n server.watcher.on('add', invalidateContent);\n server.watcher.on('unlink', invalidateContent);\n },\n },\n ];\n\n if (!highlighter) {\n return [\n {\n name: 'analogjs-external-content',\n config() {\n const bundleOptionsKey = getBundleOptionsKey();\n return {\n build: {\n [bundleOptionsKey]: {\n external: ['@analogjs/content'],\n },\n },\n };\n },\n },\n {\n name: 'analogjs-exclude-content-import',\n transform: {\n filter: {\n code: '@analogjs/content',\n },\n handler(code) {\n /**\n * Remove the package so it doesn't get\n * referenced when building for serverless\n * functions.\n */\n if (code.includes(`import('@analogjs/content')`)) {\n return {\n code: code.replace(\n `import('@analogjs/content')`,\n 'Promise.resolve({})',\n ),\n };\n }\n\n return;\n },\n },\n },\n ...contentDiscoveryPlugins,\n ];\n }\n\n return [\n {\n name: 'analogjs-content-frontmatter',\n // Filter by module ID so only `?analog-content-list=true` virtual\n // imports enter the handler. Returns `moduleSideEffects: false` so\n // Rolldown can tree-shake unused content list entries.\n transform: {\n filter: {\n id: /analog-content-list=true/,\n },\n async handler(code, id) {\n const cachedContent = cache.get(id);\n // There's no reason to run `readFileSync` and frontmatter parsing if the\n // `transform` hook is called with the same code. In such cases, we can simply\n // return the cached attributes, which is faster than repeatedly reading files\n // synchronously during the build process.\n if (cachedContent?.code === code) {\n return {\n code: `export default ${cachedContent.attributes}`,\n moduleSideEffects: false,\n };\n }\n\n const fm: any = await import('front-matter');\n // The `default` property will be available in CommonJS environment, for instance,\n // when running unit tests. It's safe to retrieve `default` first, since we still\n // fallback to the original implementation.\n const frontmatter = fm.default || fm;\n const fileContents = readFileSync(id.split('?')[0], 'utf8');\n const { attributes } = frontmatter(fileContents);\n const content = {\n code,\n attributes: JSON.stringify(attributes),\n };\n cache.set(id, content);\n\n return {\n code: `export default ${content.attributes}`,\n moduleSideEffects: false,\n };\n },\n },\n },\n {\n name: 'analogjs-content-file',\n enforce: 'post',\n async load(id) {\n if (!id.includes('analog-content-file=true')) {\n return;\n }\n\n if (!markedHighlighter) {\n if (highlighter === 'shiki') {\n const { getShikiHighlighter } =\n await import('./content/shiki/index.js');\n markedHighlighter = getShikiHighlighter(shikiOptions);\n } else {\n const { getPrismHighlighter } =\n await import('./content/prism/index.js');\n markedHighlighter = getPrismHighlighter();\n\n const langs = [\n 'bash',\n 'css',\n 'javascript',\n 'json',\n 'markup',\n 'typescript',\n ];\n\n if (\n Array.isArray(prismOptions?.additionalLangs) &&\n prismOptions?.additionalLangs?.length > 0\n ) {\n langs.push(...prismOptions.additionalLangs);\n }\n\n const loadLanguages = await import('prismjs/components/index.js');\n\n (\n loadLanguages as unknown as { default: (...args: any[]) => any }\n ).default(langs);\n }\n }\n\n const fm: any = await import('front-matter');\n // The `default` property will be available in CommonJS environment, for instance,\n // when running unit tests. It's safe to retrieve `default` first, since we still\n // fallback to the original implementation.\n const frontmatterFn = fm.default || fm;\n const fileContents = readFileSync(id.split('?')[0], 'utf8');\n const { body, frontmatter } = frontmatterFn(fileContents);\n\n // parse markdown and highlight\n const { getMarkedSetup } = await import('./content/marked/index.js');\n const markedSetupService = getMarkedSetup(\n { mangle: true, ...(markedOptions || {}) },\n markedHighlighter,\n );\n const mdContent = (await markedSetupService\n .getMarkedInstance()\n .parse(body)) as unknown as string;\n\n return `export default ${JSON.stringify(\n `---\\n${frontmatter}\\n---\\n\\n${mdContent}`,\n )}`;\n },\n },\n ...contentDiscoveryPlugins,\n ];\n}\n"],"mappings":"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"}
@@ -20,6 +20,7 @@ function depsPlugin(options) {
20
20
  [getJsTransformConfigKey()]: transformConfig,
21
21
  ssr: { noExternal: [
22
22
  "@analogjs/**",
23
+ "es-toolkit",
23
24
  "firebase/**",
24
25
  "firebase-admin/**",
25
26
  "rxfire",
@@ -1 +1 @@
1
- {"version":3,"file":"deps-plugin.js","names":[],"sources":["../../../src/lib/deps-plugin.ts"],"sourcesContent":["import { VERSION } from '@angular/compiler-cli';\nimport type { Plugin } from 'vite';\nimport { crawlFrameworkPkgs } from 'vitefu';\n\nimport { Options } from './options.js';\nimport { debugPlatform } from './utils/debug.js';\nimport { getJsTransformConfigKey } from './utils/rolldown.js';\n\nexport function depsPlugin(options?: Options): Plugin[] {\n const workspaceRoot =\n options?.workspaceRoot ?? process.env['NX_WORKSPACE_ROOT'] ?? process.cwd();\n const viteOptions = options?.vite === false ? undefined : options?.vite;\n\n return [\n {\n name: 'analogjs-deps-plugin',\n config() {\n const useAngularCompilationAPI =\n options?.experimental?.useAngularCompilationAPI ??\n viteOptions?.experimental?.useAngularCompilationAPI;\n\n const transformConfig =\n options?.vite === false || useAngularCompilationAPI\n ? {}\n : { exclude: ['**/*.ts', '**/*.js'] };\n debugPlatform('deps transform config', {\n useAngularCompilationAPI: !!useAngularCompilationAPI,\n jsTransformKey: getJsTransformConfigKey(),\n transformExcluded: 'exclude' in transformConfig,\n });\n\n return {\n [getJsTransformConfigKey()]: transformConfig,\n ssr: {\n noExternal: [\n '@analogjs/**',\n 'firebase/**',\n 'firebase-admin/**',\n 'rxfire',\n '@ng-web-apis/**',\n '@taiga-ui/**',\n '@tanstack/angular-query-experimental',\n ],\n },\n optimizeDeps: {\n include: [\n '@angular/common',\n '@angular/common/http',\n ...(Number(VERSION.major) > 15\n ? ['@angular/core/rxjs-interop']\n : []),\n 'front-matter',\n ],\n exclude: [\n '@angular/platform-server',\n '@analogjs/content',\n '@analogjs/router',\n '@nx/angular',\n '@nx/vite',\n '@nx/devkit',\n '@nx/js',\n '@nx/devkit',\n '@nx/cypress',\n '@nx/jest',\n '@nx/js',\n '@nx/eslint',\n '@nx/webpack',\n '@nx/web',\n '@nx/workspace',\n '@nx/eslint',\n '@nx/module-federation',\n '@nx/rspack',\n 'webpack',\n 'fsevents',\n 'nx',\n ],\n },\n };\n },\n },\n {\n name: 'analogjs-auto-discover-deps',\n async config(config, { command }) {\n const pkgConfig = await crawlFrameworkPkgs({\n root: workspaceRoot,\n isBuild: command === 'build',\n viteUserConfig: config,\n isSemiFrameworkPkgByJson(pkgJson) {\n return pkgJson['module'] && pkgJson['module'].includes('fesm');\n },\n });\n return pkgConfig;\n },\n },\n ];\n}\n"],"mappings":";;;;;AAQA,SAAgB,WAAW,SAA6B;CACtD,MAAM,gBACJ,SAAS,iBAAiB,QAAQ,IAAI,wBAAwB,QAAQ,KAAK;CAC7E,MAAM,cAAc,SAAS,SAAS,QAAQ,KAAA,IAAY,SAAS;AAEnE,QAAO,CACL;EACE,MAAM;EACN,SAAS;GACP,MAAM,2BACJ,SAAS,cAAc,4BACvB,aAAa,cAAc;GAE7B,MAAM,kBACJ,SAAS,SAAS,SAAS,2BACvB,EAAE,GACF,EAAE,SAAS,CAAC,WAAW,UAAU,EAAE;AACzC,iBAAc,yBAAyB;IACrC,0BAA0B,CAAC,CAAC;IAC5B,gBAAgB,yBAAyB;IACzC,mBAAmB,aAAa;IACjC,CAAC;AAEF,UAAO;KACJ,yBAAyB,GAAG;IAC7B,KAAK,EACH,YAAY;KACV;KACA;KACA;KACA;KACA;KACA;KACA;KACD,EACF;IACD,cAAc;KACZ,SAAS;MACP;MACA;MACA,GAAI,OAAO,QAAQ,MAAM,GAAG,KACxB,CAAC,6BAA6B,GAC9B,EAAE;MACN;MACD;KACD,SAAS;MACP;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACD;KACF;IACF;;EAEJ,EACD;EACE,MAAM;EACN,MAAM,OAAO,QAAQ,EAAE,WAAW;AAShC,UARkB,MAAM,mBAAmB;IACzC,MAAM;IACN,SAAS,YAAY;IACrB,gBAAgB;IAChB,yBAAyB,SAAS;AAChC,YAAO,QAAQ,aAAa,QAAQ,UAAU,SAAS,OAAO;;IAEjE,CAAC;;EAGL,CACF"}
1
+ {"version":3,"file":"deps-plugin.js","names":[],"sources":["../../../src/lib/deps-plugin.ts"],"sourcesContent":["import { VERSION } from '@angular/compiler-cli';\nimport type { Plugin } from 'vite';\nimport { crawlFrameworkPkgs } from 'vitefu';\n\nimport { Options } from './options.js';\nimport { debugPlatform } from './utils/debug.js';\nimport { getJsTransformConfigKey } from './utils/rolldown.js';\n\nexport function depsPlugin(options?: Options): Plugin[] {\n const workspaceRoot =\n options?.workspaceRoot ?? process.env['NX_WORKSPACE_ROOT'] ?? process.cwd();\n const viteOptions = options?.vite === false ? undefined : options?.vite;\n\n return [\n {\n name: 'analogjs-deps-plugin',\n config() {\n const useAngularCompilationAPI =\n options?.experimental?.useAngularCompilationAPI ??\n viteOptions?.experimental?.useAngularCompilationAPI;\n\n const transformConfig =\n options?.vite === false || useAngularCompilationAPI\n ? {}\n : { exclude: ['**/*.ts', '**/*.js'] };\n debugPlatform('deps transform config', {\n useAngularCompilationAPI: !!useAngularCompilationAPI,\n jsTransformKey: getJsTransformConfigKey(),\n transformExcluded: 'exclude' in transformConfig,\n });\n\n return {\n [getJsTransformConfigKey()]: transformConfig,\n ssr: {\n noExternal: [\n '@analogjs/**',\n 'es-toolkit',\n 'firebase/**',\n 'firebase-admin/**',\n 'rxfire',\n '@ng-web-apis/**',\n '@taiga-ui/**',\n '@tanstack/angular-query-experimental',\n ],\n },\n optimizeDeps: {\n include: [\n '@angular/common',\n '@angular/common/http',\n ...(Number(VERSION.major) > 15\n ? ['@angular/core/rxjs-interop']\n : []),\n 'front-matter',\n ],\n exclude: [\n '@angular/platform-server',\n '@analogjs/content',\n '@analogjs/router',\n '@nx/angular',\n '@nx/vite',\n '@nx/devkit',\n '@nx/js',\n '@nx/devkit',\n '@nx/cypress',\n '@nx/jest',\n '@nx/js',\n '@nx/eslint',\n '@nx/webpack',\n '@nx/web',\n '@nx/workspace',\n '@nx/eslint',\n '@nx/module-federation',\n '@nx/rspack',\n 'webpack',\n 'fsevents',\n 'nx',\n ],\n },\n };\n },\n },\n {\n name: 'analogjs-auto-discover-deps',\n async config(config, { command }) {\n const pkgConfig = await crawlFrameworkPkgs({\n root: workspaceRoot,\n isBuild: command === 'build',\n viteUserConfig: config,\n isSemiFrameworkPkgByJson(pkgJson) {\n return pkgJson['module'] && pkgJson['module'].includes('fesm');\n },\n });\n return pkgConfig;\n },\n },\n ];\n}\n"],"mappings":";;;;;AAQA,SAAgB,WAAW,SAA6B;CACtD,MAAM,gBACJ,SAAS,iBAAiB,QAAQ,IAAI,wBAAwB,QAAQ,KAAK;CAC7E,MAAM,cAAc,SAAS,SAAS,QAAQ,KAAA,IAAY,SAAS;AAEnE,QAAO,CACL;EACE,MAAM;EACN,SAAS;GACP,MAAM,2BACJ,SAAS,cAAc,4BACvB,aAAa,cAAc;GAE7B,MAAM,kBACJ,SAAS,SAAS,SAAS,2BACvB,EAAE,GACF,EAAE,SAAS,CAAC,WAAW,UAAU,EAAE;AACzC,iBAAc,yBAAyB;IACrC,0BAA0B,CAAC,CAAC;IAC5B,gBAAgB,yBAAyB;IACzC,mBAAmB,aAAa;IACjC,CAAC;AAEF,UAAO;KACJ,yBAAyB,GAAG;IAC7B,KAAK,EACH,YAAY;KACV;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACD,EACF;IACD,cAAc;KACZ,SAAS;MACP;MACA;MACA,GAAI,OAAO,QAAQ,MAAM,GAAG,KACxB,CAAC,6BAA6B,GAC9B,EAAE;MACN;MACD;KACD,SAAS;MACP;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACD;KACF;IACF;;EAEJ,EACD;EACE,MAAM;EACN,MAAM,OAAO,QAAQ,EAAE,WAAW;AAShC,UARkB,MAAM,mBAAmB;IACzC,MAAM;IACN,SAAS,YAAY;IACrB,gBAAgB;IAChB,yBAAyB,SAAS;AAChC,YAAO,QAAQ,aAAa,QAAQ,UAAU,SAAS,OAAO;;IAEjE,CAAC;;EAGL,CACF"}
@@ -1,5 +1,5 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
1
  import { join } from "node:path";
2
+ import { existsSync, readFileSync } from "node:fs";
3
3
  //#region packages/platform/src/lib/discover-library-routes.ts
4
4
  var empty = Object.freeze({
5
5
  additionalPagesDirs: Object.freeze([]),
@@ -0,0 +1,13 @@
1
+ const require_capitalize = require("./capitalize.js");
2
+ const require_words = require("./words.js");
3
+ //#region node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.mjs
4
+ function camelCase(str) {
5
+ const words$1 = require_words.words(str);
6
+ if (words$1.length === 0) return "";
7
+ const [first, ...rest] = words$1;
8
+ return `${first.toLowerCase()}${rest.map((word) => require_capitalize.capitalize(word)).join("")}`;
9
+ }
10
+ //#endregion
11
+ exports.camelCase = camelCase;
12
+
13
+ //# sourceMappingURL=camelCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camelCase.js","names":["words","capitalize"],"sources":["../../../../../../../../../../../../../node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.mjs"],"sourcesContent":["import { capitalize } from './capitalize.mjs';\nimport { words } from './words.mjs';\n\nfunction camelCase(str) {\n const words$1 = words(str);\n if (words$1.length === 0) {\n return '';\n }\n const [first, ...rest] = words$1;\n return `${first.toLowerCase()}${rest.map(word => capitalize(word)).join('')}`;\n}\n\nexport { camelCase };\n"],"x_google_ignoreList":[0],"mappings":";;;AAGA,SAAS,UAAU,KAAK;CACpB,MAAM,UAAUA,cAAAA,MAAM,IAAI;AAC1B,KAAI,QAAQ,WAAW,EACnB,QAAO;CAEX,MAAM,CAAC,OAAO,GAAG,QAAQ;AACzB,QAAO,GAAG,MAAM,aAAa,GAAG,KAAK,KAAI,SAAQC,mBAAAA,WAAW,KAAK,CAAC,CAAC,KAAK,GAAG"}
@@ -0,0 +1,8 @@
1
+ //#region node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.mjs
2
+ function capitalize(str) {
3
+ return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
4
+ }
5
+ //#endregion
6
+ exports.capitalize = capitalize;
7
+
8
+ //# sourceMappingURL=capitalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capitalize.js","names":[],"sources":["../../../../../../../../../../../../../node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.mjs"],"sourcesContent":["function capitalize(str) {\n return (str.charAt(0).toUpperCase() + str.slice(1).toLowerCase());\n}\n\nexport { capitalize };\n"],"x_google_ignoreList":[0],"mappings":";AAAA,SAAS,WAAW,KAAK;AACrB,QAAQ,IAAI,OAAO,EAAE,CAAC,aAAa,GAAG,IAAI,MAAM,EAAE,CAAC,aAAa"}
@@ -0,0 +1,9 @@
1
+ //#region node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.mjs
2
+ var CASE_SPLIT_PATTERN = /\p{Lu}?\p{Ll}+|[0-9]+|\p{Lu}+(?!\p{Ll})|\p{Emoji_Presentation}|\p{Extended_Pictographic}|\p{L}+/gu;
3
+ function words(str) {
4
+ return Array.from(str.match(CASE_SPLIT_PATTERN) ?? []);
5
+ }
6
+ //#endregion
7
+ exports.words = words;
8
+
9
+ //# sourceMappingURL=words.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"words.js","names":[],"sources":["../../../../../../../../../../../../../node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.mjs"],"sourcesContent":["const CASE_SPLIT_PATTERN = /\\p{Lu}?\\p{Ll}+|[0-9]+|\\p{Lu}+(?!\\p{Ll})|\\p{Emoji_Presentation}|\\p{Extended_Pictographic}|\\p{L}+/gu;\nfunction words(str) {\n return Array.from(str.match(CASE_SPLIT_PATTERN) ?? []);\n}\n\nexport { CASE_SPLIT_PATTERN, words };\n"],"x_google_ignoreList":[0],"mappings":";AAAA,IAAM,qBAAqB;AAC3B,SAAS,MAAM,KAAK;AAChB,QAAO,MAAM,KAAK,IAAI,MAAM,mBAAmB,IAAI,EAAE,CAAC"}
@@ -10,7 +10,10 @@ async function setupTailwindGenerator(tree, rawOptions) {
10
10
  require_add_tailwind_helpers.detectTailwindInstalledVersion(tree);
11
11
  let installTask = () => {};
12
12
  if (!options.skipPackageJson) installTask = require_add_tailwind_helpers.addTailwindRequiredPackages(tree);
13
- if (project.projectType === "application") require_add_tailwind_helpers.updateApplicationStyles(tree, options, project);
13
+ if (project.projectType === "application") {
14
+ require_add_tailwind_helpers.updateApplicationStyles(tree, options, project);
15
+ require_add_tailwind_helpers.writeTailwindPostcssConfig(tree, project);
16
+ }
14
17
  if (!options.skipFormat) await (0, _nx_devkit.formatFiles)(tree);
15
18
  return installTask;
16
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"add-tailwind-config.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/generators/app/lib/add-tailwind-config.ts"],"sourcesContent":["import {\n formatFiles,\n GeneratorCallback,\n readProjectConfiguration,\n Tree,\n} from '@nx/devkit';\nimport {\n addTailwindRequiredPackages,\n detectTailwindInstalledVersion,\n normalizeOptions,\n updateApplicationStyles,\n} from './add-tailwind-helpers';\n\nexport async function addTailwindConfig(\n tree: Tree,\n projectName: string,\n): Promise<void> {\n await setupTailwindGenerator(tree, {\n project: projectName,\n });\n}\n\nexport interface GeneratorOptions {\n project: string;\n buildTarget?: string;\n skipFormat?: boolean;\n stylesEntryPoint?: string;\n skipPackageJson?: boolean;\n}\n\nexport interface NormalizedGeneratorOptions extends GeneratorOptions {\n buildTarget: string;\n}\n\nexport async function setupTailwindGenerator(\n tree: Tree,\n rawOptions: GeneratorOptions,\n): Promise<GeneratorCallback> {\n const options = normalizeOptions(rawOptions);\n const project = readProjectConfiguration(tree, options.project);\n\n // TODO: use return value for v5+ branching when needed\n detectTailwindInstalledVersion(tree);\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let installTask: GeneratorCallback = () => {};\n if (!options.skipPackageJson) {\n installTask = addTailwindRequiredPackages(tree);\n }\n\n if (project.projectType === 'application') {\n updateApplicationStyles(tree, options, project);\n }\n\n if (!options.skipFormat) {\n await formatFiles(tree);\n }\n\n return installTask;\n}\n"],"mappings":";;;AAaA,eAAsB,kBACpB,MACA,aACe;AACf,OAAM,uBAAuB,MAAM,EACjC,SAAS,aACV,CAAC;;AAeJ,eAAsB,uBACpB,MACA,YAC4B;CAC5B,MAAM,UAAU,6BAAA,iBAAiB,WAAW;CAC5C,MAAM,WAAA,GAAA,WAAA,0BAAmC,MAAM,QAAQ,QAAQ;AAG/D,8BAAA,+BAA+B,KAAK;CAGpC,IAAI,oBAAuC;AAC3C,KAAI,CAAC,QAAQ,gBACX,eAAc,6BAAA,4BAA4B,KAAK;AAGjD,KAAI,QAAQ,gBAAgB,cAC1B,8BAAA,wBAAwB,MAAM,SAAS,QAAQ;AAGjD,KAAI,CAAC,QAAQ,WACX,QAAA,GAAA,WAAA,aAAkB,KAAK;AAGzB,QAAO"}
1
+ {"version":3,"file":"add-tailwind-config.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/generators/app/lib/add-tailwind-config.ts"],"sourcesContent":["import {\n formatFiles,\n GeneratorCallback,\n readProjectConfiguration,\n Tree,\n} from '@nx/devkit';\nimport {\n addTailwindRequiredPackages,\n detectTailwindInstalledVersion,\n normalizeOptions,\n updateApplicationStyles,\n writeTailwindPostcssConfig,\n} from './add-tailwind-helpers';\n\nexport async function addTailwindConfig(\n tree: Tree,\n projectName: string,\n): Promise<void> {\n await setupTailwindGenerator(tree, {\n project: projectName,\n });\n}\n\nexport interface GeneratorOptions {\n project: string;\n buildTarget?: string;\n skipFormat?: boolean;\n stylesEntryPoint?: string;\n skipPackageJson?: boolean;\n}\n\nexport interface NormalizedGeneratorOptions extends GeneratorOptions {\n buildTarget: string;\n}\n\nexport async function setupTailwindGenerator(\n tree: Tree,\n rawOptions: GeneratorOptions,\n): Promise<GeneratorCallback> {\n const options = normalizeOptions(rawOptions);\n const project = readProjectConfiguration(tree, options.project);\n\n // TODO: use return value for v5+ branching when needed\n detectTailwindInstalledVersion(tree);\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let installTask: GeneratorCallback = () => {};\n if (!options.skipPackageJson) {\n installTask = addTailwindRequiredPackages(tree);\n }\n\n if (project.projectType === 'application') {\n updateApplicationStyles(tree, options, project);\n writeTailwindPostcssConfig(tree, project);\n }\n\n if (!options.skipFormat) {\n await formatFiles(tree);\n }\n\n return installTask;\n}\n"],"mappings":";;;AAcA,eAAsB,kBACpB,MACA,aACe;AACf,OAAM,uBAAuB,MAAM,EACjC,SAAS,aACV,CAAC;;AAeJ,eAAsB,uBACpB,MACA,YAC4B;CAC5B,MAAM,UAAU,6BAAA,iBAAiB,WAAW;CAC5C,MAAM,WAAA,GAAA,WAAA,0BAAmC,MAAM,QAAQ,QAAQ;AAG/D,8BAAA,+BAA+B,KAAK;CAGpC,IAAI,oBAAuC;AAC3C,KAAI,CAAC,QAAQ,gBACX,eAAc,6BAAA,4BAA4B,KAAK;AAGjD,KAAI,QAAQ,gBAAgB,eAAe;AACzC,+BAAA,wBAAwB,MAAM,SAAS,QAAQ;AAC/C,+BAAA,2BAA2B,MAAM,QAAQ;;AAG3C,KAAI,CAAC,QAAQ,WACX,QAAA,GAAA,WAAA,aAAkB,KAAK;AAGzB,QAAO"}
@@ -3,4 +3,5 @@ import { GeneratorOptions, NormalizedGeneratorOptions } from "./add-tailwind-con
3
3
  export declare function normalizeOptions(options: GeneratorOptions): NormalizedGeneratorOptions;
4
4
  export declare function detectTailwindInstalledVersion(tree: Tree): "4" | "5" | undefined;
5
5
  export declare function addTailwindRequiredPackages(tree: Tree): GeneratorCallback;
6
+ export declare function writeTailwindPostcssConfig(tree: Tree, project: ProjectConfiguration): void;
6
7
  export declare function updateApplicationStyles(tree: Tree, options: NormalizedGeneratorOptions, project: ProjectConfiguration): void;
@@ -20,10 +20,22 @@ function detectTailwindInstalledVersion(tree) {
20
20
  function addTailwindRequiredPackages(tree) {
21
21
  const pkgVersions = require_tailwind_dependencies.getTailwindDependencies();
22
22
  return (0, _nx_devkit.addDependenciesToPackageJson)(tree, {
23
+ postcss: pkgVersions.postcss,
23
24
  tailwindcss: pkgVersions.tailwindcss,
25
+ "@tailwindcss/postcss": pkgVersions["@tailwindcss/postcss"],
24
26
  "@tailwindcss/vite": pkgVersions["@tailwindcss/vite"]
25
27
  }, {});
26
28
  }
29
+ function writeTailwindPostcssConfig(tree, project) {
30
+ const postcssConfigPath = (0, _nx_devkit.joinPathFragments)(project.root, "postcss.config.mjs");
31
+ if (tree.exists(postcssConfigPath)) return;
32
+ tree.write(postcssConfigPath, `export default {
33
+ plugins: {
34
+ '@tailwindcss/postcss': {},
35
+ },
36
+ };
37
+ `);
38
+ }
27
39
  function updateApplicationStyles(tree, options, project) {
28
40
  let stylesEntryPoint = options.stylesEntryPoint;
29
41
  if (stylesEntryPoint && !tree.exists(stylesEntryPoint)) throw new Error(`The provided styles entry point "${stylesEntryPoint}" could not be found.`);
@@ -58,5 +70,6 @@ exports.addTailwindRequiredPackages = addTailwindRequiredPackages;
58
70
  exports.detectTailwindInstalledVersion = detectTailwindInstalledVersion;
59
71
  exports.normalizeOptions = normalizeOptions;
60
72
  exports.updateApplicationStyles = updateApplicationStyles;
73
+ exports.writeTailwindPostcssConfig = writeTailwindPostcssConfig;
61
74
 
62
75
  //# sourceMappingURL=add-tailwind-helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-tailwind-helpers.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/generators/app/lib/add-tailwind-helpers.ts"],"sourcesContent":["import { checkAndCleanWithSemver } from '@nx/devkit/src/utils/semver';\nimport { getTailwindDependencies } from '../versions/tailwind-dependencies';\nimport { lt } from 'semver';\nimport {\n Tree,\n readJson,\n addDependenciesToPackageJson,\n GeneratorCallback,\n ProjectConfiguration,\n joinPathFragments,\n stripIndents,\n} from '@nx/devkit';\nimport {\n GeneratorOptions,\n NormalizedGeneratorOptions,\n} from './add-tailwind-config';\n\nexport function normalizeOptions(\n options: GeneratorOptions,\n): NormalizedGeneratorOptions {\n return {\n ...options,\n buildTarget: options.buildTarget || 'build',\n };\n}\n\nexport function detectTailwindInstalledVersion(\n tree: Tree,\n): '4' | '5' | undefined {\n const { dependencies, devDependencies } = readJson(tree, 'package.json');\n const tailwindVersion =\n dependencies?.tailwindcss ?? devDependencies?.tailwindcss;\n\n if (!tailwindVersion) {\n return undefined;\n }\n\n const version = checkAndCleanWithSemver('tailwindcss', tailwindVersion);\n if (lt(version, '4.0.0')) {\n throw new Error(\n `The Tailwind CSS version \"${tailwindVersion}\" is not supported. Please upgrade to v4.0.0 or higher.`,\n );\n }\n return lt(version, '5.0.0') ? '4' : '5';\n}\n\nexport function addTailwindRequiredPackages(tree: Tree): GeneratorCallback {\n const pkgVersions = getTailwindDependencies();\n return addDependenciesToPackageJson(\n tree,\n {\n tailwindcss: pkgVersions.tailwindcss,\n '@tailwindcss/vite': pkgVersions['@tailwindcss/vite'],\n },\n {},\n );\n}\n\nexport function updateApplicationStyles(\n tree: Tree,\n options: NormalizedGeneratorOptions,\n project: ProjectConfiguration,\n): void {\n let stylesEntryPoint = options.stylesEntryPoint;\n\n if (stylesEntryPoint && !tree.exists(stylesEntryPoint)) {\n throw new Error(\n `The provided styles entry point \"${stylesEntryPoint}\" could not be found.`,\n );\n }\n\n if (!stylesEntryPoint) {\n stylesEntryPoint = findStylesEntryPoint(tree, options, project);\n\n if (!stylesEntryPoint) {\n throw new Error(\n stripIndents`Could not find a styles entry point for project \"${options.project}\".\n Please specify a styles entry point using the \"--stylesEntryPoint\" option.`,\n );\n }\n }\n\n if (!stylesEntryPoint.endsWith('.css')) {\n throw new Error(\n `Tailwind CSS v4 is not compatible with any css preprocessors like sass or less. Please use a css file as the styles entry point.`,\n );\n }\n\n const stylesEntryPointContent = tree.read(stylesEntryPoint, 'utf-8');\n\n tree.write(\n stylesEntryPoint,\n stripIndents`@import \"tailwindcss\";\n\n\n ${stylesEntryPointContent}`,\n );\n}\n\nfunction findStylesEntryPoint(\n tree: Tree,\n options: NormalizedGeneratorOptions,\n project: ProjectConfiguration,\n): string | undefined {\n // first check for common names\n const possibleStylesEntryPoints = [\n joinPathFragments(project.sourceRoot ?? project.root, 'styles.css'),\n joinPathFragments(project.sourceRoot ?? project.root, 'styles.scss'),\n joinPathFragments(project.sourceRoot ?? project.root, 'styles.sass'),\n joinPathFragments(project.sourceRoot ?? project.root, 'styles.less'),\n ];\n\n const stylesEntryPoint = possibleStylesEntryPoints.find((s) =>\n tree.exists(s),\n );\n if (stylesEntryPoint) {\n return stylesEntryPoint;\n }\n\n // then check for the specified styles in the build configuration if it exists\n const styles: Array<string | { input: string; inject: boolean }> =\n project.targets?.[options.buildTarget].options?.styles;\n\n if (!styles) {\n return undefined;\n }\n\n // find the first style that belongs to the project source\n const style = styles.find((s) =>\n typeof s === 'string'\n ? s.startsWith(project.root) && tree.exists(s)\n : s.input.startsWith(project.root) &&\n s.inject !== false &&\n tree.exists(s.input),\n );\n\n if (!style) {\n return undefined;\n }\n\n return typeof style === 'string' ? style : style.input;\n}\n"],"mappings":";;;;;AAiBA,SAAgB,iBACd,SAC4B;AAC5B,QAAO;EACL,GAAG;EACH,aAAa,QAAQ,eAAe;EACrC;;AAGH,SAAgB,+BACd,MACuB;CACvB,MAAM,EAAE,cAAc,qBAAA,GAAA,WAAA,UAA6B,MAAM,eAAe;CACxE,MAAM,kBACJ,cAAc,eAAe,iBAAiB;AAEhD,KAAI,CAAC,gBACH;CAGF,MAAM,WAAA,GAAA,4BAAA,yBAAkC,eAAe,gBAAgB;AACvE,MAAA,GAAA,OAAA,IAAO,SAAS,QAAQ,CACtB,OAAM,IAAI,MACR,6BAA6B,gBAAgB,yDAC9C;AAEH,SAAA,GAAA,OAAA,IAAU,SAAS,QAAQ,GAAG,MAAM;;AAGtC,SAAgB,4BAA4B,MAA+B;CACzE,MAAM,cAAc,8BAAA,yBAAyB;AAC7C,SAAA,GAAA,WAAA,8BACE,MACA;EACE,aAAa,YAAY;EACzB,qBAAqB,YAAY;EAClC,EACD,EAAE,CACH;;AAGH,SAAgB,wBACd,MACA,SACA,SACM;CACN,IAAI,mBAAmB,QAAQ;AAE/B,KAAI,oBAAoB,CAAC,KAAK,OAAO,iBAAiB,CACpD,OAAM,IAAI,MACR,oCAAoC,iBAAiB,uBACtD;AAGH,KAAI,CAAC,kBAAkB;AACrB,qBAAmB,qBAAqB,MAAM,SAAS,QAAQ;AAE/D,MAAI,CAAC,iBACH,OAAM,IAAI,MACR,WAAA,YAAY,oDAAoD,QAAQ,QAAQ;oFAEjF;;AAIL,KAAI,CAAC,iBAAiB,SAAS,OAAO,CACpC,OAAM,IAAI,MACR,mIACD;CAGH,MAAM,0BAA0B,KAAK,KAAK,kBAAkB,QAAQ;AAEpE,MAAK,MACH,kBACA,WAAA,YAAY;;;MAGV,0BACH;;AAGH,SAAS,qBACP,MACA,SACA,SACoB;CASpB,MAAM,mBAP4B;oCACd,QAAQ,cAAc,QAAQ,MAAM,aAAa;oCACjD,QAAQ,cAAc,QAAQ,MAAM,cAAc;oCAClD,QAAQ,cAAc,QAAQ,MAAM,cAAc;oCAClD,QAAQ,cAAc,QAAQ,MAAM,cAAc;EACrE,CAEkD,MAAM,MACvD,KAAK,OAAO,EAAE,CACf;AACD,KAAI,iBACF,QAAO;CAIT,MAAM,SACJ,QAAQ,UAAU,QAAQ,aAAa,SAAS;AAElD,KAAI,CAAC,OACH;CAIF,MAAM,QAAQ,OAAO,MAAM,MACzB,OAAO,MAAM,WACT,EAAE,WAAW,QAAQ,KAAK,IAAI,KAAK,OAAO,EAAE,GAC5C,EAAE,MAAM,WAAW,QAAQ,KAAK,IAChC,EAAE,WAAW,SACb,KAAK,OAAO,EAAE,MAAM,CACzB;AAED,KAAI,CAAC,MACH;AAGF,QAAO,OAAO,UAAU,WAAW,QAAQ,MAAM"}
1
+ {"version":3,"file":"add-tailwind-helpers.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/generators/app/lib/add-tailwind-helpers.ts"],"sourcesContent":["import { checkAndCleanWithSemver } from '@nx/devkit/src/utils/semver';\nimport { getTailwindDependencies } from '../versions/tailwind-dependencies';\nimport { lt } from 'semver';\nimport {\n Tree,\n readJson,\n addDependenciesToPackageJson,\n GeneratorCallback,\n ProjectConfiguration,\n joinPathFragments,\n stripIndents,\n} from '@nx/devkit';\nimport {\n GeneratorOptions,\n NormalizedGeneratorOptions,\n} from './add-tailwind-config';\n\nexport function normalizeOptions(\n options: GeneratorOptions,\n): NormalizedGeneratorOptions {\n return {\n ...options,\n buildTarget: options.buildTarget || 'build',\n };\n}\n\nexport function detectTailwindInstalledVersion(\n tree: Tree,\n): '4' | '5' | undefined {\n const { dependencies, devDependencies } = readJson(tree, 'package.json');\n const tailwindVersion =\n dependencies?.tailwindcss ?? devDependencies?.tailwindcss;\n\n if (!tailwindVersion) {\n return undefined;\n }\n\n const version = checkAndCleanWithSemver('tailwindcss', tailwindVersion);\n if (lt(version, '4.0.0')) {\n throw new Error(\n `The Tailwind CSS version \"${tailwindVersion}\" is not supported. Please upgrade to v4.0.0 or higher.`,\n );\n }\n return lt(version, '5.0.0') ? '4' : '5';\n}\n\nexport function addTailwindRequiredPackages(tree: Tree): GeneratorCallback {\n const pkgVersions = getTailwindDependencies();\n return addDependenciesToPackageJson(\n tree,\n {\n postcss: pkgVersions.postcss,\n tailwindcss: pkgVersions.tailwindcss,\n '@tailwindcss/postcss': pkgVersions['@tailwindcss/postcss'],\n '@tailwindcss/vite': pkgVersions['@tailwindcss/vite'],\n },\n {},\n );\n}\n\nexport function writeTailwindPostcssConfig(\n tree: Tree,\n project: ProjectConfiguration,\n): void {\n const postcssConfigPath = joinPathFragments(\n project.root,\n 'postcss.config.mjs',\n );\n\n if (tree.exists(postcssConfigPath)) {\n return;\n }\n\n tree.write(\n postcssConfigPath,\n `export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n};\n`,\n );\n}\n\nexport function updateApplicationStyles(\n tree: Tree,\n options: NormalizedGeneratorOptions,\n project: ProjectConfiguration,\n): void {\n let stylesEntryPoint = options.stylesEntryPoint;\n\n if (stylesEntryPoint && !tree.exists(stylesEntryPoint)) {\n throw new Error(\n `The provided styles entry point \"${stylesEntryPoint}\" could not be found.`,\n );\n }\n\n if (!stylesEntryPoint) {\n stylesEntryPoint = findStylesEntryPoint(tree, options, project);\n\n if (!stylesEntryPoint) {\n throw new Error(\n stripIndents`Could not find a styles entry point for project \"${options.project}\".\n Please specify a styles entry point using the \"--stylesEntryPoint\" option.`,\n );\n }\n }\n\n if (!stylesEntryPoint.endsWith('.css')) {\n throw new Error(\n `Tailwind CSS v4 is not compatible with any css preprocessors like sass or less. Please use a css file as the styles entry point.`,\n );\n }\n\n const stylesEntryPointContent = tree.read(stylesEntryPoint, 'utf-8');\n\n tree.write(\n stylesEntryPoint,\n stripIndents`@import \"tailwindcss\";\n\n\n ${stylesEntryPointContent}`,\n );\n}\n\nfunction findStylesEntryPoint(\n tree: Tree,\n options: NormalizedGeneratorOptions,\n project: ProjectConfiguration,\n): string | undefined {\n // first check for common names\n const possibleStylesEntryPoints = [\n joinPathFragments(project.sourceRoot ?? project.root, 'styles.css'),\n joinPathFragments(project.sourceRoot ?? project.root, 'styles.scss'),\n joinPathFragments(project.sourceRoot ?? project.root, 'styles.sass'),\n joinPathFragments(project.sourceRoot ?? project.root, 'styles.less'),\n ];\n\n const stylesEntryPoint = possibleStylesEntryPoints.find((s) =>\n tree.exists(s),\n );\n if (stylesEntryPoint) {\n return stylesEntryPoint;\n }\n\n // then check for the specified styles in the build configuration if it exists\n const styles: Array<string | { input: string; inject: boolean }> =\n project.targets?.[options.buildTarget].options?.styles;\n\n if (!styles) {\n return undefined;\n }\n\n // find the first style that belongs to the project source\n const style = styles.find((s) =>\n typeof s === 'string'\n ? s.startsWith(project.root) && tree.exists(s)\n : s.input.startsWith(project.root) &&\n s.inject !== false &&\n tree.exists(s.input),\n );\n\n if (!style) {\n return undefined;\n }\n\n return typeof style === 'string' ? style : style.input;\n}\n"],"mappings":";;;;;AAiBA,SAAgB,iBACd,SAC4B;AAC5B,QAAO;EACL,GAAG;EACH,aAAa,QAAQ,eAAe;EACrC;;AAGH,SAAgB,+BACd,MACuB;CACvB,MAAM,EAAE,cAAc,qBAAA,GAAA,WAAA,UAA6B,MAAM,eAAe;CACxE,MAAM,kBACJ,cAAc,eAAe,iBAAiB;AAEhD,KAAI,CAAC,gBACH;CAGF,MAAM,WAAA,GAAA,4BAAA,yBAAkC,eAAe,gBAAgB;AACvE,MAAA,GAAA,OAAA,IAAO,SAAS,QAAQ,CACtB,OAAM,IAAI,MACR,6BAA6B,gBAAgB,yDAC9C;AAEH,SAAA,GAAA,OAAA,IAAU,SAAS,QAAQ,GAAG,MAAM;;AAGtC,SAAgB,4BAA4B,MAA+B;CACzE,MAAM,cAAc,8BAAA,yBAAyB;AAC7C,SAAA,GAAA,WAAA,8BACE,MACA;EACE,SAAS,YAAY;EACrB,aAAa,YAAY;EACzB,wBAAwB,YAAY;EACpC,qBAAqB,YAAY;EAClC,EACD,EAAE,CACH;;AAGH,SAAgB,2BACd,MACA,SACM;CACN,MAAM,qBAAA,GAAA,WAAA,mBACJ,QAAQ,MACR,qBACD;AAED,KAAI,KAAK,OAAO,kBAAkB,CAChC;AAGF,MAAK,MACH,mBACA;;;;;EAMD;;AAGH,SAAgB,wBACd,MACA,SACA,SACM;CACN,IAAI,mBAAmB,QAAQ;AAE/B,KAAI,oBAAoB,CAAC,KAAK,OAAO,iBAAiB,CACpD,OAAM,IAAI,MACR,oCAAoC,iBAAiB,uBACtD;AAGH,KAAI,CAAC,kBAAkB;AACrB,qBAAmB,qBAAqB,MAAM,SAAS,QAAQ;AAE/D,MAAI,CAAC,iBACH,OAAM,IAAI,MACR,WAAA,YAAY,oDAAoD,QAAQ,QAAQ;oFAEjF;;AAIL,KAAI,CAAC,iBAAiB,SAAS,OAAO,CACpC,OAAM,IAAI,MACR,mIACD;CAGH,MAAM,0BAA0B,KAAK,KAAK,kBAAkB,QAAQ;AAEpE,MAAK,MACH,kBACA,WAAA,YAAY;;;MAGV,0BACH;;AAGH,SAAS,qBACP,MACA,SACA,SACoB;CASpB,MAAM,mBAP4B;oCACd,QAAQ,cAAc,QAAQ,MAAM,aAAa;oCACjD,QAAQ,cAAc,QAAQ,MAAM,cAAc;oCAClD,QAAQ,cAAc,QAAQ,MAAM,cAAc;oCAClD,QAAQ,cAAc,QAAQ,MAAM,cAAc;EACrE,CAEkD,MAAM,MACvD,KAAK,OAAO,EAAE,CACf;AACD,KAAI,iBACF,QAAO;CAIT,MAAM,SACJ,QAAQ,UAAU,QAAQ,aAAa,SAAS;AAElD,KAAI,CAAC,OACH;CAIF,MAAM,QAAQ,OAAO,MAAM,MACzB,OAAO,MAAM,WACT,EAAE,WAAW,QAAQ,KAAK,IAAI,KAAK,OAAO,EAAE,GAC5C,EAAE,MAAM,WAAW,QAAQ,KAAK,IAChC,EAAE,WAAW,SACb,KAAK,OAAO,EAAE,MAAM,CACzB;AAED,KAAI,CAAC,MACH;AAGF,QAAO,OAAO,UAAU,WAAW,QAAQ,MAAM"}
@@ -1,9 +1,9 @@
1
1
  export declare const V18_X_NX_DEVKIT = "^20.0.0";
2
2
  export declare const V18_X_NX_ANGULAR = "^20.0.0";
3
- export declare const V18_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.23";
4
- export declare const V18_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.23";
5
- export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.23";
6
- export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.23";
3
+ export declare const V18_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.25";
4
+ export declare const V18_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.25";
5
+ export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.25";
6
+ export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.25";
7
7
  export declare const V18_X_FRONT_MATTER = "^4.0.2";
8
8
  export declare const V18_X_MARKED = "^15.0.7";
9
9
  export declare const V18_X_MARKED_GFM_HEADING_ID = "^4.1.1";
@@ -12,8 +12,10 @@ export declare const V18_X_MARKED_MANGLE = "^1.1.10";
12
12
  export declare const V18_X_MERMAID = "^10.2.4";
13
13
  export declare const V18_X_PRISMJS = "^1.29.0";
14
14
  export declare const V18_X_TAILWINDCSS = "^4.2.2";
15
+ export declare const V18_X_TAILWINDCSS_POSTCSS = "^4.2.2";
15
16
  export declare const V18_X_TAILWINDCSS_VITE = "^4.2.2";
16
- export declare const V18_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.23";
17
+ export declare const V18_X_POSTCSS = "^8.5.6";
18
+ export declare const V18_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.25";
17
19
  export declare const V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = "^19.0.0";
18
20
  export declare const V18_X_NX_VITE = "^21.0.0";
19
21
  export declare const V18_X_NX_LINTER = "^21.0.0";
@@ -1,8 +1,12 @@
1
1
  //#region packages/nx-plugin/src/generators/app/versions/nx_18_X/versions.ts
2
2
  var V18_X_TAILWINDCSS = "^4.2.2";
3
+ var V18_X_TAILWINDCSS_POSTCSS = "^4.2.2";
3
4
  var V18_X_TAILWINDCSS_VITE = "^4.2.2";
5
+ var V18_X_POSTCSS = "^8.5.6";
4
6
  //#endregion
7
+ exports.V18_X_POSTCSS = V18_X_POSTCSS;
5
8
  exports.V18_X_TAILWINDCSS = V18_X_TAILWINDCSS;
9
+ exports.V18_X_TAILWINDCSS_POSTCSS = V18_X_TAILWINDCSS_POSTCSS;
6
10
  exports.V18_X_TAILWINDCSS_VITE = V18_X_TAILWINDCSS_VITE;
7
11
 
8
12
  //# sourceMappingURL=versions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","names":[],"sources":["../../../../../../../../../../nx-plugin/src/generators/app/versions/nx_18_X/versions.ts"],"sourcesContent":["// V18_X\n// dependencies\nexport const V18_X_NX_DEVKIT = '^20.0.0';\nexport const V18_X_NX_ANGULAR = '^20.0.0';\nexport const V18_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.23';\nexport const V18_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.23';\nexport const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.23';\nexport const V18_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.23';\nexport const V18_X_FRONT_MATTER = '^4.0.2';\nexport const V18_X_MARKED = '^15.0.7';\nexport const V18_X_MARKED_GFM_HEADING_ID = '^4.1.1';\nexport const V18_X_MARKED_HIGHLIGHT = '^2.2.1';\nexport const V18_X_MARKED_MANGLE = '^1.1.10';\nexport const V18_X_MERMAID = '^10.2.4';\nexport const V18_X_PRISMJS = '^1.29.0';\nexport const V18_X_TAILWINDCSS = '^4.2.2';\nexport const V18_X_TAILWINDCSS_VITE = '^4.2.2';\n\n// devDependencies\nexport const V18_X_ANALOG_JS_PLATFORM = '^3.0.0-alpha.23';\nexport const V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = '^19.0.0';\nexport const V18_X_NX_VITE = '^21.0.0';\nexport const V18_X_NX_LINTER = '^21.0.0';\nexport const V18_X_JSDOM = '^22.1.0';\nexport const V18_X_VITE = '^8.0.0';\nexport const V18_X_VITE_TSCONFIG_PATHS = '^4.2.0';\nexport const V18_X_VITEST = '^4.0.0';\nexport const V18_X_ZOD = '^3.21.4';\n"],"mappings":";AAeA,IAAa,oBAAoB;AACjC,IAAa,yBAAyB"}
1
+ {"version":3,"file":"versions.js","names":[],"sources":["../../../../../../../../../../nx-plugin/src/generators/app/versions/nx_18_X/versions.ts"],"sourcesContent":["// V18_X\n// dependencies\nexport const V18_X_NX_DEVKIT = '^20.0.0';\nexport const V18_X_NX_ANGULAR = '^20.0.0';\nexport const V18_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.25';\nexport const V18_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.25';\nexport const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.25';\nexport const V18_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.25';\nexport const V18_X_FRONT_MATTER = '^4.0.2';\nexport const V18_X_MARKED = '^15.0.7';\nexport const V18_X_MARKED_GFM_HEADING_ID = '^4.1.1';\nexport const V18_X_MARKED_HIGHLIGHT = '^2.2.1';\nexport const V18_X_MARKED_MANGLE = '^1.1.10';\nexport const V18_X_MERMAID = '^10.2.4';\nexport const V18_X_PRISMJS = '^1.29.0';\nexport const V18_X_TAILWINDCSS = '^4.2.2';\nexport const V18_X_TAILWINDCSS_POSTCSS = '^4.2.2';\nexport const V18_X_TAILWINDCSS_VITE = '^4.2.2';\nexport const V18_X_POSTCSS = '^8.5.6';\n\n// devDependencies\nexport const V18_X_ANALOG_JS_PLATFORM = '^3.0.0-alpha.25';\nexport const V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = '^19.0.0';\nexport const V18_X_NX_VITE = '^21.0.0';\nexport const V18_X_NX_LINTER = '^21.0.0';\nexport const V18_X_JSDOM = '^22.1.0';\nexport const V18_X_VITE = '^8.0.0';\nexport const V18_X_VITE_TSCONFIG_PATHS = '^4.2.0';\nexport const V18_X_VITEST = '^4.0.0';\nexport const V18_X_ZOD = '^3.21.4';\n"],"mappings":";AAeA,IAAa,oBAAoB;AACjC,IAAa,4BAA4B;AACzC,IAAa,yBAAyB;AACtC,IAAa,gBAAgB"}
@@ -1,4 +1,4 @@
1
- declare const tailwindDependencyKeys: readonly ["tailwindcss", "@tailwindcss/vite"];
1
+ declare const tailwindDependencyKeys: readonly ["postcss", "tailwindcss", "@tailwindcss/postcss", "@tailwindcss/vite"];
2
2
  export type TailwindDependency = (typeof tailwindDependencyKeys)[number];
3
3
  export declare const getTailwindDependencies: () => Record<TailwindDependency, string>;
4
4
  export {};
@@ -2,7 +2,9 @@ const require_versions = require("./nx_18_X/versions.js");
2
2
  //#region packages/nx-plugin/src/generators/app/versions/tailwind-dependencies.ts
3
3
  var getTailwindDependencies = () => {
4
4
  return {
5
+ postcss: require_versions.V18_X_POSTCSS,
5
6
  tailwindcss: require_versions.V18_X_TAILWINDCSS,
7
+ "@tailwindcss/postcss": require_versions.V18_X_TAILWINDCSS_POSTCSS,
6
8
  "@tailwindcss/vite": require_versions.V18_X_TAILWINDCSS_VITE
7
9
  };
8
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tailwind-dependencies.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/generators/app/versions/tailwind-dependencies.ts"],"sourcesContent":["import { V18_X_TAILWINDCSS, V18_X_TAILWINDCSS_VITE } from './nx_18_X/versions';\n\nconst tailwindDependencyKeys = ['tailwindcss', '@tailwindcss/vite'] as const;\n\nexport type TailwindDependency = (typeof tailwindDependencyKeys)[number];\n\nexport const getTailwindDependencies = (): Record<\n TailwindDependency,\n string\n> => {\n return {\n tailwindcss: V18_X_TAILWINDCSS,\n '@tailwindcss/vite': V18_X_TAILWINDCSS_VITE,\n };\n};\n"],"mappings":";;AAMA,IAAa,gCAGR;AACH,QAAO;EACL,aAAa,iBAAA;EACb,qBAAqB,iBAAA;EACtB"}
1
+ {"version":3,"file":"tailwind-dependencies.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/generators/app/versions/tailwind-dependencies.ts"],"sourcesContent":["import {\n V18_X_POSTCSS,\n V18_X_TAILWINDCSS,\n V18_X_TAILWINDCSS_POSTCSS,\n V18_X_TAILWINDCSS_VITE,\n} from './nx_18_X/versions';\n\nconst tailwindDependencyKeys = [\n 'postcss',\n 'tailwindcss',\n '@tailwindcss/postcss',\n '@tailwindcss/vite',\n] as const;\n\nexport type TailwindDependency = (typeof tailwindDependencyKeys)[number];\n\nexport const getTailwindDependencies = (): Record<\n TailwindDependency,\n string\n> => {\n return {\n postcss: V18_X_POSTCSS,\n tailwindcss: V18_X_TAILWINDCSS,\n '@tailwindcss/postcss': V18_X_TAILWINDCSS_POSTCSS,\n '@tailwindcss/vite': V18_X_TAILWINDCSS_VITE,\n };\n};\n"],"mappings":";;AAgBA,IAAa,gCAGR;AACH,QAAO;EACL,SAAS,iBAAA;EACT,aAAa,iBAAA;EACb,wBAAwB,iBAAA;EACxB,qBAAqB,iBAAA;EACtB"}
@@ -1,3 +1,4 @@
1
+ const require_camelCase = require("../../../node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js");
1
2
  let _nx_devkit = require("@nx/devkit");
2
3
  let node_path = require("node:path");
3
4
  //#region packages/nx-plugin/src/generators/page/generator.ts
@@ -10,7 +11,7 @@ function normalizeOptions(tree, options) {
10
11
  }
11
12
  function generateFileName(input) {
12
13
  if (/^[a-zA-Z0-9]+\.\[[a-zA-Z0-9-]+\]$/.test(input)) return input.replace(/\[[a-zA-Z0-9-]+\]/, (match) => {
13
- return `[${match.slice(1, -1).replace(/-([a-zA-Z0-9])/g, (_, letter) => letter.toUpperCase())}]`;
14
+ return `[${require_camelCase.camelCase(match.slice(1, -1))}]`;
14
15
  });
15
16
  else return input;
16
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","names":[],"sources":["../../../../../../../../nx-plugin/src/generators/page/generator.ts"],"sourcesContent":["import {\n formatFiles,\n generateFiles,\n getWorkspaceLayout,\n names,\n offsetFromRoot,\n stripIndents,\n Tree,\n} from '@nx/devkit';\nimport { join } from 'node:path';\nimport { AnalogPageGeneratorSchema, NormalizedSchema } from './schema';\n\nfunction normalizeOptions(\n tree: Tree,\n options: AnalogPageGeneratorSchema,\n): NormalizedSchema {\n const projectRoot = `${getWorkspaceLayout(tree).appsDir}/${options.project}`;\n return {\n ...options,\n projectRoot,\n };\n}\n\nfunction generateFileName(input: string) {\n const pattern = /^[a-zA-Z0-9]+\\.\\[[a-zA-Z0-9-]+\\]$/;\n if (pattern.test(input)) {\n return input.replace(/\\[[a-zA-Z0-9-]+\\]/, (match) => {\n const wordId = match.slice(1, -1);\n const camelCaseWordId = wordId.replace(/-([a-zA-Z0-9])/g, (_, letter) =>\n letter.toUpperCase(),\n );\n return `[${camelCaseWordId}]`;\n });\n } else {\n return input;\n }\n}\n\nfunction addFiles(tree: Tree, options: NormalizedSchema) {\n const splitName = options.pathname.split('/');\n const routeName = splitName[splitName.length - 1];\n const fileName = generateFileName(routeName);\n const templateOptions = {\n ...options,\n ...names(routeName),\n name: names(routeName).fileName,\n offsetFromRoot: offsetFromRoot(options.projectRoot),\n template: '',\n fileName,\n };\n\n const pageFolders = options.pathname.split('/').slice(0, -1);\n const pageDir = join(options.projectRoot, 'src/app/pages', ...pageFolders);\n\n generateFiles(tree, join(__dirname, 'files'), pageDir, templateOptions);\n}\n\nasync function analogPageGenerator(\n tree: Tree,\n options: AnalogPageGeneratorSchema,\n): Promise<void> {\n const normalizedOptions = normalizeOptions(tree, options);\n if (options.redirectPage && !options.redirectPath) {\n throw new Error(\n stripIndents`A redirectPath is required when redirectPage is true.`,\n );\n }\n addFiles(tree, normalizedOptions);\n\n await formatFiles(tree);\n}\n\nexport default analogPageGenerator;\n"],"mappings":";;;AAYA,SAAS,iBACP,MACA,SACkB;CAClB,MAAM,cAAc,IAAA,GAAA,WAAA,oBAAsB,KAAK,CAAC,QAAQ,GAAG,QAAQ;AACnE,QAAO;EACL,GAAG;EACH;EACD;;AAGH,SAAS,iBAAiB,OAAe;AAEvC,KADgB,oCACJ,KAAK,MAAM,CACrB,QAAO,MAAM,QAAQ,sBAAsB,UAAU;AAKnD,SAAO,IAJQ,MAAM,MAAM,GAAG,GAAG,CACF,QAAQ,oBAAoB,GAAG,WAC5D,OAAO,aAAa,CACrB,CAC0B;GAC3B;KAEF,QAAO;;AAIX,SAAS,SAAS,MAAY,SAA2B;CACvD,MAAM,YAAY,QAAQ,SAAS,MAAM,IAAI;CAC7C,MAAM,YAAY,UAAU,UAAU,SAAS;CAC/C,MAAM,WAAW,iBAAiB,UAAU;CAC5C,MAAM,kBAAkB;EACtB,GAAG;EACH,IAAA,GAAA,WAAA,OAAS,UAAU;EACnB,OAAA,GAAA,WAAA,OAAY,UAAU,CAAC;EACvB,iBAAA,GAAA,WAAA,gBAA+B,QAAQ,YAAY;EACnD,UAAU;EACV;EACD;CAED,MAAM,cAAc,QAAQ,SAAS,MAAM,IAAI,CAAC,MAAM,GAAG,GAAG;CAC5D,MAAM,WAAA,GAAA,UAAA,MAAe,QAAQ,aAAa,iBAAiB,GAAG,YAAY;AAE1E,EAAA,GAAA,WAAA,eAAc,OAAA,GAAA,UAAA,MAAW,WAAW,QAAQ,EAAE,SAAS,gBAAgB;;AAGzE,eAAe,oBACb,MACA,SACe;CACf,MAAM,oBAAoB,iBAAiB,MAAM,QAAQ;AACzD,KAAI,QAAQ,gBAAgB,CAAC,QAAQ,aACnC,OAAM,IAAI,MACR,WAAA,YAAY,wDACb;AAEH,UAAS,MAAM,kBAAkB;AAEjC,QAAA,GAAA,WAAA,aAAkB,KAAK"}
1
+ {"version":3,"file":"generator.js","names":[],"sources":["../../../../../../../../nx-plugin/src/generators/page/generator.ts"],"sourcesContent":["import {\n formatFiles,\n generateFiles,\n getWorkspaceLayout,\n names,\n offsetFromRoot,\n stripIndents,\n Tree,\n} from '@nx/devkit';\nimport { camelCase } from 'es-toolkit';\nimport { join } from 'node:path';\nimport { AnalogPageGeneratorSchema, NormalizedSchema } from './schema';\n\nfunction normalizeOptions(\n tree: Tree,\n options: AnalogPageGeneratorSchema,\n): NormalizedSchema {\n const projectRoot = `${getWorkspaceLayout(tree).appsDir}/${options.project}`;\n return {\n ...options,\n projectRoot,\n };\n}\n\nfunction generateFileName(input: string) {\n const pattern = /^[a-zA-Z0-9]+\\.\\[[a-zA-Z0-9-]+\\]$/;\n if (pattern.test(input)) {\n return input.replace(/\\[[a-zA-Z0-9-]+\\]/, (match) => {\n const wordId = match.slice(1, -1);\n return `[${camelCase(wordId)}]`;\n });\n } else {\n return input;\n }\n}\n\nfunction addFiles(tree: Tree, options: NormalizedSchema) {\n const splitName = options.pathname.split('/');\n const routeName = splitName[splitName.length - 1];\n const fileName = generateFileName(routeName);\n const templateOptions = {\n ...options,\n ...names(routeName),\n name: names(routeName).fileName,\n offsetFromRoot: offsetFromRoot(options.projectRoot),\n template: '',\n fileName,\n };\n\n const pageFolders = options.pathname.split('/').slice(0, -1);\n const pageDir = join(options.projectRoot, 'src/app/pages', ...pageFolders);\n\n generateFiles(tree, join(__dirname, 'files'), pageDir, templateOptions);\n}\n\nasync function analogPageGenerator(\n tree: Tree,\n options: AnalogPageGeneratorSchema,\n): Promise<void> {\n const normalizedOptions = normalizeOptions(tree, options);\n if (options.redirectPage && !options.redirectPath) {\n throw new Error(\n stripIndents`A redirectPath is required when redirectPage is true.`,\n );\n }\n addFiles(tree, normalizedOptions);\n\n await formatFiles(tree);\n}\n\nexport default analogPageGenerator;\n"],"mappings":";;;;AAaA,SAAS,iBACP,MACA,SACkB;CAClB,MAAM,cAAc,IAAA,GAAA,WAAA,oBAAsB,KAAK,CAAC,QAAQ,GAAG,QAAQ;AACnE,QAAO;EACL,GAAG;EACH;EACD;;AAGH,SAAS,iBAAiB,OAAe;AAEvC,KADgB,oCACJ,KAAK,MAAM,CACrB,QAAO,MAAM,QAAQ,sBAAsB,UAAU;AAEnD,SAAO,IAAI,kBAAA,UADI,MAAM,MAAM,GAAG,GAAG,CACL,CAAC;GAC7B;KAEF,QAAO;;AAIX,SAAS,SAAS,MAAY,SAA2B;CACvD,MAAM,YAAY,QAAQ,SAAS,MAAM,IAAI;CAC7C,MAAM,YAAY,UAAU,UAAU,SAAS;CAC/C,MAAM,WAAW,iBAAiB,UAAU;CAC5C,MAAM,kBAAkB;EACtB,GAAG;EACH,IAAA,GAAA,WAAA,OAAS,UAAU;EACnB,OAAA,GAAA,WAAA,OAAY,UAAU,CAAC;EACvB,iBAAA,GAAA,WAAA,gBAA+B,QAAQ,YAAY;EACnD,UAAU;EACV;EACD;CAED,MAAM,cAAc,QAAQ,SAAS,MAAM,IAAI,CAAC,MAAM,GAAG,GAAG;CAC5D,MAAM,WAAA,GAAA,UAAA,MAAe,QAAQ,aAAa,iBAAiB,GAAG,YAAY;AAE1E,EAAA,GAAA,WAAA,eAAc,OAAA,GAAA,UAAA,MAAW,WAAW,QAAQ,EAAE,SAAS,gBAAgB;;AAGzE,eAAe,oBACb,MACA,SACe;CACf,MAAM,oBAAoB,iBAAiB,MAAM,QAAQ;AACzD,KAAI,QAAQ,gBAAgB,CAAC,QAAQ,aACnC,OAAM,IAAI,MACR,WAAA,YAAY,wDACb;AAEH,UAAS,MAAM,kBAAkB;AAEjC,QAAA,GAAA,WAAA,aAAkB,KAAK"}
@@ -1,13 +1,13 @@
1
- export declare const V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.23";
2
- export declare const V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.23";
1
+ export declare const V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.25";
2
+ export declare const V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.25";
3
3
  export declare const V19_X_MARKED = "^15.0.7";
4
4
  export declare const V19_X_MARKED_GFM_HEADING_ID = "^4.1.1";
5
5
  export declare const V19_X_MARKED_HIGHLIGHT = "^2.2.1";
6
6
  export declare const V19_X_MARKED_MANGLE = "^1.1.10";
7
7
  export declare const V19_X_PRISMJS = "^1.29.0";
8
- export declare const V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.23";
9
- export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.23";
10
- export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.23";
8
+ export declare const V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.25";
9
+ export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.25";
10
+ export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.25";
11
11
  export declare const V19_X_NX_ANGULAR = "^22.0.0";
12
12
  export declare const V19_X_NX_VITE = "^22.0.0";
13
13
  export declare const V19_X_JSDOM = "^22.0.0";
@@ -1,14 +1,14 @@
1
1
  //#region packages/nx-plugin/src/utils/versions/ng_19_X/versions.ts
2
- var V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.23";
3
- var V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.23";
2
+ var V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.25";
3
+ var V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.25";
4
4
  var V19_X_MARKED = "^15.0.7";
5
5
  var V19_X_MARKED_GFM_HEADING_ID = "^4.1.1";
6
6
  var V19_X_MARKED_HIGHLIGHT = "^2.2.1";
7
7
  var V19_X_MARKED_MANGLE = "^1.1.10";
8
8
  var V19_X_PRISMJS = "^1.29.0";
9
- var V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.23";
10
- var V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.23";
11
- var V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.23";
9
+ var V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.25";
10
+ var V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.25";
11
+ var V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.25";
12
12
  var V19_X_NX_VITE = "^22.0.0";
13
13
  var V19_X_JSDOM = "^22.0.0";
14
14
  var V19_X_VITE_TSCONFIG_PATHS = "^4.2.0";
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/utils/versions/ng_19_X/versions.ts"],"sourcesContent":["// V19_X\nexport const V19_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.23';\nexport const V19_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.23';\nexport const V19_X_MARKED = '^15.0.7';\nexport const V19_X_MARKED_GFM_HEADING_ID = '^4.1.1';\nexport const V19_X_MARKED_HIGHLIGHT = '^2.2.1';\nexport const V19_X_MARKED_MANGLE = '^1.1.10';\nexport const V19_X_PRISMJS = '^1.29.0';\n\n// devDependencies\nexport const V19_X_ANALOG_JS_PLATFORM = '^3.0.0-alpha.23';\nexport const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.23';\nexport const V19_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.23';\nexport const V19_X_NX_ANGULAR = '^22.0.0';\nexport const V19_X_NX_VITE = '^22.0.0';\nexport const V19_X_JSDOM = '^22.0.0';\nexport const V19_X_VITE_TSCONFIG_PATHS = '^4.2.0';\nexport const V19_X_VITEST = '^3.0.0';\nexport const V19_X_VITE = '^6.0.0';\nexport const NX_X_LATEST_VITE = '^8.0.0';\nexport const NX_X_LATEST_VITEST = '^4.0.0';\n"],"mappings":";AACA,IAAa,yBAAyB;AACtC,IAAa,0BAA0B;AACvC,IAAa,eAAe;AAC5B,IAAa,8BAA8B;AAC3C,IAAa,yBAAyB;AACtC,IAAa,sBAAsB;AACnC,IAAa,gBAAgB;AAG7B,IAAa,2BAA2B;AACxC,IAAa,sCAAsC;AACnD,IAAa,iCAAiC;AAE9C,IAAa,gBAAgB;AAC7B,IAAa,cAAc;AAC3B,IAAa,4BAA4B;AACzC,IAAa,eAAe;AAC5B,IAAa,aAAa;AAC1B,IAAa,mBAAmB;AAChC,IAAa,qBAAqB"}
1
+ {"version":3,"file":"versions.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/utils/versions/ng_19_X/versions.ts"],"sourcesContent":["// V19_X\nexport const V19_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.25';\nexport const V19_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.25';\nexport const V19_X_MARKED = '^15.0.7';\nexport const V19_X_MARKED_GFM_HEADING_ID = '^4.1.1';\nexport const V19_X_MARKED_HIGHLIGHT = '^2.2.1';\nexport const V19_X_MARKED_MANGLE = '^1.1.10';\nexport const V19_X_PRISMJS = '^1.29.0';\n\n// devDependencies\nexport const V19_X_ANALOG_JS_PLATFORM = '^3.0.0-alpha.25';\nexport const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.25';\nexport const V19_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.25';\nexport const V19_X_NX_ANGULAR = '^22.0.0';\nexport const V19_X_NX_VITE = '^22.0.0';\nexport const V19_X_JSDOM = '^22.0.0';\nexport const V19_X_VITE_TSCONFIG_PATHS = '^4.2.0';\nexport const V19_X_VITEST = '^3.0.0';\nexport const V19_X_VITE = '^6.0.0';\nexport const NX_X_LATEST_VITE = '^8.0.0';\nexport const NX_X_LATEST_VITEST = '^4.0.0';\n"],"mappings":";AACA,IAAa,yBAAyB;AACtC,IAAa,0BAA0B;AACvC,IAAa,eAAe;AAC5B,IAAa,8BAA8B;AAC3C,IAAa,yBAAyB;AACtC,IAAa,sBAAsB;AACnC,IAAa,gBAAgB;AAG7B,IAAa,2BAA2B;AACxC,IAAa,sCAAsC;AACnD,IAAa,iCAAiC;AAE9C,IAAa,gBAAgB;AAC7B,IAAa,cAAc;AAC3B,IAAa,4BAA4B;AACzC,IAAa,eAAe;AAC5B,IAAa,aAAa;AAC1B,IAAa,mBAAmB;AAChC,IAAa,qBAAqB"}
@@ -44,7 +44,7 @@ export interface Options {
44
44
  *
45
45
  * When `false`, the following top-level options are ignored because they
46
46
  * are only forwarded to the internal Angular plugin: `jit`,
47
- * `disableTypeChecking`, `liveReload`, `inlineStylesExtension`,
47
+ * `disableTypeChecking`, `hmr`, `liveReload`, `inlineStylesExtension`,
48
48
  * `fileReplacements`, and `include`.
49
49
  *
50
50
  * Use this to configure the embedded Angular integration itself, not as the
@@ -62,7 +62,13 @@ export interface Options {
62
62
  */
63
63
  inlineStylesExtension?: string;
64
64
  /**
65
- * Enables Angular's HMR during development
65
+ * Enables Angular's HMR during development/watch mode.
66
+ *
67
+ * Defaults to `true` for watch mode.
68
+ */
69
+ hmr?: boolean;
70
+ /**
71
+ * @deprecated Use `hmr` instead. Kept as a compatibility alias.
66
72
  */
67
73
  liveReload?: boolean;
68
74
  /**
@@ -10,12 +10,13 @@ import { serverModePlugin } from "../server-mode-plugin.js";
10
10
  import { routeGenerationPlugin } from "./route-generation-plugin.js";
11
11
  import viteNitroPlugin from "@analogjs/vite-plugin-nitro";
12
12
  import angular from "@analogjs/vite-plugin-angular";
13
+ import { mapValues, union } from "es-toolkit";
13
14
  //#region packages/platform/src/lib/platform-plugin.ts
14
15
  function externalPlugins(plugins) {
15
16
  return plugins;
16
17
  }
17
18
  function platformPlugin(opts = {}) {
18
- applyDebugOption(opts.debug);
19
+ applyDebugOption(opts.debug, opts.workspaceRoot);
19
20
  const isTest = process.env.NODE_ENV === "test" || !!process.env["VITEST"];
20
21
  const viteOptions = opts?.vite === false ? void 0 : opts?.vite;
21
22
  const { ...platformOptions } = {
@@ -24,9 +25,9 @@ function platformPlugin(opts = {}) {
24
25
  };
25
26
  if (platformOptions.discoverRoutes) {
26
27
  const discovered = discoverLibraryRoutes(platformOptions.workspaceRoot ?? process.env["NX_WORKSPACE_ROOT"] ?? process.cwd());
27
- platformOptions.additionalPagesDirs = [...new Set([...platformOptions.additionalPagesDirs ?? [], ...discovered.additionalPagesDirs])];
28
- platformOptions.additionalContentDirs = [...new Set([...platformOptions.additionalContentDirs ?? [], ...discovered.additionalContentDirs])];
29
- platformOptions.additionalAPIDirs = [...new Set([...platformOptions.additionalAPIDirs ?? [], ...discovered.additionalAPIDirs])];
28
+ platformOptions.additionalPagesDirs = union(platformOptions.additionalPagesDirs ?? [], discovered.additionalPagesDirs);
29
+ platformOptions.additionalContentDirs = union(platformOptions.additionalContentDirs ?? [], discovered.additionalContentDirs);
30
+ platformOptions.additionalAPIDirs = union(platformOptions.additionalAPIDirs ?? [], discovered.additionalAPIDirs);
30
31
  }
31
32
  const useAngularCompilationAPI = platformOptions.experimental?.useAngularCompilationAPI ?? viteOptions?.experimental?.useAngularCompilationAPI;
32
33
  debugPlatform("experimental options resolved", {
@@ -36,18 +37,13 @@ function platformPlugin(opts = {}) {
36
37
  let nitroOptions = platformOptions?.nitro;
37
38
  if (nitroOptions?.routeRules) nitroOptions = {
38
39
  ...nitroOptions,
39
- routeRules: Object.keys(nitroOptions.routeRules).reduce((config, curr) => {
40
- return {
41
- ...config,
42
- [curr]: {
43
- ...config[curr],
44
- headers: {
45
- ...config[curr].headers,
46
- "x-analog-no-ssr": config[curr]?.ssr === false ? "true" : void 0
47
- }
48
- }
49
- };
50
- }, nitroOptions.routeRules)
40
+ routeRules: mapValues(nitroOptions.routeRules, (rule) => ({
41
+ ...rule,
42
+ headers: {
43
+ ...rule.headers,
44
+ "x-analog-no-ssr": rule?.ssr === false ? "true" : void 0
45
+ }
46
+ }))
51
47
  };
52
48
  return [
53
49
  {
@@ -68,6 +64,7 @@ function platformPlugin(opts = {}) {
68
64
  disableTypeChecking: platformOptions.disableTypeChecking,
69
65
  include: [...platformOptions.include ?? [], ...(platformOptions.additionalPagesDirs ?? []).map((pageDir) => `${pageDir}/**/*.page.ts`)],
70
66
  additionalContentDirs: platformOptions.additionalContentDirs,
67
+ hmr: platformOptions.hmr,
71
68
  liveReload: platformOptions.liveReload,
72
69
  inlineStylesExtension: platformOptions.inlineStylesExtension,
73
70
  fileReplacements: platformOptions.fileReplacements,