@analogjs/platform 3.0.0-alpha.7 → 3.0.0-alpha.70

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 (386) hide show
  1. package/migrations/migration.json +7 -1
  2. package/package.json +37 -23
  3. package/src/index.d.ts +11 -2
  4. package/src/index.js +12 -3
  5. package/src/index.js.map +1 -0
  6. package/src/lib/clear-client-page-endpoint.d.ts +1 -1
  7. package/src/lib/clear-client-page-endpoint.js +44 -32
  8. package/src/lib/clear-client-page-endpoint.js.map +1 -0
  9. package/src/lib/content/marked/index.d.ts +5 -5
  10. package/src/lib/content/marked/index.js +10 -6
  11. package/src/lib/content/marked/index.js.map +1 -0
  12. package/src/lib/content/marked/marked-content-highlighter.d.ts +2 -2
  13. package/src/lib/content/marked/marked-content-highlighter.js +6 -3
  14. package/src/lib/content/marked/marked-content-highlighter.js.map +1 -0
  15. package/src/lib/content/marked/marked-setup.service.d.ts +8 -8
  16. package/src/lib/content/marked/marked-setup.service.js +44 -54
  17. package/src/lib/content/marked/marked-setup.service.js.map +1 -0
  18. package/src/lib/content/prism/angular.js +18 -19
  19. package/src/lib/content/prism/angular.js.map +1 -0
  20. package/src/lib/content/prism/index.d.ts +1 -1
  21. package/src/lib/content/prism/index.js +10 -7
  22. package/src/lib/content/prism/index.js.map +1 -0
  23. package/src/lib/content/prism/options.d.ts +1 -1
  24. package/src/lib/content/prism/prism-highlighter.d.ts +5 -5
  25. package/src/lib/content/prism/prism-highlighter.js +33 -33
  26. package/src/lib/content/prism/prism-highlighter.js.map +1 -0
  27. package/src/lib/content/shiki/index.d.ts +3 -3
  28. package/src/lib/content/shiki/index.js +22 -28
  29. package/src/lib/content/shiki/index.js.map +1 -0
  30. package/src/lib/content/shiki/options.d.ts +8 -7
  31. package/src/lib/content/shiki/shiki-highlighter.d.ts +14 -13
  32. package/src/lib/content/shiki/shiki-highlighter.js +49 -43
  33. package/src/lib/content/shiki/shiki-highlighter.js.map +1 -0
  34. package/src/lib/content-plugin.d.ts +19 -19
  35. package/src/lib/content-plugin.js +181 -196
  36. package/src/lib/content-plugin.js.map +1 -0
  37. package/src/lib/deps-plugin.d.ts +2 -2
  38. package/src/lib/deps-plugin.js +84 -82
  39. package/src/lib/deps-plugin.js.map +1 -0
  40. package/src/lib/discover-library-routes.d.ts +22 -0
  41. package/src/lib/discover-library-routes.js +75 -0
  42. package/src/lib/discover-library-routes.js.map +1 -0
  43. package/src/lib/i18n-component-registry-plugin.d.ts +17 -0
  44. package/src/lib/i18n-component-registry-plugin.js +100 -0
  45. package/src/lib/i18n-component-registry-plugin.js.map +1 -0
  46. package/src/lib/i18n-extract-plugin.d.ts +33 -0
  47. package/src/lib/inject-server-fn-ids.d.ts +17 -0
  48. package/src/lib/inject-server-fn-ids.js +94 -0
  49. package/src/lib/inject-server-fn-ids.js.map +1 -0
  50. package/src/lib/json-ld-manifest-plugin.d.ts +41 -0
  51. package/src/lib/json-ld-manifest-plugin.js +84 -0
  52. package/src/lib/json-ld-manifest-plugin.js.map +1 -0
  53. package/src/lib/nitro/analog-nitro-plugin.d.ts +18 -0
  54. package/src/lib/nitro/analog-nitro-plugin.js +555 -0
  55. package/src/lib/nitro/analog-nitro-plugin.js.map +1 -0
  56. package/src/lib/nitro/angular-linker-plugin.d.ts +17 -0
  57. package/src/lib/nitro/angular-linker-plugin.js +51 -0
  58. package/src/lib/nitro/angular-linker-plugin.js.map +1 -0
  59. package/src/lib/nitro/build-sitemap.d.ts +23 -0
  60. package/src/lib/nitro/build-sitemap.js +137 -0
  61. package/src/lib/nitro/build-sitemap.js.map +1 -0
  62. package/src/lib/nitro/debug.d.ts +5 -0
  63. package/src/lib/nitro/debug.js +11 -0
  64. package/src/lib/nitro/debug.js.map +1 -0
  65. package/src/lib/nitro/get-content-files.d.ts +13 -0
  66. package/src/lib/nitro/get-content-files.js +52 -0
  67. package/src/lib/nitro/get-content-files.js.map +1 -0
  68. package/src/lib/nitro/get-page-handlers.d.ts +22 -0
  69. package/src/lib/nitro/get-page-handlers.js +33 -0
  70. package/src/lib/nitro/get-page-handlers.js.map +1 -0
  71. package/src/lib/nitro/i18n-prerender.d.ts +29 -0
  72. package/src/lib/nitro/i18n-prerender.js +61 -0
  73. package/src/lib/nitro/i18n-prerender.js.map +1 -0
  74. package/src/lib/nitro/page-endpoints-plugin.d.ts +7 -0
  75. package/src/lib/nitro/page-endpoints-plugin.js +72 -0
  76. package/src/lib/nitro/page-endpoints-plugin.js.map +1 -0
  77. package/src/lib/nitro/post-rendering-hook.d.ts +2 -0
  78. package/src/lib/nitro/post-rendering-hook.js +10 -0
  79. package/src/lib/nitro/post-rendering-hook.js.map +1 -0
  80. package/src/lib/nitro/renderers.d.ts +33 -0
  81. package/src/lib/nitro/renderers.js +22 -0
  82. package/src/lib/nitro/renderers.js.map +1 -0
  83. package/src/lib/nitro/types.d.ts +122 -0
  84. package/src/lib/nx-plugin/_virtual/_rolldown/runtime.js +23 -0
  85. package/src/lib/nx-plugin/builders.json +15 -0
  86. package/src/lib/nx-plugin/executors.json +13 -5
  87. package/src/lib/nx-plugin/generators.json +25 -0
  88. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js +13 -0
  89. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js.map +1 -0
  90. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.js +8 -0
  91. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.js.map +1 -0
  92. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.js +9 -0
  93. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.js.map +1 -0
  94. package/src/lib/nx-plugin/package.json +1 -5
  95. package/src/lib/nx-plugin/src/builders/vite/schema.json +39 -0
  96. package/src/lib/nx-plugin/src/builders/vite/vite-build.d.ts +11 -0
  97. package/src/lib/nx-plugin/src/builders/vite/vite-build.js +18 -0
  98. package/src/lib/nx-plugin/src/builders/vite/vite-build.js.map +1 -0
  99. package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.d.ts +7 -0
  100. package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.js +14 -0
  101. package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.js.map +1 -0
  102. package/src/lib/nx-plugin/src/builders/vite-dev-server/schema.json +27 -0
  103. package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.d.ts +1 -1
  104. package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.js +7 -7
  105. package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.js.map +1 -1
  106. package/src/lib/nx-plugin/src/executors/vite-dev-server/schema.d.ts +1 -1
  107. package/src/lib/nx-plugin/src/executors/vite-dev-server/vite-dev-server.impl.d.ts +1 -1
  108. package/src/lib/nx-plugin/src/executors/vite-dev-server/vite-dev-server.impl.js +6 -4
  109. package/src/lib/nx-plugin/src/executors/vite-dev-server/vite-dev-server.impl.js.map +1 -1
  110. package/src/lib/nx-plugin/src/executors/vitest/compat.d.ts +1 -1
  111. package/src/lib/nx-plugin/src/executors/vitest/compat.js +7 -7
  112. package/src/lib/nx-plugin/src/executors/vitest/compat.js.map +1 -1
  113. package/src/lib/nx-plugin/src/executors/vitest/schema.d.ts +1 -1
  114. package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.d.ts +1 -1
  115. package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.js +6 -4
  116. package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.js.map +1 -1
  117. package/src/lib/nx-plugin/src/generators/app/compat.d.ts +9 -3
  118. package/src/lib/nx-plugin/src/generators/app/compat.js +18 -7
  119. package/src/lib/nx-plugin/src/generators/app/compat.js.map +1 -1
  120. package/src/lib/nx-plugin/src/generators/app/files/agents/AGENTS.md +11 -0
  121. package/src/lib/nx-plugin/src/generators/app/files/agents/CLAUDE.md +1 -0
  122. package/src/lib/nx-plugin/src/generators/app/files/root/tsconfig.base.json +3 -6
  123. package/src/lib/nx-plugin/src/generators/app/files/template-angular/src/test-setup.ts__template__ +1 -0
  124. package/src/lib/nx-plugin/src/generators/app/files/template-angular/tsconfig.app.json__template__ +1 -3
  125. package/src/lib/nx-plugin/src/generators/app/files/template-angular/tsconfig.json__template__ +2 -1
  126. package/src/lib/nx-plugin/src/generators/app/files/template-angular/vite.config.ts__template__ +6 -2
  127. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v17/src/app/app.config.ts__template__ +0 -6
  128. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v17/tsconfig.json__template__ +4 -2
  129. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v17/vite.config.ts__template__ +1 -21
  130. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v18/src/app/app.config.ts__template__ +0 -6
  131. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v18/tsconfig.json__template__ +4 -2
  132. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v18/vite.config.ts__template__ +2 -22
  133. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/src/app/app.config.ts__template__ +0 -6
  134. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/tsconfig.app.json__template__ +1 -3
  135. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/tsconfig.json__template__ +4 -2
  136. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/vite.config.ts__template__ +1 -12
  137. package/src/lib/nx-plugin/src/generators/app/generator.d.ts +11 -11
  138. package/src/lib/nx-plugin/src/generators/app/generator.js +81 -92
  139. package/src/lib/nx-plugin/src/generators/app/generator.js.map +1 -1
  140. package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.d.ts +2 -0
  141. package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.js +16 -0
  142. package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.js.map +1 -0
  143. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.d.ts +1 -1
  144. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.d.ts +1 -1
  145. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.js +73 -81
  146. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.js.map +1 -1
  147. package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.d.ts +2 -2
  148. package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.js +25 -58
  149. package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.js.map +1 -1
  150. package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.d.ts +2 -2
  151. package/src/lib/nx-plugin/src/generators/app/lib/add-files.d.ts +2 -2
  152. package/src/lib/nx-plugin/src/generators/app/lib/add-files.js +16 -16
  153. package/src/lib/nx-plugin/src/generators/app/lib/add-files.js.map +1 -1
  154. package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.d.ts +2 -2
  155. package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.js +15 -13
  156. package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.js.map +1 -1
  157. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.d.ts +7 -7
  158. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.js +19 -29
  159. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.js.map +1 -1
  160. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.d.ts +4 -5
  161. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.js +61 -103
  162. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.js.map +1 -1
  163. package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.d.ts +1 -1
  164. package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.d.ts +2 -2
  165. package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.js +17 -20
  166. package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.js.map +1 -1
  167. package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.d.ts +2 -2
  168. package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.d.ts +1 -1
  169. package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.js +15 -18
  170. package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.js.map +1 -1
  171. package/src/lib/nx-plugin/src/generators/app/schema.d.ts +2 -0
  172. package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.d.ts +2 -3
  173. package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.js +7 -10
  174. package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.js.map +1 -1
  175. package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.d.ts +0 -3
  176. package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.d.ts +1 -6
  177. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.d.ts +12 -17
  178. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js +11 -37
  179. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js.map +1 -1
  180. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.d.ts +1 -1
  181. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.js +11 -15
  182. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.js.map +1 -1
  183. package/src/lib/nx-plugin/src/generators/app/versions.d.ts +0 -28
  184. package/src/lib/nx-plugin/src/generators/init/compat.d.ts +9 -3
  185. package/src/lib/nx-plugin/src/generators/init/compat.js +18 -7
  186. package/src/lib/nx-plugin/src/generators/init/compat.js.map +1 -1
  187. package/src/lib/nx-plugin/src/generators/init/files/vite.config.ts__template__ +2 -6
  188. package/src/lib/nx-plugin/src/generators/init/generator.d.ts +3 -3
  189. package/src/lib/nx-plugin/src/generators/init/generator.js +55 -65
  190. package/src/lib/nx-plugin/src/generators/init/generator.js.map +1 -1
  191. package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.d.ts +1 -1
  192. package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.js +20 -20
  193. package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.js.map +1 -1
  194. package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.d.ts +2 -2
  195. package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.js +21 -21
  196. package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.js.map +1 -1
  197. package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.d.ts +2 -2
  198. package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.js +57 -66
  199. package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.js.map +1 -1
  200. package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.d.ts +1 -1
  201. package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.js +12 -11
  202. package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.js.map +1 -1
  203. package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.d.ts +2 -2
  204. package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.js +18 -21
  205. package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.js.map +1 -1
  206. package/src/lib/nx-plugin/src/generators/init/lib/update-main.d.ts +2 -2
  207. package/src/lib/nx-plugin/src/generators/init/lib/update-main.js +13 -15
  208. package/src/lib/nx-plugin/src/generators/init/lib/update-main.js.map +1 -1
  209. package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.d.ts +2 -2
  210. package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.js +20 -31
  211. package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.js.map +1 -1
  212. package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.d.ts +2 -2
  213. package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.js +44 -51
  214. package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.js.map +1 -1
  215. package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.d.ts +2 -2
  216. package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.js +28 -34
  217. package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.js.map +1 -1
  218. package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.d.ts +2 -2
  219. package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.js +20 -20
  220. package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.js.map +1 -1
  221. package/src/lib/nx-plugin/src/generators/init/test-files/src/test-setup.ts__template__ +1 -0
  222. package/src/lib/nx-plugin/src/generators/page/__snapshots__/generator.spec.ts.snap +0 -7
  223. package/src/lib/nx-plugin/src/generators/page/compat.d.ts +9 -0
  224. package/src/lib/nx-plugin/src/generators/page/compat.js +19 -0
  225. package/src/lib/nx-plugin/src/generators/page/compat.js.map +1 -0
  226. package/src/lib/nx-plugin/src/generators/page/files/__fileName__.page.ts__template__ +0 -1
  227. package/src/lib/nx-plugin/src/generators/page/generator.d.ts +3 -4
  228. package/src/lib/nx-plugin/src/generators/page/generator.js +35 -44
  229. package/src/lib/nx-plugin/src/generators/page/generator.js.map +1 -1
  230. package/src/lib/nx-plugin/src/generators/preset/__snapshots__/generator.spec.ts.snap +8 -7
  231. package/src/lib/nx-plugin/src/generators/preset/generator.d.ts +3 -3
  232. package/src/lib/nx-plugin/src/generators/preset/generator.js +24 -43
  233. package/src/lib/nx-plugin/src/generators/preset/generator.js.map +1 -1
  234. package/src/lib/nx-plugin/src/generators/setup-vitest/compat.d.ts +9 -3
  235. package/src/lib/nx-plugin/src/generators/setup-vitest/compat.js +18 -7
  236. package/src/lib/nx-plugin/src/generators/setup-vitest/compat.js.map +1 -1
  237. package/src/lib/nx-plugin/src/generators/setup-vitest/files/src/test-setup.ts__template__ +1 -0
  238. package/src/lib/nx-plugin/src/generators/setup-vitest/files/vite.config.mts__template__ +0 -6
  239. package/src/lib/nx-plugin/src/generators/setup-vitest/generator.d.ts +3 -3
  240. package/src/lib/nx-plugin/src/generators/setup-vitest/generator.js +33 -42
  241. package/src/lib/nx-plugin/src/generators/setup-vitest/generator.js.map +1 -1
  242. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.d.ts +1 -1
  243. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.js +8 -7
  244. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.js.map +1 -1
  245. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.d.ts +2 -2
  246. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.js +21 -27
  247. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.js.map +1 -1
  248. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.d.ts +2 -2
  249. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.js +20 -22
  250. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.js.map +1 -1
  251. package/src/lib/nx-plugin/src/index.js +0 -2
  252. package/src/lib/nx-plugin/src/utils/version-utils.d.ts +1 -1
  253. package/src/lib/nx-plugin/src/utils/version-utils.js +21 -27
  254. package/src/lib/nx-plugin/src/utils/version-utils.js.map +1 -1
  255. package/src/lib/nx-plugin/src/utils/versions/dependencies.js +43 -62
  256. package/src/lib/nx-plugin/src/utils/versions/dependencies.js.map +1 -1
  257. package/src/lib/nx-plugin/src/utils/versions/dev-dependencies.js +50 -83
  258. package/src/lib/nx-plugin/src/utils/versions/dev-dependencies.js.map +1 -1
  259. package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.d.ts +1 -1
  260. package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.js +33 -20
  261. package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.js.map +1 -1
  262. package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.d.ts +1 -1
  263. package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.js +33 -20
  264. package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.js.map +1 -1
  265. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.d.ts +9 -8
  266. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js +39 -23
  267. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js.map +1 -1
  268. package/src/lib/options.d.ts +175 -80
  269. package/src/lib/platform-plugin.d.ts +2 -2
  270. package/src/lib/platform-plugin.js +48 -62
  271. package/src/lib/platform-plugin.js.map +1 -0
  272. package/src/lib/route-file-discovery.d.ts +23 -0
  273. package/src/lib/route-file-discovery.js +114 -0
  274. package/src/lib/route-file-discovery.js.map +1 -0
  275. package/src/lib/route-generation-plugin.d.ts +3 -0
  276. package/src/lib/route-generation-plugin.js +45 -0
  277. package/src/lib/route-generation-plugin.js.map +1 -0
  278. package/src/lib/route-idiom-diagnostics.d.ts +13 -0
  279. package/src/lib/route-idiom-diagnostics.js +160 -0
  280. package/src/lib/route-idiom-diagnostics.js.map +1 -0
  281. package/src/lib/route-manifest.d.ts +122 -0
  282. package/src/lib/route-manifest.js +431 -0
  283. package/src/lib/route-manifest.js.map +1 -0
  284. package/src/lib/router-plugin.d.ts +19 -19
  285. package/src/lib/router-plugin.js +234 -176
  286. package/src/lib/router-plugin.js.map +1 -0
  287. package/src/lib/server-fn-client-transform.d.ts +26 -0
  288. package/src/lib/server-fn-client-transform.js +97 -0
  289. package/src/lib/server-fn-client-transform.js.map +1 -0
  290. package/src/lib/server-fn-id.d.ts +25 -0
  291. package/src/lib/server-fn-id.js +37 -0
  292. package/src/lib/server-fn-id.js.map +1 -0
  293. package/src/lib/ssr/defer-streaming-plugin.d.ts +65 -0
  294. package/src/lib/ssr/inject-html-plugin.d.ts +1 -1
  295. package/src/lib/ssr/inject-html-plugin.js +25 -25
  296. package/src/lib/ssr/inject-html-plugin.js.map +1 -0
  297. package/src/lib/ssr/ssr-build-plugin.d.ts +26 -2
  298. package/src/lib/ssr/ssr-build-plugin.js +38 -30
  299. package/src/lib/ssr/ssr-build-plugin.js.map +1 -0
  300. package/src/lib/style-pipeline.d.ts +33 -0
  301. package/src/lib/style-pipeline.js +32 -0
  302. package/src/lib/style-pipeline.js.map +1 -0
  303. package/src/lib/style-preprocessor.d.ts +28 -0
  304. package/src/lib/style-preprocessor.js +35 -0
  305. package/src/lib/style-preprocessor.js.map +1 -0
  306. package/src/lib/tailwind-preprocessor.d.ts +23 -0
  307. package/src/lib/tailwind-preprocessor.js +153 -0
  308. package/src/lib/tailwind-preprocessor.js.map +1 -0
  309. package/src/lib/typed-routes-plugin.d.ts +50 -0
  310. package/src/lib/typed-routes-plugin.js +234 -0
  311. package/src/lib/typed-routes-plugin.js.map +1 -0
  312. package/src/lib/utils/debug-harness.d.ts +23 -0
  313. package/src/lib/utils/debug-harness.js +88 -0
  314. package/src/lib/utils/debug-harness.js.map +1 -0
  315. package/src/lib/utils/debug-log-file.d.ts +5 -0
  316. package/src/lib/utils/debug-log-file.js +56 -0
  317. package/src/lib/utils/debug-log-file.js.map +1 -0
  318. package/src/lib/utils/debug.d.ts +22 -0
  319. package/src/lib/utils/debug.js +27 -0
  320. package/src/lib/utils/debug.js.map +1 -0
  321. package/src/lib/utils/rolldown.d.ts +3 -0
  322. package/src/lib/utils/rolldown.js +15 -0
  323. package/src/lib/utils/rolldown.js.map +1 -0
  324. package/src/server-mode-plugin.d.ts +6 -6
  325. package/src/server-mode-plugin.js +16 -18
  326. package/src/server-mode-plugin.js.map +1 -0
  327. package/src/style-pipeline.d.ts +1 -0
  328. package/src/style-pipeline.js +2 -0
  329. package/src/style-preprocessor.d.ts +1 -0
  330. package/src/style-preprocessor.js +2 -0
  331. package/README.md +0 -5
  332. package/src/lib/content/prism/options.js +0 -1
  333. package/src/lib/content/shiki/options.js +0 -1
  334. package/src/lib/nx-plugin/README.md +0 -23
  335. package/src/lib/nx-plugin/src/executors/vite/compat.d.ts +0 -3
  336. package/src/lib/nx-plugin/src/executors/vite/compat.js +0 -8
  337. package/src/lib/nx-plugin/src/executors/vite/compat.js.map +0 -1
  338. package/src/lib/nx-plugin/src/executors/vite/schema.d.ts +0 -2
  339. package/src/lib/nx-plugin/src/executors/vite/schema.json +0 -147
  340. package/src/lib/nx-plugin/src/executors/vite/vite.impl.d.ts +0 -2
  341. package/src/lib/nx-plugin/src/executors/vite/vite.impl.js +0 -5
  342. package/src/lib/nx-plugin/src/executors/vite/vite.impl.js.map +0 -1
  343. package/src/lib/nx-plugin/src/generators/app/files/tailwind/v4/.postcssrc.json +0 -5
  344. package/src/lib/nx-plugin/src/generators/app/files/tailwind/v4/tailwind.config.ts__template__ +0 -14
  345. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/index.html__template__ +0 -15
  346. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.spec.ts__template__ +0 -17
  347. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.ts__template__ +0 -10
  348. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/favicon.ico__template__ +0 -0
  349. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.providers.ts__template__ +0 -5
  350. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.server.ts__template__ +0 -23
  351. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.ts__template__ +0 -17
  352. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/.gitkeep__template__ +0 -0
  353. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/analog.svg__template__ +0 -1
  354. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/vite.svg__template__ +0 -1
  355. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/server/routes/v1/hello.ts__template__ +0 -3
  356. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/styles.css__template__ +0 -4
  357. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/test-setup.ts__template__ +0 -12
  358. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/vite-env.d.ts__template__ +0 -1
  359. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.app.json__template__ +0 -16
  360. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.editor.json__template__ +0 -7
  361. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.json__template__ +0 -32
  362. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.spec.json__template__ +0 -14
  363. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/vite.config.ts__template__ +0 -69
  364. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.js +0 -15
  365. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.js.map +0 -1
  366. package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.js +0 -58
  367. package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.js.map +0 -1
  368. package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.js +0 -47
  369. package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.js.map +0 -1
  370. package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.js +0 -110
  371. package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.js.map +0 -1
  372. package/src/lib/nx-plugin/src/generators/app/versions/dependencies.js +0 -56
  373. package/src/lib/nx-plugin/src/generators/app/versions/dependencies.js.map +0 -1
  374. package/src/lib/nx-plugin/src/generators/app/versions/dev-dependencies.js +0 -72
  375. package/src/lib/nx-plugin/src/generators/app/versions/dev-dependencies.js.map +0 -1
  376. package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.js +0 -46
  377. package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.js.map +0 -1
  378. package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.js +0 -37
  379. package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.js.map +0 -1
  380. package/src/lib/nx-plugin/src/generators/app/versions.js +0 -43
  381. package/src/lib/nx-plugin/src/generators/app/versions.js.map +0 -1
  382. package/src/lib/nx-plugin/src/index.d.ts +0 -0
  383. package/src/lib/nx-plugin/src/index.js.map +0 -1
  384. package/src/lib/options.js +0 -1
  385. package/src/lib/ssr/ssr-xhr-plugin.d.ts +0 -2
  386. package/src/lib/ssr/ssr-xhr-plugin.js +0 -28
