@analogjs/platform 3.0.0-alpha.9 → 3.0.0-alpha.90

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 (361) hide show
  1. package/migrations/migration.json +7 -1
  2. package/package.json +28 -14
  3. package/src/index.d.ts +5 -2
  4. package/src/index.js +3 -1
  5. package/src/index.js.map +1 -1
  6. package/src/lib/analog-integration-plugin.d.ts +9 -0
  7. package/src/lib/analog-integration-plugin.js +22 -0
  8. package/src/lib/analog-integration-plugin.js.map +1 -0
  9. package/src/lib/clear-client-page-endpoint.d.ts +2 -2
  10. package/src/lib/clear-client-page-endpoint.js +27 -5
  11. package/src/lib/clear-client-page-endpoint.js.map +1 -1
  12. package/src/lib/content/marked/index.d.ts +5 -5
  13. package/src/lib/content/marked/index.js.map +1 -1
  14. package/src/lib/content/marked/marked-content-highlighter.d.ts +2 -2
  15. package/src/lib/content/marked/marked-content-highlighter.js.map +1 -1
  16. package/src/lib/content/marked/marked-setup.service.d.ts +8 -8
  17. package/src/lib/content/marked/marked-setup.service.js +7 -5
  18. package/src/lib/content/marked/marked-setup.service.js.map +1 -1
  19. package/src/lib/content/prism/angular.js.map +1 -1
  20. package/src/lib/content/prism/index.d.ts +1 -1
  21. package/src/lib/content/prism/index.js.map +1 -1
  22. package/src/lib/content/prism/options.d.ts +1 -1
  23. package/src/lib/content/prism/prism-highlighter.d.ts +5 -5
  24. package/src/lib/content/prism/prism-highlighter.js.map +1 -1
  25. package/src/lib/content/shiki/index.d.ts +3 -3
  26. package/src/lib/content/shiki/index.js +9 -6
  27. package/src/lib/content/shiki/index.js.map +1 -1
  28. package/src/lib/content/shiki/options.d.ts +8 -7
  29. package/src/lib/content/shiki/shiki-highlighter.d.ts +14 -13
  30. package/src/lib/content/shiki/shiki-highlighter.js +7 -4
  31. package/src/lib/content/shiki/shiki-highlighter.js.map +1 -1
  32. package/src/lib/content/utils/escape-html.d.ts +7 -0
  33. package/src/lib/content/utils/escape-html.js +16 -0
  34. package/src/lib/content/utils/escape-html.js.map +1 -0
  35. package/src/lib/content-plugin.d.ts +19 -19
  36. package/src/lib/content-plugin.js +34 -9
  37. package/src/lib/content-plugin.js.map +1 -1
  38. package/src/lib/deps-plugin.d.ts +2 -2
  39. package/src/lib/deps-plugin.js +24 -11
  40. package/src/lib/deps-plugin.js.map +1 -1
  41. package/src/lib/discover-library-routes.d.ts +19 -0
  42. package/src/lib/discover-library-routes.js +72 -0
  43. package/src/lib/discover-library-routes.js.map +1 -0
  44. package/src/lib/i18n-component-registry-plugin.d.ts +17 -0
  45. package/src/lib/i18n-component-registry-plugin.js +100 -0
  46. package/src/lib/i18n-component-registry-plugin.js.map +1 -0
  47. package/src/lib/i18n-extract-plugin.d.ts +33 -0
  48. package/src/lib/inject-server-fn-ids.d.ts +17 -0
  49. package/src/lib/inject-server-fn-ids.js +94 -0
  50. package/src/lib/inject-server-fn-ids.js.map +1 -0
  51. package/src/lib/json-ld-manifest-plugin.d.ts +41 -0
  52. package/src/lib/json-ld-manifest-plugin.js +84 -0
  53. package/src/lib/json-ld-manifest-plugin.js.map +1 -0
  54. package/src/lib/nitro/analog-nitro-plugin.d.ts +18 -0
  55. package/src/lib/nitro/analog-nitro-plugin.js +582 -0
  56. package/src/lib/nitro/analog-nitro-plugin.js.map +1 -0
  57. package/src/lib/nitro/angular-linker-plugin.d.ts +15 -0
  58. package/src/lib/nitro/angular-linker-plugin.js +64 -0
  59. package/src/lib/nitro/angular-linker-plugin.js.map +1 -0
  60. package/src/lib/nitro/build-sitemap.d.ts +23 -0
  61. package/src/lib/nitro/build-sitemap.js +137 -0
  62. package/src/lib/nitro/build-sitemap.js.map +1 -0
  63. package/src/lib/nitro/debug.d.ts +5 -0
  64. package/src/lib/nitro/debug.js +11 -0
  65. package/src/lib/nitro/debug.js.map +1 -0
  66. package/src/lib/nitro/get-content-files.d.ts +13 -0
  67. package/src/lib/nitro/get-content-files.js +52 -0
  68. package/src/lib/nitro/get-content-files.js.map +1 -0
  69. package/src/lib/nitro/get-page-handlers.d.ts +22 -0
  70. package/src/lib/nitro/get-page-handlers.js +33 -0
  71. package/src/lib/nitro/get-page-handlers.js.map +1 -0
  72. package/src/lib/nitro/i18n-prerender.d.ts +29 -0
  73. package/src/lib/nitro/i18n-prerender.js +61 -0
  74. package/src/lib/nitro/i18n-prerender.js.map +1 -0
  75. package/src/lib/nitro/page-endpoints-plugin.d.ts +7 -0
  76. package/src/lib/nitro/page-endpoints-plugin.js +72 -0
  77. package/src/lib/nitro/page-endpoints-plugin.js.map +1 -0
  78. package/src/lib/nitro/post-rendering-hook.d.ts +2 -0
  79. package/src/lib/nitro/post-rendering-hook.js +10 -0
  80. package/src/lib/nitro/post-rendering-hook.js.map +1 -0
  81. package/src/lib/nitro/renderers.d.ts +33 -0
  82. package/src/lib/nitro/renderers.js +22 -0
  83. package/src/lib/nitro/renderers.js.map +1 -0
  84. package/src/lib/nitro/types.d.ts +122 -0
  85. package/src/lib/nx-plugin/_virtual/_rolldown/runtime.js +23 -0
  86. package/src/lib/nx-plugin/builders.json +15 -0
  87. package/src/lib/nx-plugin/executors.json +13 -5
  88. package/src/lib/nx-plugin/generators.json +25 -0
  89. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js +13 -0
  90. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js.map +1 -0
  91. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.js +8 -0
  92. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.js.map +1 -0
  93. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.js +9 -0
  94. package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.js.map +1 -0
  95. package/src/lib/nx-plugin/package.json +1 -3
  96. package/src/lib/nx-plugin/src/builders/vite/schema.json +39 -0
  97. package/src/lib/nx-plugin/src/builders/vite/vite-build.d.ts +11 -0
  98. package/src/lib/nx-plugin/src/builders/vite/vite-build.js +18 -0
  99. package/src/lib/nx-plugin/src/builders/vite/vite-build.js.map +1 -0
  100. package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.d.ts +7 -0
  101. package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.js +14 -0
  102. package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.js.map +1 -0
  103. package/src/lib/nx-plugin/src/builders/vite-dev-server/schema.json +27 -0
  104. package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.d.ts +1 -1
  105. package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.js +4 -4
  106. package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.js.map +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 +3 -3
  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 +4 -4
  112. package/src/lib/nx-plugin/src/executors/vitest/compat.js.map +1 -1
  113. package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.d.ts +1 -1
  114. package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.js +3 -3
  115. package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.js.map +1 -1
  116. package/src/lib/nx-plugin/src/generators/app/compat.d.ts +9 -3
  117. package/src/lib/nx-plugin/src/generators/app/compat.js +15 -4
  118. package/src/lib/nx-plugin/src/generators/app/compat.js.map +1 -1
  119. package/src/lib/nx-plugin/src/generators/app/files/agents/AGENTS.md +11 -0
  120. package/src/lib/nx-plugin/src/generators/app/files/agents/CLAUDE.md +1 -0
  121. package/src/lib/nx-plugin/src/generators/app/files/root/tsconfig.base.json +3 -6
  122. package/src/lib/nx-plugin/src/generators/app/files/template-angular/src/test-setup.ts__template__ +1 -0
  123. package/src/lib/nx-plugin/src/generators/app/files/template-angular/tsconfig.app.json__template__ +1 -3
  124. package/src/lib/nx-plugin/src/generators/app/files/template-angular/tsconfig.json__template__ +2 -1
  125. package/src/lib/nx-plugin/src/generators/app/files/template-angular/vite.config.ts__template__ +7 -3
  126. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v17/tsconfig.json__template__ +4 -2
  127. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v17/vite.config.ts__template__ +2 -5
  128. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v18/tsconfig.json__template__ +4 -2
  129. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v18/vite.config.ts__template__ +3 -6
  130. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/tsconfig.app.json__template__ +1 -3
  131. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/tsconfig.json__template__ +4 -2
  132. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/vite.config.ts__template__ +2 -5
  133. package/src/lib/nx-plugin/src/generators/app/generator.d.ts +11 -11
  134. package/src/lib/nx-plugin/src/generators/app/generator.js +44 -37
  135. package/src/lib/nx-plugin/src/generators/app/generator.js.map +1 -1
  136. package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.d.ts +2 -0
  137. package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.js +16 -0
  138. package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.js.map +1 -0
  139. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.d.ts +1 -1
  140. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.d.ts +1 -1
  141. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.js +6 -5
  142. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.js.map +1 -1
  143. package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.d.ts +2 -2
  144. package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.js +8 -11
  145. package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.js.map +1 -1
  146. package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.d.ts +2 -2
  147. package/src/lib/nx-plugin/src/generators/app/lib/add-files.d.ts +2 -2
  148. package/src/lib/nx-plugin/src/generators/app/lib/add-files.js +6 -5
  149. package/src/lib/nx-plugin/src/generators/app/lib/add-files.js.map +1 -1
  150. package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.d.ts +2 -2
  151. package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.js +6 -5
  152. package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.js.map +1 -1
  153. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.d.ts +7 -7
  154. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.js +13 -11
  155. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.js.map +1 -1
  156. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.d.ts +4 -5
  157. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.js +34 -40
  158. package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.js.map +1 -1
  159. package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.d.ts +1 -1
  160. package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.d.ts +2 -2
  161. package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.js +1 -1
  162. package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.js.map +1 -1
  163. package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.d.ts +2 -2
  164. package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.d.ts +1 -1
  165. package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.js +5 -4
  166. package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.js.map +1 -1
  167. package/src/lib/nx-plugin/src/generators/app/schema.d.ts +3 -0
  168. package/src/lib/nx-plugin/src/generators/app/schema.json +6 -0
  169. package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.d.ts +4 -2
  170. package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.js +9 -6
  171. package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.js.map +1 -1
  172. package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.d.ts +0 -3
  173. package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.d.ts +1 -1
  174. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.d.ts +12 -12
  175. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js +8 -27
  176. package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js.map +1 -1
  177. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.d.ts +1 -1
  178. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.js +6 -5
  179. package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.js.map +1 -1
  180. package/src/lib/nx-plugin/src/generators/app/versions.d.ts +0 -18
  181. package/src/lib/nx-plugin/src/generators/init/compat.d.ts +9 -3
  182. package/src/lib/nx-plugin/src/generators/init/compat.js +15 -4
  183. package/src/lib/nx-plugin/src/generators/init/compat.js.map +1 -1
  184. package/src/lib/nx-plugin/src/generators/init/files/vite.config.ts__template__ +2 -6
  185. package/src/lib/nx-plugin/src/generators/init/generator.d.ts +3 -3
  186. package/src/lib/nx-plugin/src/generators/init/generator.js +35 -34
  187. package/src/lib/nx-plugin/src/generators/init/generator.js.map +1 -1
  188. package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.d.ts +1 -1
  189. package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.js +8 -7
  190. package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.js.map +1 -1
  191. package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.d.ts +2 -2
  192. package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.js +6 -5
  193. package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.js.map +1 -1
  194. package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.d.ts +2 -2
  195. package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.js +15 -14
  196. package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.js.map +1 -1
  197. package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.d.ts +1 -1
  198. package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.js +1 -1
  199. package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.js.map +1 -1
  200. package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.d.ts +2 -2
  201. package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.js +7 -6
  202. package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.js.map +1 -1
  203. package/src/lib/nx-plugin/src/generators/init/lib/update-main.d.ts +2 -2
  204. package/src/lib/nx-plugin/src/generators/init/lib/update-main.js +5 -4
  205. package/src/lib/nx-plugin/src/generators/init/lib/update-main.js.map +1 -1
  206. package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.d.ts +2 -2
  207. package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.js +9 -8
  208. package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.js.map +1 -1
  209. package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.d.ts +2 -2
  210. package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.js +6 -5
  211. package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.js.map +1 -1
  212. package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.d.ts +2 -2
  213. package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.js +6 -5
  214. package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.js.map +1 -1
  215. package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.d.ts +2 -2
  216. package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.js +6 -5
  217. package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.js.map +1 -1
  218. package/src/lib/nx-plugin/src/generators/init/test-files/src/test-setup.ts__template__ +1 -0
  219. package/src/lib/nx-plugin/src/generators/page/__snapshots__/generator.spec.ts.snap +0 -7
  220. package/src/lib/nx-plugin/src/generators/page/compat.d.ts +9 -0
  221. package/src/lib/nx-plugin/src/generators/page/compat.js +19 -0
  222. package/src/lib/nx-plugin/src/generators/page/compat.js.map +1 -0
  223. package/src/lib/nx-plugin/src/generators/page/files/__fileName__.page.ts__template__ +0 -1
  224. package/src/lib/nx-plugin/src/generators/page/generator.d.ts +3 -4
  225. package/src/lib/nx-plugin/src/generators/page/generator.js +14 -13
  226. package/src/lib/nx-plugin/src/generators/page/generator.js.map +1 -1
  227. package/src/lib/nx-plugin/src/generators/preset/__snapshots__/generator.spec.ts.snap +9 -7
  228. package/src/lib/nx-plugin/src/generators/preset/generator.d.ts +3 -3
  229. package/src/lib/nx-plugin/src/generators/preset/generator.js +24 -7
  230. package/src/lib/nx-plugin/src/generators/preset/generator.js.map +1 -1
  231. package/src/lib/nx-plugin/src/generators/preset/schema.d.ts +1 -0
  232. package/src/lib/nx-plugin/src/generators/preset/schema.json +6 -0
  233. package/src/lib/nx-plugin/src/generators/setup-vitest/compat.d.ts +9 -3
  234. package/src/lib/nx-plugin/src/generators/setup-vitest/compat.js +15 -4
  235. package/src/lib/nx-plugin/src/generators/setup-vitest/compat.js.map +1 -1
  236. package/src/lib/nx-plugin/src/generators/setup-vitest/files/src/test-setup.ts__template__ +1 -0
  237. package/src/lib/nx-plugin/src/generators/setup-vitest/files/vite.config.mts__template__ +0 -6
  238. package/src/lib/nx-plugin/src/generators/setup-vitest/generator.d.ts +3 -3
  239. package/src/lib/nx-plugin/src/generators/setup-vitest/generator.js +19 -21
  240. package/src/lib/nx-plugin/src/generators/setup-vitest/generator.js.map +1 -1
  241. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.d.ts +1 -1
  242. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.js +5 -4
  243. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.js.map +1 -1
  244. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.d.ts +2 -2
  245. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.js +6 -5
  246. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.js.map +1 -1
  247. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.d.ts +2 -2
  248. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.js +6 -5
  249. package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.js.map +1 -1
  250. package/src/lib/nx-plugin/src/utils/version-utils.d.ts +1 -1
  251. package/src/lib/nx-plugin/src/utils/version-utils.js +9 -8
  252. package/src/lib/nx-plugin/src/utils/version-utils.js.map +1 -1
  253. package/src/lib/nx-plugin/src/utils/versions/dependencies.js +33 -32
  254. package/src/lib/nx-plugin/src/utils/versions/dependencies.js.map +1 -1
  255. package/src/lib/nx-plugin/src/utils/versions/dev-dependencies.js +40 -39
  256. package/src/lib/nx-plugin/src/utils/versions/dev-dependencies.js.map +1 -1
  257. package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.d.ts +1 -1
  258. package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.js +16 -2
  259. package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.js.map +1 -1
  260. package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.d.ts +1 -1
  261. package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.js +16 -2
  262. package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.js.map +1 -1
  263. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.d.ts +9 -8
  264. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js +27 -10
  265. package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js.map +1 -1
  266. package/src/lib/options.d.ts +165 -84
  267. package/src/lib/platform-plugin.d.ts +2 -2
  268. package/src/lib/platform-plugin.js +20 -34
  269. package/src/lib/platform-plugin.js.map +1 -1
  270. package/src/lib/route-file-discovery.d.ts +23 -0
  271. package/src/lib/route-file-discovery.js +114 -0
  272. package/src/lib/route-file-discovery.js.map +1 -0
  273. package/src/lib/route-generation-plugin.d.ts +3 -0
  274. package/src/lib/route-generation-plugin.js +45 -0
  275. package/src/lib/route-generation-plugin.js.map +1 -0
  276. package/src/lib/route-idiom-diagnostics.d.ts +13 -0
  277. package/src/lib/route-idiom-diagnostics.js +160 -0
  278. package/src/lib/route-idiom-diagnostics.js.map +1 -0
  279. package/src/lib/route-manifest.d.ts +122 -0
  280. package/src/lib/route-manifest.js +431 -0
  281. package/src/lib/route-manifest.js.map +1 -0
  282. package/src/lib/router-plugin.d.ts +19 -19
  283. package/src/lib/router-plugin.js +127 -33
  284. package/src/lib/router-plugin.js.map +1 -1
  285. package/src/lib/server-fn-client-transform.d.ts +26 -0
  286. package/src/lib/server-fn-client-transform.js +97 -0
  287. package/src/lib/server-fn-client-transform.js.map +1 -0
  288. package/src/lib/server-fn-id.d.ts +25 -0
  289. package/src/lib/server-fn-id.js +37 -0
  290. package/src/lib/server-fn-id.js.map +1 -0
  291. package/src/lib/ssr/defer-streaming-plugin.d.ts +65 -0
  292. package/src/lib/ssr/inject-html-plugin.d.ts +1 -1
  293. package/src/lib/ssr/inject-html-plugin.js.map +1 -1
  294. package/src/lib/ssr/ssr-build-plugin.d.ts +24 -16
  295. package/src/lib/ssr/ssr-build-plugin.js +2 -18
  296. package/src/lib/ssr/ssr-build-plugin.js.map +1 -1
  297. package/src/lib/typed-routes-plugin.d.ts +50 -0
  298. package/src/lib/typed-routes-plugin.js +234 -0
  299. package/src/lib/typed-routes-plugin.js.map +1 -0
  300. package/src/lib/utils/debug-harness.d.ts +23 -0
  301. package/src/lib/utils/debug-harness.js +88 -0
  302. package/src/lib/utils/debug-harness.js.map +1 -0
  303. package/src/lib/utils/debug-log-file.d.ts +5 -0
  304. package/src/lib/utils/debug-log-file.js +56 -0
  305. package/src/lib/utils/debug-log-file.js.map +1 -0
  306. package/src/lib/utils/debug.d.ts +20 -0
  307. package/src/lib/utils/debug.js +24 -0
  308. package/src/lib/utils/debug.js.map +1 -0
  309. package/src/lib/utils/rolldown.d.ts +2 -2
  310. package/src/lib/utils/rolldown.js.map +1 -1
  311. package/src/server-mode-plugin.d.ts +11 -5
  312. package/src/server-mode-plugin.js +16 -6
  313. package/src/server-mode-plugin.js.map +1 -1
  314. package/src/lib/nx-plugin/src/executors/vite/compat.d.ts +0 -3
  315. package/src/lib/nx-plugin/src/executors/vite/compat.js +0 -8
  316. package/src/lib/nx-plugin/src/executors/vite/compat.js.map +0 -1
  317. package/src/lib/nx-plugin/src/executors/vite/schema.d.ts +0 -2
  318. package/src/lib/nx-plugin/src/executors/vite/schema.json +0 -147
  319. package/src/lib/nx-plugin/src/executors/vite/vite.impl.d.ts +0 -2
  320. package/src/lib/nx-plugin/src/executors/vite/vite.impl.js +0 -7
  321. package/src/lib/nx-plugin/src/executors/vite/vite.impl.js.map +0 -1
  322. package/src/lib/nx-plugin/src/generators/app/files/tailwind/v4/.postcssrc.json +0 -5
  323. package/src/lib/nx-plugin/src/generators/app/files/tailwind/v4/tailwind.config.ts__template__ +0 -14
  324. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/index.html__template__ +0 -15
  325. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.spec.ts__template__ +0 -17
  326. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.ts__template__ +0 -10
  327. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/favicon.ico__template__ +0 -0
  328. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.providers.ts__template__ +0 -5
  329. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.server.ts__template__ +0 -23
  330. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.ts__template__ +0 -11
  331. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/.gitkeep__template__ +0 -0
  332. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/analog.svg__template__ +0 -1
  333. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/vite.svg__template__ +0 -1
  334. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/server/routes/v1/hello.ts__template__ +0 -3
  335. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/styles.css__template__ +0 -4
  336. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/test-setup.ts__template__ +0 -12
  337. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/vite-env.d.ts__template__ +0 -1
  338. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.app.json__template__ +0 -16
  339. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.editor.json__template__ +0 -7
  340. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.json__template__ +0 -32
  341. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.spec.json__template__ +0 -14
  342. package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/vite.config.ts__template__ +0 -61
  343. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.js +0 -14
  344. package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.js.map +0 -1
  345. package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.js +0 -15
  346. package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.js.map +0 -1
  347. package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.js +0 -11
  348. package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.js.map +0 -1
  349. package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.js +0 -64
  350. package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.js.map +0 -1
  351. package/src/lib/nx-plugin/src/generators/app/versions/dependencies.js +0 -37
  352. package/src/lib/nx-plugin/src/generators/app/versions/dependencies.js.map +0 -1
  353. package/src/lib/nx-plugin/src/generators/app/versions/dev-dependencies.js +0 -45
  354. package/src/lib/nx-plugin/src/generators/app/versions/dev-dependencies.js.map +0 -1
  355. package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.js +0 -27
  356. package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.js.map +0 -1
  357. package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.js +0 -30
  358. package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.js.map +0 -1
  359. package/src/lib/nx-plugin/src/generators/app/versions.js +0 -29
  360. package/src/lib/nx-plugin/src/generators/app/versions.js.map +0 -1
  361. package/src/lib/nx-plugin/src/index.d.ts +0 -0