@@ -0,0 +1,153 @@
1
+ import { debugTailwind } from "./utils/debug.js";
2
+ import path from "node:path";
3
+ import { readFileSync } from "node:fs";
4
+ //#region packages/platform/src/lib/tailwind-preprocessor.ts
5
+ var PLATFORM_TAILWIND_PREFIX = "[@analogjs/platform]";
6
+ var CSS_REFERENCE_DIRECTIVE_REGEX = /(^|[;}\n\r])\s*@reference\b/m;
7
+ var CSS_TAILWIND_IMPORT_REGEX = /(^|[;}\n\r])\s*@import\s+["']tailwindcss["']/m;
8
+ function stripCssBlockComments(code) {
9
+ let result = "";
10
+ let quote = null;
11
+ for (let index = 0; index < code.length; index++) {
12
+ const character = code[index];
13
+ const nextCharacter = code[index + 1];
14
+ if (quote) {
15
+ if (character === "\\" && nextCharacter) {
16
+ result += character;
17
+ result += nextCharacter;
18
+ index++;
19
+ continue;
20
+ }
21
+ if (character === quote) quote = null;
22
+ result += character;
23
+ continue;
24
+ }
25
+ if (character === "\"" || character === "'" || character === "`") {
26
+ quote = character;
27
+ result += character;
28
+ continue;
29
+ }
30
+ if (character === "/" && nextCharacter === "*") {
31
+ result += " ";
32
+ index += 2;
33
+ while (index < code.length) {
34
+ const commentCharacter = code[index];
35
+ const commentNextCharacter = code[index + 1];
36
+ if (commentCharacter === "*" && commentNextCharacter === "/") {
37
+ result += " ";
38
+ index++;
39
+ break;
40
+ }
41
+ result += commentCharacter === "\n" || commentCharacter === "\r" ? commentCharacter : " ";
42
+ index++;
43
+ }
44
+ continue;
45
+ }
46
+ result += character;
47
+ }
48
+ return result;
49
+ }
50
+ function hasReferenceTextInComments(code) {
51
+ let quote = null;
52
+ for (let index = 0; index < code.length; index++) {
53
+ const character = code[index];
54
+ const nextCharacter = code[index + 1];
55
+ if (quote) {
56
+ if (character === "\\" && nextCharacter) {
57
+ index++;
58
+ continue;
59
+ }
60
+ if (character === quote) quote = null;
61
+ continue;
62
+ }
63
+ if (character === "\"" || character === "'" || character === "`") {
64
+ quote = character;
65
+ continue;
66
+ }
67
+ if (character === "/" && nextCharacter === "*") {
68
+ const commentStart = index + 2;
69
+ index += 2;
70
+ while (index < code.length) {
71
+ const commentCharacter = code[index];
72
+ const commentNextCharacter = code[index + 1];
73
+ if (commentCharacter === "*" && commentNextCharacter === "/") break;
74
+ index++;
75
+ }
76
+ if (code.slice(commentStart, index).includes("@reference")) return true;
77
+ }
78
+ }
79
+ return false;
80
+ }
81
+ function inspectCssTailwindDirectives(code) {
82
+ const commentlessCode = stripCssBlockComments(code);
83
+ return {
84
+ commentlessCode,
85
+ hasReferenceDirective: CSS_REFERENCE_DIRECTIVE_REGEX.test(commentlessCode),
86
+ hasReferenceText: hasReferenceTextInComments(code),
87
+ hasTailwindImportDirective: CSS_TAILWIND_IMPORT_REGEX.test(commentlessCode)
88
+ };
89
+ }
90
+ function toReferenceSpecifier(filename, tailwindRootCss) {
91
+ const fromDir = path.posix.dirname(filename.replace(/\\/g, "/"));
92
+ const toFile = tailwindRootCss.replace(/\\/g, "/");
93
+ const relativePath = path.posix.relative(fromDir, toFile);
94
+ return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
95
+ }
96
+ function throwTailwindReferenceTextError(filename, referenceSpecifier) {
97
+ throw new Error(`${PLATFORM_TAILWIND_PREFIX} Tailwind @reference auto-injection was blocked for "${filename}" because the stylesheet contains the text "@reference" but does not contain a real @reference directive.\n\nThis is usually caused by a CSS comment such as "/* ... @reference ... */".\n\nFix one of:\n - Reword the comment so it does not contain "@reference"\n - Add a real @reference "${referenceSpecifier}"; directive\n`);
98
+ }
99
+ /**
100
+ * Creates a stylesheet preprocessor that injects Tailwind v4 `@reference`
101
+ * directives into Angular component styles when needed. The Tailwind prefix is
102
+ * detected from the configured root CSS file.
103
+ */
104
+ function tailwindPreprocessor(options) {
105
+ const { tailwindRootCss, mode: modeOption = "auto", shouldInject } = options;
106
+ let rootPrefix;
107
+ debugTailwind("configured", {
108
+ tailwindRootCss,
109
+ mode: modeOption
110
+ });
111
+ return (code, filename) => {
112
+ const directiveState = inspectCssTailwindDirectives(code);
113
+ if (directiveState.hasReferenceDirective) {
114
+ debugTailwind("skip (already has @reference)", { filename });
115
+ return code;
116
+ }
117
+ const resolvedMode = typeof modeOption === "function" ? modeOption(filename) : modeOption;
118
+ if (resolvedMode === "disabled") {
119
+ debugTailwind("skip (mode disabled)", { filename });
120
+ return code;
121
+ }
122
+ const resolvedPrefix = typeof resolvedMode === "object" ? resolvedMode.prefix : getRootPrefix();
123
+ const isRootFile = path.resolve(filename) === path.resolve(tailwindRootCss) || directiveState.hasTailwindImportDirective;
124
+ const hasTailwindUsage = resolvedPrefix ? directiveState.commentlessCode.includes(`${resolvedPrefix}:`) : false;
125
+ if (!(shouldInject ? shouldInject(code, filename, resolvedPrefix) : hasTailwindUsage && !isRootFile) || !resolvedPrefix) {
126
+ debugTailwind("skip (no injection needed)", {
127
+ filename,
128
+ resolvedPrefix,
129
+ isRootFile,
130
+ hasTailwindUsage
131
+ });
132
+ return code;
133
+ }
134
+ const refPath = toReferenceSpecifier(filename, tailwindRootCss);
135
+ if (directiveState.hasReferenceText) throwTailwindReferenceTextError(filename, refPath);
136
+ debugTailwind("injected @reference", {
137
+ filename,
138
+ refPath
139
+ });
140
+ return `@reference "${refPath}";\n${code}`;
141
+ };
142
+ function getRootPrefix() {
143
+ if (rootPrefix === void 0) rootPrefix = extractTailwindPrefix(readFileSync(tailwindRootCss, "utf-8"));
144
+ return rootPrefix;
145
+ }
146
+ }
147
+ function extractTailwindPrefix(code) {
148
+ return code.match(/@import\s+["']tailwindcss["']\s+prefix\(\s*([^)\s;]+)\s*\)/i)?.[1]?.trim() ?? null;
149
+ }
150
+ //#endregion
151
+ export { tailwindPreprocessor };
152
+
153
+ //# sourceMappingURL=tailwind-preprocessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwind-preprocessor.js","names":[],"sources":["../../../src/lib/tailwind-preprocessor.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport path from 'node:path';\n\nimport type { StylePreprocessor } from './style-preprocessor.js';\nimport { debugTailwind } from './utils/debug.js';\n\nexport type TailwindPreprocessorMode = 'auto' | 'disabled' | { prefix: string };\nconst PLATFORM_TAILWIND_PREFIX = '[@analogjs/platform]';\nconst CSS_REFERENCE_DIRECTIVE_REGEX = /(^|[;}\\n\\r])\\s*@reference\\b/m;\nconst CSS_TAILWIND_IMPORT_REGEX =\n /(^|[;}\\n\\r])\\s*@import\\s+[\"']tailwindcss[\"']/m;\n\ninterface CssTailwindDirectiveState {\n commentlessCode: string;\n hasReferenceDirective: boolean;\n hasReferenceText: boolean;\n hasTailwindImportDirective: boolean;\n}\n\n// Mask real block comments while preserving quoted CSS content. This keeps\n// prose like `/* add @reference here */` from disabling injection without\n// mistaking `/* ... */` sequences inside strings for real comments.\nfunction stripCssBlockComments(code: string): string {\n let result = '';\n let quote: '\"' | \"'\" | '`' | null = null;\n\n for (let index = 0; index < code.length; index++) {\n const character = code[index];\n const nextCharacter = code[index + 1];\n\n if (quote) {\n if (character === '\\\\' && nextCharacter) {\n result += character;\n result += nextCharacter;\n index++;\n continue;\n }\n if (character === quote) {\n quote = null;\n }\n result += character;\n continue;\n }\n\n if (character === '\"' || character === \"'\" || character === '`') {\n quote = character;\n result += character;\n continue;\n }\n\n if (character === '/' && nextCharacter === '*') {\n result += ' ';\n index += 2;\n\n while (index < code.length) {\n const commentCharacter = code[index];\n const commentNextCharacter = code[index + 1];\n\n if (commentCharacter === '*' && commentNextCharacter === '/') {\n result += ' ';\n index++;\n break;\n }\n\n result +=\n commentCharacter === '\\n' || commentCharacter === '\\r'\n ? commentCharacter\n : ' ';\n index++;\n }\n continue;\n }\n\n result += character;\n }\n\n return result;\n}\n\nfunction hasReferenceTextInComments(code: string): boolean {\n let quote: '\"' | \"'\" | '`' | null = null;\n\n for (let index = 0; index < code.length; index++) {\n const character = code[index];\n const nextCharacter = code[index + 1];\n\n if (quote) {\n if (character === '\\\\' && nextCharacter) {\n index++;\n continue;\n }\n if (character === quote) {\n quote = null;\n }\n continue;\n }\n\n if (character === '\"' || character === \"'\" || character === '`') {\n quote = character;\n continue;\n }\n\n if (character === '/' && nextCharacter === '*') {\n const commentStart = index + 2;\n index += 2;\n\n while (index < code.length) {\n const commentCharacter = code[index];\n const commentNextCharacter = code[index + 1];\n\n if (commentCharacter === '*' && commentNextCharacter === '/') {\n break;\n }\n index++;\n }\n\n if (code.slice(commentStart, index).includes('@reference')) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nfunction inspectCssTailwindDirectives(code: string): CssTailwindDirectiveState {\n const commentlessCode = stripCssBlockComments(code);\n\n return {\n commentlessCode,\n hasReferenceDirective: CSS_REFERENCE_DIRECTIVE_REGEX.test(commentlessCode),\n hasReferenceText: hasReferenceTextInComments(code),\n hasTailwindImportDirective: CSS_TAILWIND_IMPORT_REGEX.test(commentlessCode),\n };\n}\n\nfunction toReferenceSpecifier(\n filename: string,\n tailwindRootCss: string,\n): string {\n const fromDir = path.posix.dirname(filename.replace(/\\\\/g, '/'));\n const toFile = tailwindRootCss.replace(/\\\\/g, '/');\n const relativePath = path.posix.relative(fromDir, toFile);\n\n return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;\n}\n\nfunction throwTailwindReferenceTextError(\n filename: string,\n referenceSpecifier: string,\n): never {\n throw new Error(\n `${PLATFORM_TAILWIND_PREFIX} Tailwind @reference auto-injection was ` +\n `blocked for \"${filename}\" because the stylesheet contains the ` +\n `text \"@reference\" but does not contain a real @reference ` +\n `directive.\\n\\n` +\n `This is usually caused by a CSS comment such as ` +\n `\"/* ... @reference ... */\".\\n\\n` +\n `Fix one of:\\n` +\n ` - Reword the comment so it does not contain \"@reference\"\\n` +\n ` - Add a real @reference \"${referenceSpecifier}\"; directive\\n`,\n );\n}\n\nexport interface TailwindPreprocessorOptions {\n /** Absolute path to the Tailwind root CSS file that imports `tailwindcss`. */\n tailwindRootCss: string;\n\n /**\n * Controls whether the preprocessor auto-detects, disables, or manually\n * overrides the Tailwind prefix for a given file.\n */\n mode?:\n | TailwindPreprocessorMode\n | ((filename: string) => TailwindPreprocessorMode);\n\n /**\n * Optional predicate to override the default `@reference` injection behavior.\n */\n shouldInject?: (\n code: string,\n filename: string,\n resolvedPrefix: string | null,\n ) => boolean;\n}\n\n/**\n * Creates a stylesheet preprocessor that injects Tailwind v4 `@reference`\n * directives into Angular component styles when needed. The Tailwind prefix is\n * detected from the configured root CSS file.\n */\nexport function tailwindPreprocessor(\n options: TailwindPreprocessorOptions,\n): StylePreprocessor {\n const { tailwindRootCss, mode: modeOption = 'auto', shouldInject } = options;\n let rootPrefix: string | undefined;\n\n debugTailwind('configured', { tailwindRootCss, mode: modeOption });\n\n return (code: string, filename: string): string => {\n const directiveState = inspectCssTailwindDirectives(code);\n\n if (directiveState.hasReferenceDirective) {\n debugTailwind('skip (already has @reference)', { filename });\n return code;\n }\n\n const resolvedMode =\n typeof modeOption === 'function' ? modeOption(filename) : modeOption;\n\n if (resolvedMode === 'disabled') {\n debugTailwind('skip (mode disabled)', { filename });\n return code;\n }\n\n const resolvedPrefix =\n typeof resolvedMode === 'object' ? resolvedMode.prefix : getRootPrefix();\n const isRootFile =\n path.resolve(filename) === path.resolve(tailwindRootCss) ||\n directiveState.hasTailwindImportDirective;\n const hasTailwindUsage = resolvedPrefix\n ? directiveState.commentlessCode.includes(`${resolvedPrefix}:`)\n : false;\n const shouldAddReference = shouldInject\n ? shouldInject(code, filename, resolvedPrefix)\n : hasTailwindUsage && !isRootFile;\n\n if (!shouldAddReference || !resolvedPrefix) {\n debugTailwind('skip (no injection needed)', {\n filename,\n resolvedPrefix,\n isRootFile,\n hasTailwindUsage,\n });\n return code;\n }\n\n const refPath = toReferenceSpecifier(filename, tailwindRootCss);\n if (directiveState.hasReferenceText) {\n throwTailwindReferenceTextError(filename, refPath);\n }\n\n debugTailwind('injected @reference', { filename, refPath });\n\n return `@reference \"${refPath}\";\\n${code}`;\n };\n\n function getRootPrefix(): string | null {\n if (rootPrefix === undefined) {\n rootPrefix = extractTailwindPrefix(\n readFileSync(tailwindRootCss, 'utf-8'),\n );\n }\n\n return rootPrefix;\n }\n}\n\nfunction extractTailwindPrefix(code: string): string | null {\n const prefixMatch = code.match(\n /@import\\s+[\"']tailwindcss[\"']\\s+prefix\\(\\s*([^)\\s;]+)\\s*\\)/i,\n );\n\n return prefixMatch?.[1]?.trim() ?? null;\n}\n"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { type Plugin } from "vite";
2
+ export interface TypedRoutesPluginOptions {
3
+ /**
4
+ * Output path for the single generated route module,
5
+ * relative to the app root.
6
+ *
7
+ * @default 'src/routeTree.gen.ts'
8
+ */
9
+ outFile?: string;
10
+ /**
11
+ * Workspace root used to resolve additional route/content directories.
12
+ *
13
+ * @default process.env['NX_WORKSPACE_ROOT'] ?? process.cwd()
14
+ */
15
+ workspaceRoot?: string;
16
+ /**
17
+ * Additional page directories to scan for `.page.ts` files.
18
+ */
19
+ additionalPagesDirs?: string[];
20
+ /**
21
+ * Additional content directories to scan for `.md` files.
22
+ */
23
+ additionalContentDirs?: string[];
24
+ /**
25
+ * Include generated `routeJsonLdManifest` exports in the generated route file.
26
+ *
27
+ * @default true
28
+ */
29
+ jsonLdManifest?: boolean;
30
+ /**
31
+ * When true, compare generated output against the existing file and
32
+ * throw an error if they differ instead of writing. Useful for CI to
33
+ * detect stale checked-in route files.
34
+ *
35
+ * @default false
36
+ */
37
+ verify?: boolean;
38
+ /**
39
+ * When true, production builds fail after regenerating a stale checked-in
40
+ * route file. This preserves self-healing writes in development while making
41
+ * build-time freshness issues visible by default.
42
+ *
43
+ * @default true
44
+ */
45
+ verifyOnBuild?: boolean;
46
+ }
47
+ /**
48
+ * Vite plugin that generates a single typed route module for Analog file routes.
49
+ */
50
+ export declare function typedRoutes(options?: TypedRoutesPluginOptions): Plugin;
@@ -0,0 +1,234 @@
1
+ import { debugTypedRouter } from "./utils/debug.js";
2
+ import { detectSchemaExports, filenameToRoutePath, formatManifestSummary, generateRouteManifest, generateRouteTableDeclaration, generateRouteTreeDeclaration } from "./route-manifest.js";
3
+ import { detectJsonLdModuleExports, extractMarkdownJsonLd, generateJsonLdManifestSource } from "./json-ld-manifest-plugin.js";
4
+ import { createRouteFileDiscovery } from "./route-file-discovery.js";
5
+ import { dirname, join, relative, resolve } from "node:path";
6
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { normalizePath } from "vite";
8
+ //#region packages/platform/src/lib/typed-routes-plugin.ts
9
+ var DEFAULT_OUT_FILE = "src/routeTree.gen.ts";
10
+ function resolvePluginOptions(options = {}) {
11
+ return {
12
+ outFile: options.outFile ?? DEFAULT_OUT_FILE,
13
+ workspaceRoot: options.workspaceRoot ?? process.env["NX_WORKSPACE_ROOT"] ?? process.cwd(),
14
+ additionalPagesDirs: options.additionalPagesDirs ?? [],
15
+ additionalContentDirs: options.additionalContentDirs ?? [],
16
+ jsonLdManifest: options.jsonLdManifest ?? true,
17
+ verify: options.verify ?? false,
18
+ verifyOnBuild: options.verifyOnBuild ?? true
19
+ };
20
+ }
21
+ /**
22
+ * Vite plugin that generates a single typed route module for Analog file routes.
23
+ */
24
+ function typedRoutes(options = {}) {
25
+ const resolvedOptions = resolvePluginOptions(options);
26
+ const workspaceRoot = normalizePath(resolvedOptions.workspaceRoot);
27
+ let root = "";
28
+ let command = "serve";
29
+ let discovery;
30
+ function isFreshnessCheck() {
31
+ return resolvedOptions.verify || command === "build" && resolvedOptions.verifyOnBuild;
32
+ }
33
+ function resolveDiscoveredFile(filename) {
34
+ const fromRoot = join(root, filename);
35
+ if (existsSync(fromRoot)) return fromRoot;
36
+ return join(workspaceRoot, filename);
37
+ }
38
+ function detectSchemas(relativeFilename) {
39
+ if (!relativeFilename.endsWith(".ts")) return {
40
+ hasParamsSchema: false,
41
+ hasQuerySchema: false
42
+ };
43
+ try {
44
+ return detectSchemaExports(readFileSync(resolveDiscoveredFile(relativeFilename), "utf-8"));
45
+ } catch {
46
+ return {
47
+ hasParamsSchema: false,
48
+ hasQuerySchema: false
49
+ };
50
+ }
51
+ }
52
+ /**
53
+ * Ensures the generated route file is imported from an app entry file
54
+ * so the module augmentation is always part of the TypeScript program.
55
+ */
56
+ function ensureEntryImport() {
57
+ const entryFiles = ["src/main.ts", "src/main.server.ts"];
58
+ function importSpecifierFor(entryFile) {
59
+ const rel = relative(dirname(entryFile), resolvedOptions.outFile).replace(/\.ts$/, "").replace(/\\/g, "/");
60
+ return rel.startsWith(".") ? rel : "./" + rel;
61
+ }
62
+ for (const entryFile of entryFiles) {
63
+ const entryPath = join(root, entryFile);
64
+ if (!existsSync(entryPath)) continue;
65
+ const content = readFileSync(entryPath, "utf-8");
66
+ const specifier = importSpecifierFor(entryFile);
67
+ const escaped = specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
68
+ if (new RegExp(`import\\s+['"]${escaped}(\\.ts|\\.js)?['"]`).test(content)) return;
69
+ if (isFreshnessCheck()) return;
70
+ const importLine = `import '${specifier}';`;
71
+ const lines = content.split("\n");
72
+ let lastImportLine = -1;
73
+ for (let i = 0; i < lines.length; i++) if (/^import\s/.test(lines[i])) lastImportLine = i;
74
+ if (lastImportLine >= 0) lines.splice(lastImportLine + 1, 0, importLine);
75
+ else lines.unshift(importLine);
76
+ writeFileSync(entryPath, lines.join("\n"), "utf-8");
77
+ console.log(`[analog] Added route tree import to ${entryFile}`);
78
+ return;
79
+ }
80
+ const specifier = importSpecifierFor("src/main.ts");
81
+ if (isFreshnessCheck()) return;
82
+ console.warn(`[analog] Could not find an entry file (src/main.ts or src/main.server.ts) to add the route tree import. Add \`import '${specifier}';\` to your app entry file to ensure typed routing is active.`);
83
+ }
84
+ function generate() {
85
+ const routeFiles = discovery.getRouteFiles();
86
+ const contentFiles = discovery.getContentFiles();
87
+ debugTypedRouter("discovered files", {
88
+ routeFiles: routeFiles.length,
89
+ contentFiles: contentFiles.length
90
+ });
91
+ const manifest = generateRouteManifest([...routeFiles, ...contentFiles], detectSchemas, (filename) => discovery.isAppLocal(filename) ? 0 : 1);
92
+ const declaration = generateRouteTableDeclaration(manifest);
93
+ const canonicalFiles = new Set(manifest.routes.map((route) => route.filename));
94
+ const jsonLdEntries = buildJsonLdEntries(resolveDiscoveredFile, routeFiles.filter((filename) => canonicalFiles.has(filename)), contentFiles.filter((filename) => canonicalFiles.has(filename)));
95
+ const output = combineGeneratedModules(declaration, generateRouteTreeDeclaration(manifest, { jsonLdFiles: jsonLdEntries.map((entry) => entry.sourceFile) }), resolvedOptions.jsonLdManifest && jsonLdEntries.length > 0 ? generateJsonLdManifestSource(jsonLdEntries, resolvedOptions.outFile) : "");
96
+ const hardCollisions = manifest.collisions.filter((c) => c.samePriority);
97
+ if (manifest.collisions.length > 0) debugTypedRouter("route collisions", {
98
+ total: manifest.collisions.length,
99
+ hard: hardCollisions.length,
100
+ collisions: manifest.collisions.map((c) => ({
101
+ path: c.fullPath,
102
+ kept: c.keptFile,
103
+ dropped: c.droppedFile
104
+ }))
105
+ });
106
+ if (hardCollisions.length > 0 && command === "build") {
107
+ const details = hardCollisions.map((c) => ` '${c.fullPath}': '${c.keptFile}' vs '${c.droppedFile}'`).join("\n");
108
+ throw new Error(`[analog] Route collisions detected during build:\n${details}\n\nEach route path must be defined by exactly one source file. Remove or rename the conflicting files to resolve the collision.`);
109
+ }
110
+ if (manifest.routes.length > 0) console.log(formatManifestSummary(manifest));
111
+ const outPath = join(root, resolvedOptions.outFile);
112
+ const outDir = dirname(outPath);
113
+ const hadExistingOutput = existsSync(outPath);
114
+ if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });
115
+ let existing = "";
116
+ try {
117
+ existing = readFileSync(outPath, "utf-8");
118
+ } catch {}
119
+ if (output.includes(root)) console.warn(`[analog] Generated route output contains an absolute path prefix (${root}). Route keys and sourceFile values should be workspace-relative.`);
120
+ const normalizeEndings = (s) => s.replace(/\r\n/g, "\n");
121
+ if (normalizeEndings(existing) !== normalizeEndings(output)) {
122
+ debugTypedRouter("route file changed", {
123
+ outFile: resolvedOptions.outFile,
124
+ routes: manifest.routes.length,
125
+ verify: resolvedOptions.verify,
126
+ verifyOnBuild: resolvedOptions.verifyOnBuild,
127
+ command
128
+ });
129
+ if (resolvedOptions.verify) throw new Error(`[analog] Stale route file detected: ${resolvedOptions.outFile}\nThe checked-in generated route file does not match the current route sources.\nRegenerate route files and commit the updated output.`);
130
+ writeFileSync(outPath, output, "utf-8");
131
+ if (command === "build" && resolvedOptions.verifyOnBuild && hadExistingOutput) throw new Error(`[analog] Stale route file detected during build: ${resolvedOptions.outFile}\nThe generated route file was updated to match the current route sources.\nReview the updated output, commit it if it is checked in, and rerun the build.`);
132
+ }
133
+ }
134
+ return {
135
+ name: "analog-typed-routes",
136
+ config(config, env) {
137
+ command = env.command;
138
+ root = normalizePath(resolve(workspaceRoot, config.root || ".") || ".");
139
+ discovery = createRouteFileDiscovery({
140
+ root,
141
+ workspaceRoot,
142
+ additionalPagesDirs: resolvedOptions.additionalPagesDirs,
143
+ additionalContentDirs: resolvedOptions.additionalContentDirs
144
+ });
145
+ },
146
+ buildStart() {
147
+ generate();
148
+ if (!isFreshnessCheck()) ensureEntryImport();
149
+ },
150
+ configureServer(server) {
151
+ const regenerate = (path, event) => {
152
+ if (!discovery.getDiscoveredFileKind(path)) return;
153
+ debugTypedRouter("watch regenerate", {
154
+ event,
155
+ path
156
+ });
157
+ discovery.updateDiscoveredFile(path, event);
158
+ generate();
159
+ };
160
+ server.watcher.on("add", (path) => regenerate(path, "add"));
161
+ server.watcher.on("change", (path) => regenerate(path, "change"));
162
+ server.watcher.on("unlink", (path) => regenerate(path, "unlink"));
163
+ }
164
+ };
165
+ }
166
+ function buildJsonLdEntries(resolveFile, routeFiles, contentFiles) {
167
+ const entries = [];
168
+ let importIndex = 0;
169
+ routeFiles.forEach((filename) => {
170
+ try {
171
+ if (!detectJsonLdModuleExports(readFileSync(resolveFile(filename), "utf-8"))) return;
172
+ entries.push({
173
+ kind: "module",
174
+ routePath: filenameToRoutePath(filename),
175
+ sourceFile: filename,
176
+ importAlias: `routeModule${importIndex++}`
177
+ });
178
+ } catch {}
179
+ });
180
+ contentFiles.forEach((filename) => {
181
+ try {
182
+ const jsonLd = extractMarkdownJsonLd(readFileSync(resolveFile(filename), "utf-8"));
183
+ if (jsonLd.length === 0) return;
184
+ entries.push({
185
+ kind: "content",
186
+ routePath: filenameToRoutePath(filename),
187
+ sourceFile: filename,
188
+ jsonLd
189
+ });
190
+ } catch {}
191
+ });
192
+ return entries.sort((a, b) => a.routePath.localeCompare(b.routePath));
193
+ }
194
+ function combineGeneratedModules(...sources) {
195
+ const imports = [];
196
+ const seenImports = /* @__PURE__ */ new Set();
197
+ const bodies = [];
198
+ for (const source of sources) {
199
+ const { body, importLines } = splitGeneratedModule(source);
200
+ for (const importLine of importLines) if (!seenImports.has(importLine)) {
201
+ seenImports.add(importLine);
202
+ imports.push(importLine);
203
+ }
204
+ if (body.trim()) bodies.push(body.trim());
205
+ }
206
+ return [
207
+ "// This file is auto-generated by @analogjs/platform",
208
+ "// Do not edit manually",
209
+ "",
210
+ ...imports.length > 0 ? [...imports, ""] : [],
211
+ bodies.join("\n\n"),
212
+ ""
213
+ ].join("\n");
214
+ }
215
+ function splitGeneratedModule(source) {
216
+ const lines = source.split("\n");
217
+ let index = 0;
218
+ while (index < lines.length && lines[index].startsWith("//")) index++;
219
+ while (index < lines.length && lines[index] === "") index++;
220
+ const importLines = [];
221
+ while (index < lines.length && lines[index].startsWith("import ")) {
222
+ importLines.push(lines[index]);
223
+ index++;
224
+ }
225
+ while (index < lines.length && lines[index] === "") index++;
226
+ return {
227
+ importLines,
228
+ body: lines.slice(index).join("\n")
229
+ };
230
+ }
231
+ //#endregion
232
+ export { typedRoutes };
233
+
234
+ //# sourceMappingURL=typed-routes-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typed-routes-plugin.js","names":[],"sources":["../../../src/lib/typed-routes-plugin.ts"],"sourcesContent":["import { normalizePath, type Plugin } from 'vite';\nimport { resolve, join, dirname, relative } from 'node:path';\nimport { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\n\nimport {\n generateRouteManifest,\n generateRouteTableDeclaration,\n generateRouteTreeDeclaration,\n detectSchemaExports,\n formatManifestSummary,\n filenameToRoutePath,\n} from './route-manifest.js';\nimport type { RouteSchemaInfo } from './route-manifest.js';\nimport {\n detectJsonLdModuleExports,\n extractMarkdownJsonLd,\n generateJsonLdManifestSource,\n type JsonLdManifestEntry,\n} from './json-ld-manifest-plugin.js';\nimport {\n createRouteFileDiscovery,\n type RouteFileDiscovery,\n} from './route-file-discovery.js';\nimport { debugTypedRouter } from './utils/debug.js';\n\nconst DEFAULT_OUT_FILE = 'src/routeTree.gen.ts';\n\nexport interface TypedRoutesPluginOptions {\n /**\n * Output path for the single generated route module,\n * relative to the app root.\n *\n * @default 'src/routeTree.gen.ts'\n */\n outFile?: string;\n /**\n * Workspace root used to resolve additional route/content directories.\n *\n * @default process.env['NX_WORKSPACE_ROOT'] ?? process.cwd()\n */\n workspaceRoot?: string;\n /**\n * Additional page directories to scan for `.page.ts` files.\n */\n additionalPagesDirs?: string[];\n /**\n * Additional content directories to scan for `.md` files.\n */\n additionalContentDirs?: string[];\n /**\n * Include generated `routeJsonLdManifest` exports in the generated route file.\n *\n * @default true\n */\n jsonLdManifest?: boolean;\n /**\n * When true, compare generated output against the existing file and\n * throw an error if they differ instead of writing. Useful for CI to\n * detect stale checked-in route files.\n *\n * @default false\n */\n verify?: boolean;\n /**\n * When true, production builds fail after regenerating a stale checked-in\n * route file. This preserves self-healing writes in development while making\n * build-time freshness issues visible by default.\n *\n * @default true\n */\n verifyOnBuild?: boolean;\n}\n\nfunction resolvePluginOptions(\n options: TypedRoutesPluginOptions = {},\n): Required<TypedRoutesPluginOptions> {\n return {\n outFile: options.outFile ?? DEFAULT_OUT_FILE,\n workspaceRoot:\n options.workspaceRoot ??\n process.env['NX_WORKSPACE_ROOT'] ??\n process.cwd(),\n additionalPagesDirs: options.additionalPagesDirs ?? [],\n additionalContentDirs: options.additionalContentDirs ?? [],\n jsonLdManifest: options.jsonLdManifest ?? true,\n verify: options.verify ?? false,\n verifyOnBuild: options.verifyOnBuild ?? true,\n };\n}\n\n/**\n * Vite plugin that generates a single typed route module for Analog file routes.\n */\nexport function typedRoutes(options: TypedRoutesPluginOptions = {}): Plugin {\n const resolvedOptions = resolvePluginOptions(options);\n const workspaceRoot = normalizePath(resolvedOptions.workspaceRoot);\n let root = '';\n let command: 'build' | 'serve' = 'serve';\n let discovery: RouteFileDiscovery;\n\n function isFreshnessCheck(): boolean {\n return (\n resolvedOptions.verify ||\n (command === 'build' && resolvedOptions.verifyOnBuild)\n );\n }\n\n function resolveDiscoveredFile(filename: string): string {\n const fromRoot = join(root, filename);\n if (existsSync(fromRoot)) return fromRoot;\n return join(workspaceRoot, filename);\n }\n\n function detectSchemas(relativeFilename: string): RouteSchemaInfo {\n if (!relativeFilename.endsWith('.ts')) {\n return { hasParamsSchema: false, hasQuerySchema: false };\n }\n\n try {\n const absPath = resolveDiscoveredFile(relativeFilename);\n const content = readFileSync(absPath, 'utf-8');\n return detectSchemaExports(content);\n } catch {\n return { hasParamsSchema: false, hasQuerySchema: false };\n }\n }\n\n /**\n * Ensures the generated route file is imported from an app entry file\n * so the module augmentation is always part of the TypeScript program.\n */\n function ensureEntryImport(): void {\n const entryFiles = ['src/main.ts', 'src/main.server.ts'];\n\n // Compute the import specifier relative to the entry file\n function importSpecifierFor(entryFile: string): string {\n const rel = relative(dirname(entryFile), resolvedOptions.outFile)\n .replace(/\\.ts$/, '')\n .replace(/\\\\/g, '/');\n return rel.startsWith('.') ? rel : './' + rel;\n }\n\n for (const entryFile of entryFiles) {\n const entryPath = join(root, entryFile);\n if (!existsSync(entryPath)) continue;\n\n const content = readFileSync(entryPath, 'utf-8');\n const specifier = importSpecifierFor(entryFile);\n\n // Check if any variation of the import already exists\n const escaped = specifier.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`import\\\\s+['\"]${escaped}(\\\\.ts|\\\\.js)?['\"]`);\n if (pattern.test(content)) {\n return;\n }\n\n if (isFreshnessCheck()) {\n return;\n }\n\n // Insert the import after the last existing import line\n const importLine = `import '${specifier}';`;\n const lines = content.split('\\n');\n let lastImportLine = -1;\n\n for (let i = 0; i < lines.length; i++) {\n if (/^import\\s/.test(lines[i])) {\n lastImportLine = i;\n }\n }\n\n if (lastImportLine >= 0) {\n lines.splice(lastImportLine + 1, 0, importLine);\n } else {\n lines.unshift(importLine);\n }\n\n writeFileSync(entryPath, lines.join('\\n'), 'utf-8');\n console.log(`[analog] Added route tree import to ${entryFile}`);\n return;\n }\n\n // No suitable entry file found\n const specifier = importSpecifierFor('src/main.ts');\n if (isFreshnessCheck()) {\n return;\n }\n console.warn(\n `[analog] Could not find an entry file (src/main.ts or src/main.server.ts) ` +\n `to add the route tree import. Add \\`import '${specifier}';\\` ` +\n `to your app entry file to ensure typed routing is active.`,\n );\n }\n\n function generate(): void {\n const routeFiles = discovery.getRouteFiles();\n const contentFiles = discovery.getContentFiles();\n debugTypedRouter('discovered files', {\n routeFiles: routeFiles.length,\n contentFiles: contentFiles.length,\n });\n const allFiles = [...routeFiles, ...contentFiles];\n const manifest = generateRouteManifest(\n allFiles,\n detectSchemas,\n (filename) => (discovery.isAppLocal(filename) ? 0 : 1),\n );\n const declaration = generateRouteTableDeclaration(manifest);\n const canonicalFiles = new Set(\n manifest.routes.map((route) => route.filename),\n );\n const jsonLdEntries = buildJsonLdEntries(\n resolveDiscoveredFile,\n routeFiles.filter((filename) => canonicalFiles.has(filename)),\n contentFiles.filter((filename) => canonicalFiles.has(filename)),\n );\n const routeTree = generateRouteTreeDeclaration(manifest, {\n jsonLdFiles: jsonLdEntries.map((entry) => entry.sourceFile),\n });\n const output = combineGeneratedModules(\n declaration,\n routeTree,\n resolvedOptions.jsonLdManifest && jsonLdEntries.length > 0\n ? generateJsonLdManifestSource(jsonLdEntries, resolvedOptions.outFile)\n : '',\n );\n\n const hardCollisions = manifest.collisions.filter((c) => c.samePriority);\n if (manifest.collisions.length > 0) {\n debugTypedRouter('route collisions', {\n total: manifest.collisions.length,\n hard: hardCollisions.length,\n collisions: manifest.collisions.map((c) => ({\n path: c.fullPath,\n kept: c.keptFile,\n dropped: c.droppedFile,\n })),\n });\n }\n if (hardCollisions.length > 0 && command === 'build') {\n const details = hardCollisions\n .map((c) => ` '${c.fullPath}': '${c.keptFile}' vs '${c.droppedFile}'`)\n .join('\\n');\n throw new Error(\n `[analog] Route collisions detected during build:\\n${details}\\n\\n` +\n `Each route path must be defined by exactly one source file. ` +\n `Remove or rename the conflicting files to resolve the collision.`,\n );\n }\n\n if (manifest.routes.length > 0) {\n console.log(formatManifestSummary(manifest));\n }\n\n const outPath = join(root, resolvedOptions.outFile);\n const outDir = dirname(outPath);\n const hadExistingOutput = existsSync(outPath);\n\n if (!existsSync(outDir)) {\n mkdirSync(outDir, { recursive: true });\n }\n\n let existing = '';\n\n try {\n existing = readFileSync(outPath, 'utf-8');\n } catch {\n // file does not exist yet\n }\n\n // Build-time guard: detect absolute path leaks in generated output.\n // Machine-specific prefixes must never appear in route keys or sourceFile values.\n if (output.includes(root)) {\n console.warn(\n `[analog] Generated route output contains an absolute path prefix (${root}). ` +\n `Route keys and sourceFile values should be workspace-relative.`,\n );\n }\n\n // Normalize line endings before comparison so that files checked in\n // with LF don't appear stale on Windows where readFileSync may return CRLF.\n const normalizeEndings = (s: string) => s.replace(/\\r\\n/g, '\\n');\n if (normalizeEndings(existing) !== normalizeEndings(output)) {\n debugTypedRouter('route file changed', {\n outFile: resolvedOptions.outFile,\n routes: manifest.routes.length,\n verify: resolvedOptions.verify,\n verifyOnBuild: resolvedOptions.verifyOnBuild,\n command,\n });\n if (resolvedOptions.verify) {\n throw new Error(\n `[analog] Stale route file detected: ${resolvedOptions.outFile}\\n` +\n `The checked-in generated route file does not match the current route sources.\\n` +\n `Regenerate route files and commit the updated output.`,\n );\n }\n\n writeFileSync(outPath, output, 'utf-8');\n\n if (\n command === 'build' &&\n resolvedOptions.verifyOnBuild &&\n hadExistingOutput\n ) {\n throw new Error(\n `[analog] Stale route file detected during build: ${resolvedOptions.outFile}\\n` +\n `The generated route file was updated to match the current route sources.\\n` +\n `Review the updated output, commit it if it is checked in, and rerun the build.`,\n );\n }\n }\n }\n\n return {\n name: 'analog-typed-routes',\n config(config, env) {\n command = env.command;\n root = normalizePath(resolve(workspaceRoot, config.root || '.') || '.');\n discovery = createRouteFileDiscovery({\n root,\n workspaceRoot,\n additionalPagesDirs: resolvedOptions.additionalPagesDirs,\n additionalContentDirs: resolvedOptions.additionalContentDirs,\n });\n },\n buildStart() {\n generate();\n if (!isFreshnessCheck()) {\n ensureEntryImport();\n }\n },\n configureServer(server) {\n const regenerate = (path: string, event: 'add' | 'change' | 'unlink') => {\n // Reuse the discovery matcher so watch-time updates stay in sync with\n // the initial scan and don't pull Nitro server routes into routeTree.gen.ts.\n if (!discovery.getDiscoveredFileKind(path)) {\n return;\n }\n\n debugTypedRouter('watch regenerate', { event, path });\n discovery.updateDiscoveredFile(path, event);\n generate();\n };\n\n server.watcher.on('add', (path) => regenerate(path, 'add'));\n server.watcher.on('change', (path) => regenerate(path, 'change'));\n server.watcher.on('unlink', (path) => regenerate(path, 'unlink'));\n },\n };\n}\n\nfunction buildJsonLdEntries(\n resolveFile: (filename: string) => string,\n routeFiles: string[],\n contentFiles: string[],\n): JsonLdManifestEntry[] {\n const entries: JsonLdManifestEntry[] = [];\n let importIndex = 0;\n\n routeFiles.forEach((filename) => {\n try {\n const source = readFileSync(resolveFile(filename), 'utf-8');\n if (!detectJsonLdModuleExports(source)) {\n return;\n }\n\n entries.push({\n kind: 'module',\n routePath: filenameToRoutePath(filename),\n sourceFile: filename,\n importAlias: `routeModule${importIndex++}`,\n });\n } catch {\n // ignore unreadable route file\n }\n });\n\n contentFiles.forEach((filename) => {\n try {\n const source = readFileSync(resolveFile(filename), 'utf-8');\n const jsonLd = extractMarkdownJsonLd(source);\n\n if (jsonLd.length === 0) {\n return;\n }\n\n entries.push({\n kind: 'content',\n routePath: filenameToRoutePath(filename),\n sourceFile: filename,\n jsonLd,\n });\n } catch {\n // ignore unreadable content file\n }\n });\n\n return entries.sort((a, b) => a.routePath.localeCompare(b.routePath));\n}\n\nfunction combineGeneratedModules(...sources: string[]): string {\n const imports: string[] = [];\n const seenImports = new Set<string>();\n const bodies: string[] = [];\n\n for (const source of sources) {\n const { body, importLines } = splitGeneratedModule(source);\n for (const importLine of importLines) {\n if (!seenImports.has(importLine)) {\n seenImports.add(importLine);\n imports.push(importLine);\n }\n }\n if (body.trim()) {\n bodies.push(body.trim());\n }\n }\n\n return [\n '// This file is auto-generated by @analogjs/platform',\n '// Do not edit manually',\n '',\n ...(imports.length > 0 ? [...imports, ''] : []),\n bodies.join('\\n\\n'),\n '',\n ].join('\\n');\n}\n\nfunction splitGeneratedModule(source: string): {\n importLines: string[];\n body: string;\n} {\n const lines = source.split('\\n');\n let index = 0;\n\n while (index < lines.length && lines[index].startsWith('//')) {\n index++;\n }\n\n while (index < lines.length && lines[index] === '') {\n index++;\n }\n\n const importLines: string[] = [];\n while (index < lines.length && lines[index].startsWith('import ')) {\n importLines.push(lines[index]);\n index++;\n }\n\n while (index < lines.length && lines[index] === '') {\n index++;\n }\n\n return {\n importLines,\n body: lines.slice(index).join('\\n'),\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { Debugger } from "obug";
2
+ export type DebugMode = "build" | "dev";
3
+ export interface DebugModeOptions<S extends string = string> {
4
+ scopes?: boolean | S[];
5
+ mode?: DebugMode;
6
+ /**
7
+ * Write debug output to log files under `tmp/debug/` in the workspace root.
8
+ * - `true` or `'single'` — all output to `tmp/debug/analog.log`
9
+ * - `'scoped'` — one file per scope, e.g. `tmp/debug/analog.angular.hmr.log`
10
+ */
11
+ logFile?: boolean | "single" | "scoped";
12
+ }
13
+ export type DebugOption<S extends string = string> = boolean | S[] | DebugModeOptions<S> | DebugModeOptions<S>[];
14
+ export interface DebugHarness<S extends string = string> {
15
+ applyDebugOption(debug: DebugOption<S> | undefined, workspaceRoot?: string): void;
16
+ activateDeferredDebug(command: "build" | "serve"): void;
17
+ /** @internal test-only reset */
18
+ _resetDeferredDebug(): void;
19
+ }
20
+ export declare function createDebugHarness<S extends string = string>(config: {
21
+ fallbackNamespace: string;
22
+ instanceGroups: Debugger[][];
23
+ }): DebugHarness<S>;
@@ -0,0 +1,88 @@
1
+ import { DEBUG_LOG_DIR, DEBUG_LOG_FILENAME, wrapInstancesForFileLog, wrapInstancesForScopedFileLog } from "./debug-log-file.js";
2
+ import { join } from "node:path";
3
+ import { enable } from "obug";
4
+ //#region packages/platform/src/lib/utils/debug-harness.ts
5
+ /**
6
+ * Duplicates of this file (keep in sync):
7
+ * packages/platform/src/lib/utils/debug-harness.ts
8
+ * packages/vite-plugin-angular/src/lib/utils/debug-harness.ts
9
+ */
10
+ function resolveNamespaces(scopes, fallback) {
11
+ if (scopes === true || scopes === void 0) return fallback;
12
+ if (Array.isArray(scopes) && scopes.length) return scopes.join(",");
13
+ return null;
14
+ }
15
+ function extractLogFile(debug) {
16
+ if (typeof debug === "boolean") return false;
17
+ if (Array.isArray(debug)) {
18
+ if (debug.length === 0 || typeof debug[0] === "string") return false;
19
+ return debug.find((e) => !!e.logFile)?.logFile ?? false;
20
+ }
21
+ return debug.logFile ?? false;
22
+ }
23
+ function createDebugHarness(config) {
24
+ let pendingDebug = [];
25
+ function installFileWrappers(logFile, root) {
26
+ if (logFile === "scoped") {
27
+ const dirPath = join(root, DEBUG_LOG_DIR);
28
+ for (const group of config.instanceGroups) wrapInstancesForScopedFileLog(group, dirPath);
29
+ } else {
30
+ const filePath = join(root, DEBUG_LOG_DIR, DEBUG_LOG_FILENAME);
31
+ for (const group of config.instanceGroups) wrapInstancesForFileLog(group, filePath);
32
+ }
33
+ }
34
+ function applyEntry(entry, fallback, logFile, root) {
35
+ if (!entry.mode) {
36
+ const ns = resolveNamespaces(entry.scopes ?? true, fallback);
37
+ if (ns) enable(ns);
38
+ if (logFile) installFileWrappers(logFile, root);
39
+ } else pendingDebug.push({
40
+ entry,
41
+ logFile,
42
+ root
43
+ });
44
+ }
45
+ return {
46
+ applyDebugOption(debug, workspaceRoot) {
47
+ if (debug == null || debug === false) return;
48
+ const logFile = extractLogFile(debug);
49
+ const root = workspaceRoot ?? process.env["NX_WORKSPACE_ROOT"] ?? process.cwd();
50
+ if (typeof debug === "boolean") {
51
+ const ns = resolveNamespaces(debug, config.fallbackNamespace);
52
+ if (ns) enable(ns);
53
+ return;
54
+ }
55
+ if (Array.isArray(debug)) {
56
+ if (debug.length === 0) return;
57
+ if (typeof debug[0] === "string") {
58
+ const ns = debug.join(",");
59
+ if (ns) enable(ns);
60
+ return;
61
+ }
62
+ for (const entry of debug) {
63
+ const entryLogFile = entry.logFile ?? false;
64
+ applyEntry(entry, config.fallbackNamespace, entryLogFile || logFile, root);
65
+ }
66
+ return;
67
+ }
68
+ applyEntry(debug, config.fallbackNamespace, logFile, root);
69
+ },
70
+ activateDeferredDebug(command) {
71
+ if (pendingDebug.length === 0) return;
72
+ const currentMode = command === "serve" ? "dev" : "build";
73
+ for (const { entry, logFile, root } of pendingDebug) if (entry.mode === currentMode) {
74
+ const ns = resolveNamespaces(entry.scopes ?? true, config.fallbackNamespace);
75
+ if (ns) enable(ns);
76
+ if (logFile) installFileWrappers(logFile, root);
77
+ }
78
+ pendingDebug = [];
79
+ },
80
+ _resetDeferredDebug() {
81
+ pendingDebug = [];
82
+ }
83
+ };
84
+ }
85
+ //#endregion
86
+ export { createDebugHarness };
87
+
88
+ //# sourceMappingURL=debug-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-harness.js","names":[],"sources":["../../../../src/lib/utils/debug-harness.ts"],"sourcesContent":["/**\n * Duplicates of this file (keep in sync):\n * packages/platform/src/lib/utils/debug-harness.ts\n * packages/vite-plugin-angular/src/lib/utils/debug-harness.ts\n */\nimport { join } from 'node:path';\nimport { enable } from 'obug';\nimport type { Debugger } from 'obug';\n\nimport {\n DEBUG_LOG_DIR,\n DEBUG_LOG_FILENAME,\n wrapInstancesForFileLog,\n wrapInstancesForScopedFileLog,\n} from './debug-log-file.js';\n\nexport type DebugMode = 'build' | 'dev';\n\nexport interface DebugModeOptions<S extends string = string> {\n scopes?: boolean | S[];\n mode?: DebugMode;\n /**\n * Write debug output to log files under `tmp/debug/` in the workspace root.\n * - `true` or `'single'` — all output to `tmp/debug/analog.log`\n * - `'scoped'` — one file per scope, e.g. `tmp/debug/analog.angular.hmr.log`\n */\n logFile?: boolean | 'single' | 'scoped';\n}\n\nexport type DebugOption<S extends string = string> =\n | boolean\n | S[]\n | DebugModeOptions<S>\n | DebugModeOptions<S>[];\n\nexport interface DebugHarness<S extends string = string> {\n applyDebugOption(\n debug: DebugOption<S> | undefined,\n workspaceRoot?: string,\n ): void;\n activateDeferredDebug(command: 'build' | 'serve'): void;\n /** @internal test-only reset */\n _resetDeferredDebug(): void;\n}\n\nfunction resolveNamespaces(\n scopes: boolean | string[] | undefined,\n fallback: string,\n): string | null {\n if (scopes === true || scopes === undefined) return fallback;\n if (Array.isArray(scopes) && scopes.length) return scopes.join(',');\n return null;\n}\n\nfunction extractLogFile(\n debug: DebugOption,\n): true | 'single' | 'scoped' | false {\n if (typeof debug === 'boolean') return false;\n if (Array.isArray(debug)) {\n if (debug.length === 0 || typeof debug[0] === 'string') return false;\n const entry = (debug as DebugModeOptions[]).find((e) => !!e.logFile);\n return entry?.logFile ?? false;\n }\n return (debug as DebugModeOptions).logFile ?? false;\n}\n\nexport function createDebugHarness<S extends string = string>(config: {\n fallbackNamespace: string;\n instanceGroups: Debugger[][];\n}): DebugHarness<S> {\n interface PendingEntry {\n entry: DebugModeOptions<S>;\n logFile: true | 'single' | 'scoped' | false;\n root: string;\n }\n\n let pendingDebug: PendingEntry[] = [];\n\n function installFileWrappers(\n logFile: true | 'single' | 'scoped',\n root: string,\n ): void {\n if (logFile === 'scoped') {\n const dirPath = join(root, DEBUG_LOG_DIR);\n for (const group of config.instanceGroups) {\n wrapInstancesForScopedFileLog(group, dirPath);\n }\n } else {\n const filePath = join(root, DEBUG_LOG_DIR, DEBUG_LOG_FILENAME);\n for (const group of config.instanceGroups) {\n wrapInstancesForFileLog(group, filePath);\n }\n }\n }\n\n function applyEntry(\n entry: DebugModeOptions<S>,\n fallback: string,\n logFile: true | 'single' | 'scoped' | false,\n root: string,\n ): void {\n if (!entry.mode) {\n const ns = resolveNamespaces(entry.scopes ?? true, fallback);\n if (ns) enable(ns);\n if (logFile) installFileWrappers(logFile, root);\n } else {\n pendingDebug.push({ entry, logFile, root });\n }\n }\n\n return {\n applyDebugOption(\n debug: DebugOption<S> | undefined,\n workspaceRoot?: string,\n ): void {\n if (debug == null || debug === false) return;\n\n const logFile = extractLogFile(debug);\n const root =\n workspaceRoot ?? process.env['NX_WORKSPACE_ROOT'] ?? process.cwd();\n\n if (typeof debug === 'boolean') {\n const ns = resolveNamespaces(debug, config.fallbackNamespace);\n if (ns) enable(ns);\n return;\n }\n\n if (Array.isArray(debug)) {\n if (debug.length === 0) return;\n\n if (typeof debug[0] === 'string') {\n const ns = (debug as string[]).join(',');\n if (ns) enable(ns);\n return;\n }\n\n for (const entry of debug as DebugModeOptions<S>[]) {\n const entryLogFile = entry.logFile ?? false;\n applyEntry(\n entry,\n config.fallbackNamespace,\n entryLogFile || logFile,\n root,\n );\n }\n return;\n }\n\n applyEntry(debug, config.fallbackNamespace, logFile, root);\n },\n\n activateDeferredDebug(command: 'build' | 'serve'): void {\n if (pendingDebug.length === 0) return;\n\n const currentMode = command === 'serve' ? 'dev' : 'build';\n\n for (const { entry, logFile, root } of pendingDebug) {\n if (entry.mode === currentMode) {\n const ns = resolveNamespaces(\n entry.scopes ?? true,\n config.fallbackNamespace,\n );\n if (ns) enable(ns);\n if (logFile) installFileWrappers(logFile, root);\n }\n }\n\n pendingDebug = [];\n },\n\n _resetDeferredDebug(): void {\n pendingDebug = [];\n },\n };\n}\n"],"mappings":";;;;;;;;;AA6CA,SAAS,kBACP,QACA,UACe;AACf,KAAI,WAAW,QAAQ,WAAW,KAAA,EAAW,QAAO;AACpD,KAAI,MAAM,QAAQ,OAAO,IAAI,OAAO,OAAQ,QAAO,OAAO,KAAK,IAAI;AACnE,QAAO;;AAGT,SAAS,eACP,OACoC;AACpC,KAAI,OAAO,UAAU,UAAW,QAAO;AACvC,KAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,MAAI,MAAM,WAAW,KAAK,OAAO,MAAM,OAAO,SAAU,QAAO;AAE/D,SADe,MAA6B,MAAM,MAAM,CAAC,CAAC,EAAE,QAAQ,EACtD,WAAW;;AAE3B,QAAQ,MAA2B,WAAW;;AAGhD,SAAgB,mBAA8C,QAG1C;CAOlB,IAAI,eAA+B,EAAE;CAErC,SAAS,oBACP,SACA,MACM;AACN,MAAI,YAAY,UAAU;GACxB,MAAM,UAAU,KAAK,MAAM,cAAc;AACzC,QAAK,MAAM,SAAS,OAAO,eACzB,+BAA8B,OAAO,QAAQ;SAE1C;GACL,MAAM,WAAW,KAAK,MAAM,eAAe,mBAAmB;AAC9D,QAAK,MAAM,SAAS,OAAO,eACzB,yBAAwB,OAAO,SAAS;;;CAK9C,SAAS,WACP,OACA,UACA,SACA,MACM;AACN,MAAI,CAAC,MAAM,MAAM;GACf,MAAM,KAAK,kBAAkB,MAAM,UAAU,MAAM,SAAS;AAC5D,OAAI,GAAI,QAAO,GAAG;AAClB,OAAI,QAAS,qBAAoB,SAAS,KAAK;QAE/C,cAAa,KAAK;GAAE;GAAO;GAAS;GAAM,CAAC;;AAI/C,QAAO;EACL,iBACE,OACA,eACM;AACN,OAAI,SAAS,QAAQ,UAAU,MAAO;GAEtC,MAAM,UAAU,eAAe,MAAM;GACrC,MAAM,OACJ,iBAAiB,QAAQ,IAAI,wBAAwB,QAAQ,KAAK;AAEpE,OAAI,OAAO,UAAU,WAAW;IAC9B,MAAM,KAAK,kBAAkB,OAAO,OAAO,kBAAkB;AAC7D,QAAI,GAAI,QAAO,GAAG;AAClB;;AAGF,OAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,QAAI,MAAM,WAAW,EAAG;AAExB,QAAI,OAAO,MAAM,OAAO,UAAU;KAChC,MAAM,KAAM,MAAmB,KAAK,IAAI;AACxC,SAAI,GAAI,QAAO,GAAG;AAClB;;AAGF,SAAK,MAAM,SAAS,OAAgC;KAClD,MAAM,eAAe,MAAM,WAAW;AACtC,gBACE,OACA,OAAO,mBACP,gBAAgB,SAChB,KACD;;AAEH;;AAGF,cAAW,OAAO,OAAO,mBAAmB,SAAS,KAAK;;EAG5D,sBAAsB,SAAkC;AACtD,OAAI,aAAa,WAAW,EAAG;GAE/B,MAAM,cAAc,YAAY,UAAU,QAAQ;AAElD,QAAK,MAAM,EAAE,OAAO,SAAS,UAAU,aACrC,KAAI,MAAM,SAAS,aAAa;IAC9B,MAAM,KAAK,kBACT,MAAM,UAAU,MAChB,OAAO,kBACR;AACD,QAAI,GAAI,QAAO,GAAG;AAClB,QAAI,QAAS,qBAAoB,SAAS,KAAK;;AAInD,kBAAe,EAAE;;EAGnB,sBAA4B;AAC1B,kBAAe,EAAE;;EAEpB"}
@@ -0,0 +1,5 @@
1
+ import type { Debugger } from "obug";
2
+ export declare const DEBUG_LOG_DIR = "tmp/debug";
3
+ export declare const DEBUG_LOG_FILENAME = "analog.log";
4
+ export declare function wrapInstancesForFileLog(instances: Debugger[], filePath: string): void;
5
+ export declare function wrapInstancesForScopedFileLog(instances: Debugger[], dirPath: string): void;