@@ -1,22 +1,22 @@
1
- import * as vite from 'vite';
2
- import type { WithShikiHighlighterOptions } from './content/shiki/options.js';
3
- import type { WithPrismHighlighterOptions } from './content/prism/options.js';
4
- import type { WithMarkedOptions } from './content/marked/index.js';
5
- import type { Options } from './options.js';
1
+ import * as vite from "vite";
2
+ import type { WithShikiHighlighterOptions } from "./content/shiki/options.js";
3
+ import type { WithPrismHighlighterOptions } from "./content/prism/options.js";
4
+ import type { WithMarkedOptions } from "./content/marked/index.js";
5
+ import type { Options } from "./options.js";
6
6
  export type ContentPluginOptions = {
7
- highlighter?: 'shiki' | 'prism';
8
- markedOptions?: WithMarkedOptions;
9
- shikiOptions?: WithShikiHighlighterOptions;
10
- prismOptions?: WithPrismHighlighterOptions;
7
+ highlighter?: "shiki" | "prism";
8
+ markedOptions?: WithMarkedOptions;
9
+ shikiOptions?: WithShikiHighlighterOptions;
10
+ prismOptions?: WithPrismHighlighterOptions;
11
11
  };
12
12
  /**
13
- * Content plugin that provides markdown and content file processing for Analog.
14
- *
15
- * IMPORTANT: This plugin uses tinyglobby for file discovery.
16
- * Key pitfall with { dot: true }:
17
- * - Returns relative paths from cwd (e.g., "apps/blog-app/src/content/...")
18
- * - These paths CANNOT be used directly in ES module imports
19
- * - Relative paths without ./ or ../ are treated as package names
20
- * - Must convert to absolute paths for imports to work correctly
21
- */
22
- export declare function contentPlugin({ highlighter, markedOptions, shikiOptions, prismOptions, }?: ContentPluginOptions, options?: Options): vite.Plugin[];
13
+ * Content plugin that provides markdown and content file processing for Analog.
14
+ *
15
+ * IMPORTANT: This plugin uses tinyglobby for file discovery.
16
+ * Key pitfall with { dot: true }:
17
+ * - Returns relative paths from cwd (e.g., "apps/blog-app/src/content/...")
18
+ * - These paths CANNOT be used directly in ES module imports
19
+ * - Relative paths without ./ or ../ are treated as package names
20
+ * - Must convert to absolute paths for imports to work correctly
21
+ */
22
+ export declare function contentPlugin({ highlighter, markedOptions, shikiOptions, prismOptions }?: ContentPluginOptions, options?: Options): vite.Plugin[];
@@ -1,8 +1,8 @@
1
1
  import { getBundleOptionsKey } from "./utils/rolldown.js";
2
+ import { relative, resolve } from "node:path";
3
+ import { readFileSync } from "node:fs";
2
4
  import * as vite from "vite";
3
5
  import { globSync } from "tinyglobby";
4
- import { resolve } from "node:path";
5
- import { readFileSync } from "node:fs";
6
6
  //#region packages/platform/src/lib/content-plugin.ts
7
7
  /**
8
8
  * Content plugin that provides markdown and content file processing for Analog.
@@ -16,29 +16,47 @@ import { readFileSync } from "node:fs";
16
16
  */
17
17
  function contentPlugin({ highlighter, markedOptions, shikiOptions, prismOptions } = {}, options) {
18
18
  const cache = /* @__PURE__ */ new Map();
19
+ let contentFilesListCache;
19
20
  let markedHighlighter;
20
- const workspaceRoot = vite.normalizePath(options?.workspaceRoot ?? process.cwd());
21
+ const workspaceRoot = vite.normalizePath(options?.workspaceRoot ?? process.env["NX_WORKSPACE_ROOT"] ?? process.cwd());
21
22
  let config;
22
23
  let root;
24
+ let contentRootDirs;
25
+ const normalizeContentDir = (dir) => {
26
+ const normalized = vite.normalizePath(dir.startsWith("/") ? `${workspaceRoot}${dir}` : resolve(workspaceRoot, dir));
27
+ return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
28
+ };
29
+ const initContentRootDirs = () => {
30
+ contentRootDirs = [vite.normalizePath(`${root}/src/content`), ...(options?.additionalContentDirs || []).map(normalizeContentDir)];
31
+ };
32
+ const discoverContentFilesList = () => {
33
+ contentFilesListCache ??= globSync(contentRootDirs.map((dir) => `${dir}/**/*.md`), { dot: true });
34
+ return contentFilesListCache;
35
+ };
36
+ const resolveContentModulePath = (module) => vite.normalizePath(module.startsWith("/") ? module : `${workspaceRoot}/${module}`);
37
+ const getContentModuleKey = (module) => {
38
+ const absolutePath = resolveContentModulePath(module);
39
+ const relativeToRoot = vite.normalizePath(relative(root, absolutePath));
40
+ return !relativeToRoot.startsWith("..") && !relativeToRoot.startsWith("/") ? `/${relativeToRoot}` : `/${vite.normalizePath(relative(workspaceRoot, absolutePath))}`;
41
+ };
23
42
  const contentDiscoveryPlugins = [{
24
43
  name: "analog-content-glob-routes",
25
44
  config(_config) {
26
45
  config = _config;
27
46
  root = vite.normalizePath(resolve(workspaceRoot, config.root || ".") || ".");
47
+ initContentRootDirs();
28
48
  },
29
49
  transform: {
30
50
  filter: { code: "ANALOG_CONTENT_FILE_LIST" },
31
51
  handler(code) {
32
52
  if (code.includes("ANALOG_CONTENT_FILE_LIST")) {
33
- const contentFilesList = globSync([`${root}/src/content/**/*.md`, ...(options?.additionalContentDirs || []).map((glob) => `${workspaceRoot}${glob}/**/*.md`)], { dot: true });
53
+ const contentFilesList = discoverContentFilesList();
34
54
  const eagerImports = [];
35
55
  contentFilesList.forEach((module, index) => {
36
- const absolutePath = module.startsWith("/") ? module : `${workspaceRoot}/${module}`;
56
+ const absolutePath = resolveContentModulePath(module);
37
57
  eagerImports.push(`import { default as analog_module_${index} } from "${absolutePath}?analog-content-list=true";`);
38
58
  });
39
- let result = code.replace("const ANALOG_CONTENT_FILE_LIST = {};", `
40
- let ANALOG_CONTENT_FILE_LIST = {${contentFilesList.map((module, index) => `"${module.replace(root, "")}": analog_module_${index}`)}};
41
- `);
59
+ let result = code.replace(/ANALOG_CONTENT_FILE_LIST\s*=\s*\{\s*\}/, `ANALOG_CONTENT_FILE_LIST = {${contentFilesList.map((module, index) => `"${getContentModuleKey(module)}": analog_module_${index}`)}}`);
42
60
  if (!code.includes("analog_module_")) result = `${eagerImports.join("\n")}\n${result}`;
43
61
  return {
44
62
  code: result,
@@ -51,7 +69,9 @@ function contentPlugin({ highlighter, markedOptions, shikiOptions, prismOptions
51
69
  name: "analogjs-invalidate-content-dirs",
52
70
  configureServer(server) {
53
71
  function invalidateContent(path) {
54
- if (path.includes(vite.normalizePath(`/content/`))) {
72
+ const normalizedPath = vite.normalizePath(path);
73
+ if (contentRootDirs.some((dir) => normalizedPath === dir || normalizedPath.startsWith(`${dir}/`))) {
74
+ contentFilesListCache = void 0;
55
75
  server.moduleGraph.fileToModulesMap.forEach((mods) => {
56
76
  mods.forEach((mod) => {
57
77
  if (mod.id?.includes("analogjs") && mod.id?.includes("content")) {
@@ -62,6 +82,11 @@ function contentPlugin({ highlighter, markedOptions, shikiOptions, prismOptions
62
82
  }
63
83
  });
64
84
  });
85
+ server.ws.send("analog:debug-full-reload", {
86
+ plugin: "platform:content-plugin",
87
+ reason: "content-file-set-changed",
88
+ path: normalizedPath
89
+ });
65
90
  server.ws.send({ type: "full-reload" });
66
91
  }
67
92
  }
@@ -1 +1 @@
1
- {"version":3,"file":"content-plugin.js","names":[],"sources":["../../../../../packages/platform/src/lib/content-plugin.ts"],"sourcesContent":["import * as vite from 'vite';\nimport { readFileSync } from 'node:fs';\nimport { 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\n let markedHighlighter: MarkedContentHighlighter;\n const workspaceRoot = vite.normalizePath(\n options?.workspaceRoot ?? process.cwd(),\n );\n let config: vite.UserConfig;\n let root: string;\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 },\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: string[] = globSync(\n [\n `${root}/src/content/**/*.md`,\n ...(options?.additionalContentDirs || []).map(\n (glob) => `${workspaceRoot}${glob}/**/*.md`,\n ),\n ],\n { dot: true },\n );\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 = module.startsWith('/')\n ? module\n : `${workspaceRoot}/${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 `\"${module.replace(root, '')}\": 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 if (path.includes(vite.normalizePath(`/content/`))) {\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 // Match just the assignment (not the declaration) so the rewrite\n // works whether the source uses `const`, `let`, `var`, or\n // `export const` — including the post-Rolldown `var X = {};`\n // form — without destroying the declaration that keeps the\n // module binding exported.\n let result = code.replace(\n /ANALOG_CONTENT_FILE_LIST\\s*=\\s*\\{\\s*\\}/,\n `ANALOG_CONTENT_FILE_LIST = {${contentFilesList.map(\n (module, index) =>\n `\"${getContentModuleKey(module)}\": analog_module_${index}`,\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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"}
@@ -1,3 +1,3 @@
1
- import type { Plugin } from 'vite';
2
- import { Options } from './options.js';
1
+ import type { Plugin } from "vite";
2
+ import { Options } from "./options.js";
3
3
  export declare function depsPlugin(options?: Options): Plugin[];
@@ -1,24 +1,37 @@
1
+ import { debugPlatform } from "./utils/debug.js";
1
2
  import { getJsTransformConfigKey } from "./utils/rolldown.js";
2
3
  import { VERSION } from "@angular/compiler-cli";
3
4
  import { crawlFrameworkPkgs } from "vitefu";
4
5
  //#region packages/platform/src/lib/deps-plugin.ts
5
6
  function depsPlugin(options) {
6
- const workspaceRoot = options?.workspaceRoot ?? process.cwd();
7
+ const workspaceRoot = options?.workspaceRoot ?? process.env["NX_WORKSPACE_ROOT"] ?? process.cwd();
7
8
  return [{
8
9
  name: "analogjs-deps-plugin",
9
10
  config() {
10
- const transformConfig = options?.vite === false || options?.vite?.experimental?.useAngularCompilationAPI ? {} : { exclude: ["**/*.ts", "**/*.js"] };
11
+ const transformConfig = { exclude: ["**/*.ts", "**/*.js"] };
12
+ debugPlatform("deps transform config", {
13
+ jsTransformKey: getJsTransformConfigKey(),
14
+ transformExcluded: true
15
+ });
11
16
  return {
12
17
  [getJsTransformConfigKey()]: transformConfig,
13
- ssr: { noExternal: [
14
- "@analogjs/**",
15
- "firebase/**",
16
- "firebase-admin/**",
17
- "rxfire",
18
- "@ng-web-apis/**",
19
- "@taiga-ui/**",
20
- "@tanstack/angular-query-experimental"
21
- ] },
18
+ ssr: {
19
+ noExternal: [
20
+ "@analogjs/**",
21
+ "es-toolkit",
22
+ "firebase/**",
23
+ "firebase-admin/**",
24
+ "rxfire",
25
+ "@ng-web-apis/**",
26
+ "@taiga-ui/**",
27
+ "@tanstack/angular-query-experimental"
28
+ ],
29
+ optimizeDeps: { include: [
30
+ "@angular/common",
31
+ "@angular/common/http",
32
+ ...Number(VERSION.major) > 15 ? ["@angular/core/rxjs-interop"] : []
33
+ ] }
34
+ },
22
35
  optimizeDeps: {
23
36
  include: [
24
37
  "@angular/common",
@@ -1 +1 @@
1
- {"version":3,"file":"deps-plugin.js","names":[],"sources":["../../../../../packages/platform/src/lib/deps-plugin.ts"],"sourcesContent":["import { VERSION } from '@angular/compiler-cli';\nimport type { Plugin } from 'vite';\nimport * as vite from 'vite';\nimport { crawlFrameworkPkgs } from 'vitefu';\n\nimport { Options } from './options.js';\nimport { getJsTransformConfigKey } from './utils/rolldown.js';\n\nexport function depsPlugin(options?: Options): Plugin[] {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n\n return [\n {\n name: 'analogjs-deps-plugin',\n config() {\n const transformConfig =\n options?.vite === false ||\n options?.vite?.experimental?.useAngularCompilationAPI\n ? {}\n : { exclude: ['**/*.ts', '**/*.js'] };\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,gBAAgB,SAAS,iBAAiB,QAAQ,KAAK;AAE7D,QAAO,CACL;EACE,MAAM;EACN,SAAS;GACP,MAAM,kBACJ,SAAS,SAAS,SAClB,SAAS,MAAM,cAAc,2BACzB,EAAE,GACF,EAAE,SAAS,CAAC,WAAW,UAAU,EAAE;AAEzC,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\n return [\n {\n name: 'analogjs-deps-plugin',\n config() {\n // Skip Vite's built-in ts/js transform so `@analogjs/vite-plugin-angular`\n // (when the user includes it) owns Angular file compilation. Users who\n // run an alternative compiler or compile through Angular's own\n // compilation API can override this in their own Vite config.\n const transformConfig = { exclude: ['**/*.ts', '**/*.js'] };\n debugPlatform('deps transform config', {\n jsTransformKey: getJsTransformConfigKey(),\n transformExcluded: true,\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 // The server pre-bundle is resolved separately from the client\n // one, so a secondary entry point left out of it loads its own\n // copy of `@angular/core`. `inject()` then runs against a runtime\n // with no active injection context and SSR fails with NG0203.\n optimizeDeps: {\n include: [\n '@angular/common',\n '@angular/common/http',\n ...(Number(VERSION.major) > 15\n ? ['@angular/core/rxjs-interop']\n : []),\n ],\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;AAE7E,QAAO,CACL;EACE,MAAM;EACN,SAAS;GAKP,MAAM,kBAAkB,EAAE,SAAS,CAAC,WAAW,UAAU,EAAE;AAC3D,iBAAc,yBAAyB;IACrC,gBAAgB,yBAAyB;IACzC,mBAAmB;IACpB,CAAC;AAEF,UAAO;KACJ,yBAAyB,GAAG;IAC7B,KAAK;KACH,YAAY;MACV;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACD;KAKD,cAAc,EACZ,SAAS;MACP;MACA;MACA,GAAI,OAAO,QAAQ,MAAM,GAAG,KACxB,CAAC,6BAA6B,GAC9B,EAAE;MACP,EACF;KACF;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"}
@@ -0,0 +1,19 @@
1
+ export interface DiscoveredLibraryRoutes {
2
+ additionalPagesDirs: string[];
3
+ additionalContentDirs: string[];
4
+ additionalAPIDirs: string[];
5
+ }
6
+ /**
7
+ * Scans workspace libraries directly for conventional route directories
8
+ * (`src/pages`, `src/content`, `src/api`).
9
+ *
10
+ * Returns workspace-relative paths (e.g. `/libs/shared/feature`) suitable
11
+ * for merging into the `additional*Dirs` options.
12
+ */
13
+ export declare function discoverLibraryRoutes(workspaceRoot: string): DiscoveredLibraryRoutes;
14
+ /**
15
+ * Builds `${dir}/**\/*.page.ts` globs for each provided directory. The
16
+ * platform registers these with Angular compilation through `analog.setup()`
17
+ * for every `additionalPagesDirs` entry.
18
+ */
19
+ export declare function pageGlobs(dirs: string[]): string[];
@@ -0,0 +1,72 @@
1
+ import { normalizePath } from "vite";
2
+ import { globSync } from "tinyglobby";
3
+ //#region packages/platform/src/lib/discover-library-routes.ts
4
+ Object.freeze({
5
+ additionalPagesDirs: Object.freeze([]),
6
+ additionalContentDirs: Object.freeze([]),
7
+ additionalAPIDirs: Object.freeze([])
8
+ });
9
+ var discoverableLibRouteDirs = [
10
+ "libs/**/src/pages",
11
+ "libs/**/src/content",
12
+ "libs/**/src/api"
13
+ ];
14
+ function toWorkspacePath(path) {
15
+ return normalizePath(path).replace(/\/$/, "");
16
+ }
17
+ /**
18
+ * Scans workspace libraries directly for conventional route directories
19
+ * (`src/pages`, `src/content`, `src/api`).
20
+ *
21
+ * Returns workspace-relative paths (e.g. `/libs/shared/feature`) suitable
22
+ * for merging into the `additional*Dirs` options.
23
+ */
24
+ function discoverLibraryRoutes(workspaceRoot) {
25
+ const result = {
26
+ additionalPagesDirs: [],
27
+ additionalContentDirs: [],
28
+ additionalAPIDirs: []
29
+ };
30
+ const normalizedWorkspaceRoot = toWorkspacePath(workspaceRoot);
31
+ const discovered = /* @__PURE__ */ new Map();
32
+ for (const dir of globSync(discoverableLibRouteDirs, {
33
+ cwd: normalizedWorkspaceRoot,
34
+ dot: true,
35
+ onlyDirectories: true
36
+ })) {
37
+ const normalizedDir = toWorkspacePath(dir);
38
+ const workspaceRelativeDir = normalizedDir.startsWith(`${normalizedWorkspaceRoot}/`) ? normalizedDir.slice(normalizedWorkspaceRoot.length + 1) : normalizedDir;
39
+ if (!workspaceRelativeDir.startsWith("libs/")) continue;
40
+ const srcIndex = workspaceRelativeDir.indexOf("/src/");
41
+ if (srcIndex === -1) continue;
42
+ const libRoot = workspaceRelativeDir.slice(0, srcIndex);
43
+ const entry = discovered.get(libRoot) ?? {
44
+ pages: false,
45
+ content: false,
46
+ api: false
47
+ };
48
+ if (workspaceRelativeDir.endsWith("/src/pages")) entry.pages = true;
49
+ if (workspaceRelativeDir.endsWith("/src/content")) entry.content = true;
50
+ if (workspaceRelativeDir.endsWith("/src/api")) entry.api = true;
51
+ discovered.set(libRoot, entry);
52
+ }
53
+ for (const libRoot of [...discovered.keys()].sort()) {
54
+ const entry = discovered.get(libRoot);
55
+ if (entry.pages) result.additionalPagesDirs.push(`/${libRoot}`);
56
+ if (entry.content) result.additionalContentDirs.push(`/${libRoot}/src/content`);
57
+ if (entry.api) result.additionalAPIDirs.push(`/${libRoot}/src/api`);
58
+ }
59
+ return result;
60
+ }
61
+ /**
62
+ * Builds `${dir}/**\/*.page.ts` globs for each provided directory. The
63
+ * platform registers these with Angular compilation through `analog.setup()`
64
+ * for every `additionalPagesDirs` entry.
65
+ */
66
+ function pageGlobs(dirs) {
67
+ return dirs.map((dir) => `${dir}/**/*.page.ts`);
68
+ }
69
+ //#endregion
70
+ export { discoverLibraryRoutes, pageGlobs };
71
+
72
+ //# sourceMappingURL=discover-library-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover-library-routes.js","names":[],"sources":["../../../src/lib/discover-library-routes.ts"],"sourcesContent":["import { normalizePath } from 'vite';\nimport { globSync } from 'tinyglobby';\n\nexport interface DiscoveredLibraryRoutes {\n additionalPagesDirs: string[];\n additionalContentDirs: string[];\n additionalAPIDirs: string[];\n}\n\nconst empty: DiscoveredLibraryRoutes = Object.freeze({\n additionalPagesDirs: Object.freeze([] as string[]),\n additionalContentDirs: Object.freeze([] as string[]),\n additionalAPIDirs: Object.freeze([] as string[]),\n});\n\nconst discoverableLibRouteDirs = [\n 'libs/**/src/pages',\n 'libs/**/src/content',\n 'libs/**/src/api',\n] as const;\n\nfunction toWorkspacePath(path: string) {\n return normalizePath(path).replace(/\\/$/, '');\n}\n\n/**\n * Scans workspace libraries directly for conventional route directories\n * (`src/pages`, `src/content`, `src/api`).\n *\n * Returns workspace-relative paths (e.g. `/libs/shared/feature`) suitable\n * for merging into the `additional*Dirs` options.\n */\nexport function discoverLibraryRoutes(\n workspaceRoot: string,\n): DiscoveredLibraryRoutes {\n const result: DiscoveredLibraryRoutes = {\n additionalPagesDirs: [],\n additionalContentDirs: [],\n additionalAPIDirs: [],\n };\n const normalizedWorkspaceRoot = toWorkspacePath(workspaceRoot);\n const discovered = new Map<\n string,\n {\n pages: boolean;\n content: boolean;\n api: boolean;\n }\n >();\n\n for (const dir of globSync(discoverableLibRouteDirs, {\n cwd: normalizedWorkspaceRoot,\n dot: true,\n onlyDirectories: true,\n })) {\n const normalizedDir = toWorkspacePath(dir);\n const workspaceRelativeDir = normalizedDir.startsWith(\n `${normalizedWorkspaceRoot}/`,\n )\n ? normalizedDir.slice(normalizedWorkspaceRoot.length + 1)\n : normalizedDir;\n\n if (!workspaceRelativeDir.startsWith('libs/')) {\n continue;\n }\n\n const srcIndex = workspaceRelativeDir.indexOf('/src/');\n if (srcIndex === -1) {\n continue;\n }\n\n const libRoot = workspaceRelativeDir.slice(0, srcIndex);\n const entry = discovered.get(libRoot) ?? {\n pages: false,\n content: false,\n api: false,\n };\n\n if (workspaceRelativeDir.endsWith('/src/pages')) {\n entry.pages = true;\n }\n\n if (workspaceRelativeDir.endsWith('/src/content')) {\n entry.content = true;\n }\n\n if (workspaceRelativeDir.endsWith('/src/api')) {\n entry.api = true;\n }\n\n discovered.set(libRoot, entry);\n }\n\n for (const libRoot of [...discovered.keys()].sort()) {\n const entry = discovered.get(libRoot)!;\n\n if (entry.pages) {\n result.additionalPagesDirs.push(`/${libRoot}`);\n }\n\n if (entry.content) {\n result.additionalContentDirs.push(`/${libRoot}/src/content`);\n }\n\n if (entry.api) {\n result.additionalAPIDirs.push(`/${libRoot}/src/api`);\n }\n }\n\n return result;\n}\n\n/**\n * Builds `${dir}/**\\/*.page.ts` globs for each provided directory. The\n * platform registers these with Angular compilation through `analog.setup()`\n * for every `additionalPagesDirs` entry.\n */\nexport function pageGlobs(dirs: string[]): string[] {\n return dirs.map((dir) => `${dir}/**/*.page.ts`);\n}\n"],"mappings":";;;AASuC,OAAO,OAAO;CACnD,qBAAqB,OAAO,OAAO,EAAE,CAAa;CAClD,uBAAuB,OAAO,OAAO,EAAE,CAAa;CACpD,mBAAmB,OAAO,OAAO,EAAE,CAAa;CACjD,CAAC;AAEF,IAAM,2BAA2B;CAC/B;CACA;CACA;CACD;AAED,SAAS,gBAAgB,MAAc;AACrC,QAAO,cAAc,KAAK,CAAC,QAAQ,OAAO,GAAG;;;;;;;;;AAU/C,SAAgB,sBACd,eACyB;CACzB,MAAM,SAAkC;EACtC,qBAAqB,EAAE;EACvB,uBAAuB,EAAE;EACzB,mBAAmB,EAAE;EACtB;CACD,MAAM,0BAA0B,gBAAgB,cAAc;CAC9D,MAAM,6BAAa,IAAI,KAOpB;AAEH,MAAK,MAAM,OAAO,SAAS,0BAA0B;EACnD,KAAK;EACL,KAAK;EACL,iBAAiB;EAClB,CAAC,EAAE;EACF,MAAM,gBAAgB,gBAAgB,IAAI;EAC1C,MAAM,uBAAuB,cAAc,WACzC,GAAG,wBAAwB,GAC5B,GACG,cAAc,MAAM,wBAAwB,SAAS,EAAE,GACvD;AAEJ,MAAI,CAAC,qBAAqB,WAAW,QAAQ,CAC3C;EAGF,MAAM,WAAW,qBAAqB,QAAQ,QAAQ;AACtD,MAAI,aAAa,GACf;EAGF,MAAM,UAAU,qBAAqB,MAAM,GAAG,SAAS;EACvD,MAAM,QAAQ,WAAW,IAAI,QAAQ,IAAI;GACvC,OAAO;GACP,SAAS;GACT,KAAK;GACN;AAED,MAAI,qBAAqB,SAAS,aAAa,CAC7C,OAAM,QAAQ;AAGhB,MAAI,qBAAqB,SAAS,eAAe,CAC/C,OAAM,UAAU;AAGlB,MAAI,qBAAqB,SAAS,WAAW,CAC3C,OAAM,MAAM;AAGd,aAAW,IAAI,SAAS,MAAM;;AAGhC,MAAK,MAAM,WAAW,CAAC,GAAG,WAAW,MAAM,CAAC,CAAC,MAAM,EAAE;EACnD,MAAM,QAAQ,WAAW,IAAI,QAAQ;AAErC,MAAI,MAAM,MACR,QAAO,oBAAoB,KAAK,IAAI,UAAU;AAGhD,MAAI,MAAM,QACR,QAAO,sBAAsB,KAAK,IAAI,QAAQ,cAAc;AAG9D,MAAI,MAAM,IACR,QAAO,kBAAkB,KAAK,IAAI,QAAQ,UAAU;;AAIxD,QAAO;;;;;;;AAQT,SAAgB,UAAU,MAA0B;AAClD,QAAO,KAAK,KAAK,QAAQ,GAAG,IAAI,eAAe"}
@@ -0,0 +1,17 @@
1
+ import type { Plugin } from "vite";
2
+ /**
3
+ * Vite plugin that instruments compiled Angular component definitions with
4
+ * calls to `registerI18nComponentDef()` from `@analogjs/router`. This
5
+ * populates a process-level registry of component definitions that the
6
+ * server renderer uses to null cached `tView` objects between SSR requests,
7
+ * allowing `$localize` tagged templates in `consts()` to re-evaluate with
8
+ * the freshly loaded translations for each request's locale.
9
+ *
10
+ * The plugin runs in `enforce: 'post'` so that it sees the compiled
11
+ * JavaScript output from the Angular compiler (which contains the
12
+ * `ClassName.ɵcmp = ɵɵdefineComponent({...})` assignments).
13
+ *
14
+ * Only active when the platform's `i18n` option is configured.
15
+ * Only transforms modules loaded for the SSR environment.
16
+ */
17
+ export declare function i18nComponentRegistryPlugin(): Plugin;
@@ -0,0 +1,100 @@
1
+ import MagicString from "magic-string";
2
+ //#region packages/platform/src/lib/i18n-component-registry-plugin.ts
3
+ /**
4
+ * Vite plugin that instruments compiled Angular component definitions with
5
+ * calls to `registerI18nComponentDef()` from `@analogjs/router`. This
6
+ * populates a process-level registry of component definitions that the
7
+ * server renderer uses to null cached `tView` objects between SSR requests,
8
+ * allowing `$localize` tagged templates in `consts()` to re-evaluate with
9
+ * the freshly loaded translations for each request's locale.
10
+ *
11
+ * The plugin runs in `enforce: 'post'` so that it sees the compiled
12
+ * JavaScript output from the Angular compiler (which contains the
13
+ * `ClassName.ɵcmp = ɵɵdefineComponent({...})` assignments).
14
+ *
15
+ * Only active when the platform's `i18n` option is configured.
16
+ * Only transforms modules loaded for the SSR environment.
17
+ */
18
+ function i18nComponentRegistryPlugin() {
19
+ return {
20
+ name: "analogjs-i18n-component-registry",
21
+ enforce: "post",
22
+ transform(code, id, options) {
23
+ if (!options?.ssr) return;
24
+ if (!code.includes(".ɵcmp")) return;
25
+ if (id.includes("node_modules")) return;
26
+ if (!id.match(/\.(ts|js)(\?|$)/)) return;
27
+ const classNames = findComponentClassNames(this.parse(code));
28
+ if (classNames.size === 0) return;
29
+ const registrations = [...classNames].map((name) => `__analog_i18n_reg(${name});`).join("\n");
30
+ const s = new MagicString(code);
31
+ s.prepend(`import { ɵregisterI18nComponentDef as __analog_i18n_reg } from '@analogjs/router';\n`);
32
+ s.append(`\n${registrations}\n`);
33
+ return {
34
+ code: s.toString(),
35
+ map: s.generateMap({
36
+ hires: true,
37
+ source: id,
38
+ includeContent: true
39
+ })
40
+ };
41
+ }
42
+ };
43
+ }
44
+ /**
45
+ * Walks the AST to find class names whose definitions include a `ɵcmp`
46
+ * static property assignment — the marker Angular uses for compiled
47
+ * component definitions.
48
+ *
49
+ * Handles two codegen styles:
50
+ *
51
+ * Production (tree-shaken):
52
+ * _ClassName.ɵcmp = ɵɵdefineComponent({...})
53
+ * → AssignmentExpression left: MemberExpression(.ɵcmp) object: Identifier
54
+ *
55
+ * Dev mode (class fields):
56
+ * class Foo { static { this.ɵcmp = i0.ɵɵdefineComponent({...}) } }
57
+ * → ClassDeclaration → StaticBlock → AssignmentExpression left: MemberExpression(.ɵcmp) object: ThisExpression
58
+ */
59
+ function findComponentClassNames(ast) {
60
+ const names = /* @__PURE__ */ new Set();
61
+ walk(ast, (node) => {
62
+ if (node.type === "AssignmentExpression" && isNode(node.left) && node.left.type === "MemberExpression" && isNode(node.left.property) && node.left.property.name === "ɵcmp" && isNode(node.left.object) && node.left.object.type === "Identifier") {
63
+ const name = node.left.object.name;
64
+ if (name !== "this") names.add(name);
65
+ }
66
+ if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && isNode(node.id) && node.id.name) {
67
+ const className = node.id.name;
68
+ if (classHasCmpDef(node)) names.add(className);
69
+ }
70
+ });
71
+ return names;
72
+ }
73
+ function classHasCmpDef(classNode) {
74
+ let found = false;
75
+ walk(classNode, (node) => {
76
+ if (found) return;
77
+ if (node.type === "PropertyDefinition" && node.static === true && isNode(node.key) && node.key.name === "ɵcmp") {
78
+ found = true;
79
+ return;
80
+ }
81
+ if (node.type === "AssignmentExpression" && isNode(node.left) && node.left.type === "MemberExpression" && isNode(node.left.property) && node.left.property.name === "ɵcmp" && isNode(node.left.object) && node.left.object.type === "ThisExpression") found = true;
82
+ });
83
+ return found;
84
+ }
85
+ function isNode(v) {
86
+ return v != null && typeof v === "object" && "type" in v;
87
+ }
88
+ function walk(node, visitor) {
89
+ visitor(node);
90
+ for (const key of Object.keys(node)) {
91
+ const child = node[key];
92
+ if (Array.isArray(child)) {
93
+ for (const item of child) if (isNode(item)) walk(item, visitor);
94
+ } else if (isNode(child)) walk(child, visitor);
95
+ }
96
+ }
97
+ //#endregion
98
+ export { i18nComponentRegistryPlugin };
99
+
100
+ //# sourceMappingURL=i18n-component-registry-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n-component-registry-plugin.js","names":[],"sources":["../../../src/lib/i18n-component-registry-plugin.ts"],"sourcesContent":["import type { Plugin, TransformResult } from 'vite';\nimport MagicString from 'magic-string';\n\n/**\n * Vite plugin that instruments compiled Angular component definitions with\n * calls to `registerI18nComponentDef()` from `@analogjs/router`. This\n * populates a process-level registry of component definitions that the\n * server renderer uses to null cached `tView` objects between SSR requests,\n * allowing `$localize` tagged templates in `consts()` to re-evaluate with\n * the freshly loaded translations for each request's locale.\n *\n * The plugin runs in `enforce: 'post'` so that it sees the compiled\n * JavaScript output from the Angular compiler (which contains the\n * `ClassName.ɵcmp = ɵɵdefineComponent({...})` assignments).\n *\n * Only active when the platform's `i18n` option is configured.\n * Only transforms modules loaded for the SSR environment.\n */\nexport function i18nComponentRegistryPlugin(): Plugin {\n return {\n name: 'analogjs-i18n-component-registry',\n enforce: 'post',\n\n transform(code, id, options): TransformResult | undefined {\n if (!options?.ssr) return;\n if (!code.includes('.ɵcmp')) return;\n if (id.includes('node_modules')) return;\n if (!id.match(/\\.(ts|js)(\\?|$)/)) return;\n\n const ast = this.parse(code) as unknown as AstNode;\n const classNames = findComponentClassNames(ast);\n\n if (classNames.size === 0) return;\n\n const registrations = [...classNames]\n .map((name) => `__analog_i18n_reg(${name});`)\n .join('\\n');\n\n // Use MagicString so the source map stays aligned with the original\n // file — prepended imports and appended registration calls must not\n // shift line numbers for frames that land inside the user's code.\n const s = new MagicString(code);\n s.prepend(\n `import { ɵregisterI18nComponentDef as __analog_i18n_reg } from '@analogjs/router';\\n`,\n );\n s.append(`\\n${registrations}\\n`);\n\n return {\n code: s.toString(),\n map: s.generateMap({\n hires: true,\n source: id,\n includeContent: true,\n }) as TransformResult['map'],\n };\n },\n };\n}\n\n// Minimal ESTree node shape used by the walker.\ninterface AstNode {\n type: string;\n [key: string]: unknown;\n}\n\n/**\n * Walks the AST to find class names whose definitions include a `ɵcmp`\n * static property assignment — the marker Angular uses for compiled\n * component definitions.\n *\n * Handles two codegen styles:\n *\n * Production (tree-shaken):\n * _ClassName.ɵcmp = ɵɵdefineComponent({...})\n * → AssignmentExpression left: MemberExpression(.ɵcmp) object: Identifier\n *\n * Dev mode (class fields):\n * class Foo { static { this.ɵcmp = i0.ɵɵdefineComponent({...}) } }\n * → ClassDeclaration → StaticBlock → AssignmentExpression left: MemberExpression(.ɵcmp) object: ThisExpression\n */\nfunction findComponentClassNames(ast: AstNode): Set<string> {\n const names = new Set<string>();\n\n walk(ast, (node: any) => {\n // Prod: top-level `Identifier.ɵcmp = ...`\n if (\n node.type === 'AssignmentExpression' &&\n isNode(node.left) &&\n node.left.type === 'MemberExpression' &&\n isNode(node.left.property) &&\n (node.left.property as AstNode & { name?: string }).name === 'ɵcmp' &&\n isNode(node.left.object) &&\n node.left.object.type === 'Identifier'\n ) {\n const name = (node.left.object as AstNode & { name: string }).name;\n if (name !== 'this') {\n names.add(name);\n }\n }\n\n // Dev: ClassDeclaration containing `this.ɵcmp = ...` in a static block\n if (\n (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') &&\n isNode(node.id) &&\n (node.id as AstNode & { name?: string }).name\n ) {\n const className = (node.id as AstNode & { name: string }).name;\n if (classHasCmpDef(node)) {\n names.add(className);\n }\n }\n });\n\n return names;\n}\n\nfunction classHasCmpDef(classNode: AstNode): boolean {\n let found = false;\n\n walk(classNode, (node: any) => {\n if (found) return;\n\n // static ɵcmp = ... (PropertyDefinition)\n if (\n node.type === 'PropertyDefinition' &&\n node.static === true &&\n isNode(node.key) &&\n (node.key as AstNode & { name?: string }).name === 'ɵcmp'\n ) {\n found = true;\n return;\n }\n\n // static { this.ɵcmp = ... }\n if (\n node.type === 'AssignmentExpression' &&\n isNode(node.left) &&\n node.left.type === 'MemberExpression' &&\n isNode(node.left.property) &&\n (node.left.property as AstNode & { name?: string }).name === 'ɵcmp' &&\n isNode(node.left.object) &&\n node.left.object.type === 'ThisExpression'\n ) {\n found = true;\n }\n });\n\n return found;\n}\n\nfunction isNode(v: unknown): v is AstNode {\n return v != null && typeof v === 'object' && 'type' in (v as object);\n}\n\nfunction walk(node: AstNode, visitor: (n: AstNode) => void): void {\n visitor(node);\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (isNode(item)) walk(item, visitor);\n }\n } else if (isNode(child)) {\n walk(child, visitor);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,SAAgB,8BAAsC;AACpD,QAAO;EACL,MAAM;EACN,SAAS;EAET,UAAU,MAAM,IAAI,SAAsC;AACxD,OAAI,CAAC,SAAS,IAAK;AACnB,OAAI,CAAC,KAAK,SAAS,QAAQ,CAAE;AAC7B,OAAI,GAAG,SAAS,eAAe,CAAE;AACjC,OAAI,CAAC,GAAG,MAAM,kBAAkB,CAAE;GAGlC,MAAM,aAAa,wBADP,KAAK,MAAM,KAAK,CACmB;AAE/C,OAAI,WAAW,SAAS,EAAG;GAE3B,MAAM,gBAAgB,CAAC,GAAG,WAAW,CAClC,KAAK,SAAS,qBAAqB,KAAK,IAAI,CAC5C,KAAK,KAAK;GAKb,MAAM,IAAI,IAAI,YAAY,KAAK;AAC/B,KAAE,QACA,uFACD;AACD,KAAE,OAAO,KAAK,cAAc,IAAI;AAEhC,UAAO;IACL,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,YAAY;KACjB,OAAO;KACP,QAAQ;KACR,gBAAgB;KACjB,CAAC;IACH;;EAEJ;;;;;;;;;;;;;;;;;AAwBH,SAAS,wBAAwB,KAA2B;CAC1D,MAAM,wBAAQ,IAAI,KAAa;AAE/B,MAAK,MAAM,SAAc;AAEvB,MACE,KAAK,SAAS,0BACd,OAAO,KAAK,KAAK,IACjB,KAAK,KAAK,SAAS,sBACnB,OAAO,KAAK,KAAK,SAAS,IACzB,KAAK,KAAK,SAAyC,SAAS,UAC7D,OAAO,KAAK,KAAK,OAAO,IACxB,KAAK,KAAK,OAAO,SAAS,cAC1B;GACA,MAAM,OAAQ,KAAK,KAAK,OAAsC;AAC9D,OAAI,SAAS,OACX,OAAM,IAAI,KAAK;;AAKnB,OACG,KAAK,SAAS,sBAAsB,KAAK,SAAS,sBACnD,OAAO,KAAK,GAAG,IACd,KAAK,GAAmC,MACzC;GACA,MAAM,YAAa,KAAK,GAAkC;AAC1D,OAAI,eAAe,KAAK,CACtB,OAAM,IAAI,UAAU;;GAGxB;AAEF,QAAO;;AAGT,SAAS,eAAe,WAA6B;CACnD,IAAI,QAAQ;AAEZ,MAAK,YAAY,SAAc;AAC7B,MAAI,MAAO;AAGX,MACE,KAAK,SAAS,wBACd,KAAK,WAAW,QAChB,OAAO,KAAK,IAAI,IACf,KAAK,IAAoC,SAAS,QACnD;AACA,WAAQ;AACR;;AAIF,MACE,KAAK,SAAS,0BACd,OAAO,KAAK,KAAK,IACjB,KAAK,KAAK,SAAS,sBACnB,OAAO,KAAK,KAAK,SAAS,IACzB,KAAK,KAAK,SAAyC,SAAS,UAC7D,OAAO,KAAK,KAAK,OAAO,IACxB,KAAK,KAAK,OAAO,SAAS,iBAE1B,SAAQ;GAEV;AAEF,QAAO;;AAGT,SAAS,OAAO,GAA0B;AACxC,QAAO,KAAK,QAAQ,OAAO,MAAM,YAAY,UAAW;;AAG1D,SAAS,KAAK,MAAe,SAAqC;AAChE,SAAQ,KAAK;AACb,MAAK,MAAM,OAAO,OAAO,KAAK,KAAK,EAAE;EACnC,MAAM,QAAQ,KAAK;AACnB,MAAI,MAAM,QAAQ,MAAM;QACjB,MAAM,QAAQ,MACjB,KAAI,OAAO,KAAK,CAAE,MAAK,MAAM,QAAQ;aAE9B,OAAO,MAAM,CACtB,MAAK,OAAO,QAAQ"}
@@ -0,0 +1,33 @@
1
+ import { Plugin } from "vite";
2
+ import { I18nOptions } from "./options.js";
3
+ /**
4
+ * Vite plugin that extracts i18n messages from compiled JavaScript output.
5
+ *
6
+ * After the client build completes, this plugin scans all `.js` files in the
7
+ * output directory for `$localize` tagged template literals and extracts the
8
+ * message IDs and source text. It then writes the extracted messages to a
9
+ * translation source file.
10
+ *
11
+ * Uses `@angular/localize/tools` MessageExtractor when available,
12
+ * falling back to a regex-based extractor.
13
+ */
14
+ export declare function i18nExtractPlugin(i18nOptions: I18nOptions): Plugin;
15
+ export interface ExtractedMessage {
16
+ id: string;
17
+ text: string;
18
+ description?: string;
19
+ }
20
+ /**
21
+ * Regex-based fallback extractor for when @angular/localize/tools is not available.
22
+ *
23
+ * Parses `$localize` tagged template literals to extract message IDs and text.
24
+ * Handles the common forms:
25
+ * $localize`:@@messageId:text`
26
+ * $localize`:description@@messageId:text`
27
+ * $localize`text`
28
+ */
29
+ export declare function extractWithRegex(files: string[]): ExtractedMessage[];
30
+ /**
31
+ * Serializes extracted messages into the specified format.
32
+ */
33
+ export declare function serializeMessages(messages: ExtractedMessage[], format: string, sourceLocale: string): string;
@@ -0,0 +1,17 @@
1
+ export interface InjectServerFnIdsResult {
2
+ code: string;
3
+ ids: {
4
+ name: string;
5
+ id: string;
6
+ }[];
7
+ }
8
+ /**
9
+ * Server/SSR-build transform: injects the derived `id` into each
10
+ * `export const NAME = serverFn(config, handler)` so the function registers
11
+ * under the same opaque id the client proxy dispatches to. Unlike the client
12
+ * scrub this keeps the handler and every other statement intact — it only edits
13
+ * the config object — so the server module still runs the real implementation.
14
+ *
15
+ * Returns `null` when the module defines no server function.
16
+ */
17
+ export declare function injectServerFnIds(code: string, fileId: string): InjectServerFnIdsResult | null;