@jasonshimmy/vite-plugin-cer-app 0.23.2 → 0.24.0

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 (392) hide show
  1. package/dist/cli/checks/lighthouse.d.ts +26 -0
  2. package/dist/cli/checks/lighthouse.d.ts.map +1 -0
  3. package/dist/cli/checks/lighthouse.js +121 -0
  4. package/dist/cli/checks/lighthouse.js.map +1 -0
  5. package/dist/cli/checks/links.d.ts +12 -0
  6. package/dist/cli/checks/links.d.ts.map +1 -0
  7. package/dist/cli/checks/links.js +89 -0
  8. package/dist/cli/checks/links.js.map +1 -0
  9. package/dist/cli/checks/performance.d.ts +17 -0
  10. package/dist/cli/checks/performance.d.ts.map +1 -0
  11. package/dist/cli/checks/performance.js +61 -0
  12. package/dist/cli/checks/performance.js.map +1 -0
  13. package/dist/cli/commands/check.d.ts +3 -0
  14. package/dist/cli/commands/check.d.ts.map +1 -0
  15. package/dist/cli/commands/check.js +85 -0
  16. package/dist/cli/commands/check.js.map +1 -0
  17. package/dist/cli/create/index.d.ts +11 -1
  18. package/dist/cli/create/index.d.ts.map +1 -1
  19. package/dist/cli/create/index.js +135 -65
  20. package/dist/cli/create/index.js.map +1 -1
  21. package/dist/cli/create/templates/spa/package.json.tpl +5 -3
  22. package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
  23. package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
  24. package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
  25. package/dist/cli/index.js +2 -0
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/index.d.ts +3 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/plugin/build-ssg.d.ts +22 -6
  30. package/dist/plugin/build-ssg.d.ts.map +1 -1
  31. package/dist/plugin/build-ssg.js +227 -17
  32. package/dist/plugin/build-ssg.js.map +1 -1
  33. package/dist/plugin/content/parser.d.ts.map +1 -1
  34. package/dist/plugin/content/parser.js +54 -10
  35. package/dist/plugin/content/parser.js.map +1 -1
  36. package/dist/plugin/dev-server.d.ts +4 -1
  37. package/dist/plugin/dev-server.d.ts.map +1 -1
  38. package/dist/plugin/dev-server.js.map +1 -1
  39. package/dist/plugin/dts-generator.d.ts.map +1 -1
  40. package/dist/plugin/dts-generator.js +50 -8
  41. package/dist/plugin/dts-generator.js.map +1 -1
  42. package/dist/plugin/generated-dir.d.ts +2 -0
  43. package/dist/plugin/generated-dir.d.ts.map +1 -1
  44. package/dist/plugin/generated-dir.js +17 -6
  45. package/dist/plugin/generated-dir.js.map +1 -1
  46. package/dist/plugin/html-post-process.d.ts +6 -0
  47. package/dist/plugin/html-post-process.d.ts.map +1 -1
  48. package/dist/plugin/html-post-process.js +24 -0
  49. package/dist/plugin/html-post-process.js.map +1 -1
  50. package/dist/plugin/index.d.ts.map +1 -1
  51. package/dist/plugin/index.js +60 -13
  52. package/dist/plugin/index.js.map +1 -1
  53. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  54. package/dist/plugin/transforms/auto-import.js +7 -0
  55. package/dist/plugin/transforms/auto-import.js.map +1 -1
  56. package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
  57. package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
  58. package/dist/plugin/transforms/prune-runtime-css.js +40 -0
  59. package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
  60. package/dist/runtime/app-template.d.ts +1 -1
  61. package/dist/runtime/app-template.d.ts.map +1 -1
  62. package/dist/runtime/app-template.js +206 -36
  63. package/dist/runtime/app-template.js.map +1 -1
  64. package/dist/runtime/composables/index.d.ts +4 -0
  65. package/dist/runtime/composables/index.d.ts.map +1 -1
  66. package/dist/runtime/composables/index.js +2 -0
  67. package/dist/runtime/composables/index.js.map +1 -1
  68. package/dist/runtime/composables/use-active-headings.d.ts +24 -0
  69. package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
  70. package/dist/runtime/composables/use-active-headings.js +112 -0
  71. package/dist/runtime/composables/use-active-headings.js.map +1 -0
  72. package/dist/runtime/composables/use-content-page.d.ts +45 -0
  73. package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
  74. package/dist/runtime/composables/use-content-page.js +179 -0
  75. package/dist/runtime/composables/use-content-page.js.map +1 -0
  76. package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
  77. package/dist/runtime/composables/use-content-search.js +1 -5
  78. package/dist/runtime/composables/use-content-search.js.map +1 -1
  79. package/dist/runtime/composables/use-fetch.d.ts +2 -1
  80. package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
  81. package/dist/runtime/composables/use-fetch.js +112 -43
  82. package/dist/runtime/composables/use-fetch.js.map +1 -1
  83. package/dist/runtime/composables/use-route.d.ts.map +1 -1
  84. package/dist/runtime/composables/use-route.js +39 -11
  85. package/dist/runtime/composables/use-route.js.map +1 -1
  86. package/dist/runtime/content/client.js +2 -2
  87. package/dist/runtime/content/client.js.map +1 -1
  88. package/dist/runtime/entry-server-template.d.ts +16 -1
  89. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  90. package/dist/runtime/entry-server-template.js +120 -13
  91. package/dist/runtime/entry-server-template.js.map +1 -1
  92. package/dist/types/config.d.ts +45 -4
  93. package/dist/types/config.d.ts.map +1 -1
  94. package/dist/types/config.js.map +1 -1
  95. package/dist/types/middleware.d.ts +2 -2
  96. package/dist/types/middleware.d.ts.map +1 -1
  97. package/package.json +22 -19
  98. package/.github/copilot-instructions.md +0 -169
  99. package/.github/workflows/publish.yml +0 -257
  100. package/.nvmrc +0 -1
  101. package/CHANGELOG.md +0 -236
  102. package/CLAUDE.md +0 -113
  103. package/commits.txt +0 -1
  104. package/cypress.config.ts +0 -16
  105. package/docs/authentication.md +0 -285
  106. package/docs/cli.md +0 -324
  107. package/docs/components.md +0 -237
  108. package/docs/composables.md +0 -907
  109. package/docs/configuration.md +0 -696
  110. package/docs/content.md +0 -570
  111. package/docs/data-loading.md +0 -336
  112. package/docs/getting-started.md +0 -237
  113. package/docs/head-management.md +0 -212
  114. package/docs/i18n.md +0 -159
  115. package/docs/layouts.md +0 -224
  116. package/docs/middleware.md +0 -234
  117. package/docs/plugins.md +0 -170
  118. package/docs/rendering-modes.md +0 -377
  119. package/docs/routing.md +0 -485
  120. package/docs/server-api.md +0 -253
  121. package/docs/testing.md +0 -455
  122. package/docs/use-fetch.md +0 -183
  123. package/e2e/cypress/e2e/api.cy.ts +0 -123
  124. package/e2e/cypress/e2e/async-component.cy.ts +0 -27
  125. package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
  126. package/e2e/cypress/e2e/content.cy.ts +0 -425
  127. package/e2e/cypress/e2e/cookie.cy.ts +0 -85
  128. package/e2e/cypress/e2e/data.cy.ts +0 -158
  129. package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
  130. package/e2e/cypress/e2e/fouc.cy.ts +0 -254
  131. package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
  132. package/e2e/cypress/e2e/head.cy.ts +0 -89
  133. package/e2e/cypress/e2e/i18n.cy.ts +0 -79
  134. package/e2e/cypress/e2e/interactive.cy.ts +0 -137
  135. package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
  136. package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
  137. package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
  138. package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
  139. package/e2e/cypress/e2e/middleware.cy.ts +0 -45
  140. package/e2e/cypress/e2e/navigate.cy.ts +0 -39
  141. package/e2e/cypress/e2e/observability.cy.ts +0 -77
  142. package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
  143. package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
  144. package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
  145. package/e2e/cypress/e2e/routes.cy.ts +0 -128
  146. package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
  147. package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
  148. package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
  149. package/e2e/cypress/e2e/session.cy.ts +0 -73
  150. package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
  151. package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
  152. package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
  153. package/e2e/cypress/e2e/use-state.cy.ts +0 -138
  154. package/e2e/cypress/support/commands.ts +0 -120
  155. package/e2e/cypress/support/e2e.ts +0 -10
  156. package/e2e/cypress/tsconfig.json +0 -14
  157. package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
  158. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
  159. package/e2e/kitchen-sink/app/error.ts +0 -18
  160. package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
  161. package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
  162. package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
  163. package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
  164. package/e2e/kitchen-sink/app/loading.ts +0 -9
  165. package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
  166. package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
  167. package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
  168. package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
  169. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
  170. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
  171. package/e2e/kitchen-sink/app/pages/404.ts +0 -9
  172. package/e2e/kitchen-sink/app/pages/about.ts +0 -17
  173. package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
  174. package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
  175. package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
  176. package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
  177. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
  178. package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
  179. package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
  180. package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
  181. package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
  182. package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
  183. package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
  184. package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
  185. package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
  186. package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
  187. package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
  188. package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
  189. package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
  190. package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
  191. package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
  192. package/e2e/kitchen-sink/app/pages/head.ts +0 -20
  193. package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
  194. package/e2e/kitchen-sink/app/pages/index.ts +0 -27
  195. package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
  196. package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
  197. package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
  198. package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
  199. package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
  200. package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
  201. package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
  202. package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
  203. package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
  204. package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
  205. package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
  206. package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
  207. package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
  208. package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
  209. package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
  210. package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
  211. package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
  212. package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
  213. package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
  214. package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
  215. package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
  216. package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
  217. package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
  218. package/e2e/kitchen-sink/cer-env.d.ts +0 -35
  219. package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
  220. package/e2e/kitchen-sink/cer.config.ts +0 -43
  221. package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
  222. package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
  223. package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
  224. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
  225. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
  226. package/e2e/kitchen-sink/content/blog/index.md +0 -8
  227. package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
  228. package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
  229. package/e2e/kitchen-sink/content/index.md +0 -16
  230. package/e2e/kitchen-sink/server/api/echo.ts +0 -12
  231. package/e2e/kitchen-sink/server/api/health.ts +0 -3
  232. package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
  233. package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
  234. package/e2e/kitchen-sink/server/api/session.ts +0 -23
  235. package/e2e/kitchen-sink/server/data/posts.ts +0 -21
  236. package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
  237. package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
  238. package/e2e/kitchen-sink/tsconfig.json +0 -3
  239. package/e2e/scripts/clean.mjs +0 -14
  240. package/eslint.config.ts +0 -22
  241. package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
  242. package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
  243. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
  244. package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
  245. package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
  246. package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
  247. package/src/__tests__/cli/preview-hardening.test.ts +0 -265
  248. package/src/__tests__/cli/preview-isr.test.ts +0 -320
  249. package/src/__tests__/index.test.ts +0 -21
  250. package/src/__tests__/plugin/app-template.test.ts +0 -166
  251. package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
  252. package/src/__tests__/plugin/build-ssg.test.ts +0 -598
  253. package/src/__tests__/plugin/build-ssr.test.ts +0 -192
  254. package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
  255. package/src/__tests__/plugin/content/emitter.test.ts +0 -117
  256. package/src/__tests__/plugin/content/loader.test.ts +0 -154
  257. package/src/__tests__/plugin/content/parser.test.ts +0 -381
  258. package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
  259. package/src/__tests__/plugin/content/search.test.ts +0 -119
  260. package/src/__tests__/plugin/dev-server.test.ts +0 -813
  261. package/src/__tests__/plugin/dts-generator.test.ts +0 -394
  262. package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
  263. package/src/__tests__/plugin/generated-dir.test.ts +0 -144
  264. package/src/__tests__/plugin/html-post-process.test.ts +0 -146
  265. package/src/__tests__/plugin/path-utils.test.ts +0 -411
  266. package/src/__tests__/plugin/resolve-config.test.ts +0 -233
  267. package/src/__tests__/plugin/scanner.test.ts +0 -186
  268. package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
  269. package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
  270. package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
  271. package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
  272. package/src/__tests__/plugin/virtual/error.test.ts +0 -71
  273. package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
  274. package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
  275. package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
  276. package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
  277. package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
  278. package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
  279. package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
  280. package/src/__tests__/runtime/app-template.test.ts +0 -208
  281. package/src/__tests__/runtime/define-middleware.test.ts +0 -64
  282. package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
  283. package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
  284. package/src/__tests__/runtime/isr-handler.test.ts +0 -338
  285. package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
  286. package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
  287. package/src/__tests__/runtime/oauth-index.test.ts +0 -43
  288. package/src/__tests__/runtime/use-auth.test.ts +0 -169
  289. package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
  290. package/src/__tests__/runtime/use-content-search.test.ts +0 -163
  291. package/src/__tests__/runtime/use-content.test.ts +0 -226
  292. package/src/__tests__/runtime/use-cookie.test.ts +0 -277
  293. package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
  294. package/src/__tests__/runtime/use-fetch.test.ts +0 -377
  295. package/src/__tests__/runtime/use-head.test.ts +0 -311
  296. package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
  297. package/src/__tests__/runtime/use-inject.test.ts +0 -66
  298. package/src/__tests__/runtime/use-locale.test.ts +0 -152
  299. package/src/__tests__/runtime/use-navigate.test.ts +0 -121
  300. package/src/__tests__/runtime/use-page-data.test.ts +0 -298
  301. package/src/__tests__/runtime/use-route.test.ts +0 -156
  302. package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
  303. package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
  304. package/src/__tests__/runtime/use-session.test.ts +0 -320
  305. package/src/__tests__/runtime/use-state.test.ts +0 -340
  306. package/src/__tests__/types/config.test.ts +0 -18
  307. package/src/cli/adapters/cloudflare.ts +0 -335
  308. package/src/cli/adapters/netlify.ts +0 -326
  309. package/src/cli/adapters/vercel.ts +0 -311
  310. package/src/cli/commands/adapt.ts +0 -84
  311. package/src/cli/commands/build.ts +0 -165
  312. package/src/cli/commands/dev.ts +0 -125
  313. package/src/cli/commands/generate.ts +0 -91
  314. package/src/cli/commands/preview-isr.ts +0 -172
  315. package/src/cli/commands/preview.ts +0 -523
  316. package/src/cli/create/index.ts +0 -275
  317. package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
  318. package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
  319. package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
  320. package/src/cli/create/templates/shared/index.html.tpl +0 -12
  321. package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
  322. package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
  323. package/src/cli/create/templates/spa/package.json.tpl +0 -18
  324. package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
  325. package/src/cli/create/templates/ssg/package.json.tpl +0 -19
  326. package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
  327. package/src/cli/create/templates/ssr/package.json.tpl +0 -18
  328. package/src/cli/index.ts +0 -22
  329. package/src/index.ts +0 -20
  330. package/src/plugin/build-ssg.ts +0 -403
  331. package/src/plugin/build-ssr.ts +0 -134
  332. package/src/plugin/content/emitter.ts +0 -50
  333. package/src/plugin/content/index.ts +0 -233
  334. package/src/plugin/content/parser.ts +0 -259
  335. package/src/plugin/content/path-utils.ts +0 -55
  336. package/src/plugin/content/scanner.ts +0 -26
  337. package/src/plugin/content/search.ts +0 -28
  338. package/src/plugin/dev-server.ts +0 -379
  339. package/src/plugin/dts-generator.ts +0 -273
  340. package/src/plugin/generated-dir.ts +0 -121
  341. package/src/plugin/html-post-process.ts +0 -96
  342. package/src/plugin/index.ts +0 -584
  343. package/src/plugin/path-utils.ts +0 -186
  344. package/src/plugin/scanner.ts +0 -65
  345. package/src/plugin/transforms/auto-import.ts +0 -206
  346. package/src/plugin/transforms/head-inject.ts +0 -161
  347. package/src/plugin/virtual/composables.ts +0 -28
  348. package/src/plugin/virtual/content-components.ts +0 -83
  349. package/src/plugin/virtual/error.ts +0 -34
  350. package/src/plugin/virtual/layouts.ts +0 -41
  351. package/src/plugin/virtual/loading.ts +0 -32
  352. package/src/plugin/virtual/middleware.ts +0 -45
  353. package/src/plugin/virtual/plugins.ts +0 -46
  354. package/src/plugin/virtual/routes.ts +0 -514
  355. package/src/plugin/virtual/server-api.ts +0 -85
  356. package/src/plugin/virtual/server-middleware.ts +0 -44
  357. package/src/runtime/app-template.ts +0 -377
  358. package/src/runtime/composables/define-middleware.ts +0 -17
  359. package/src/runtime/composables/define-server-middleware.ts +0 -18
  360. package/src/runtime/composables/index.ts +0 -27
  361. package/src/runtime/composables/use-auth.ts +0 -125
  362. package/src/runtime/composables/use-content-search.ts +0 -205
  363. package/src/runtime/composables/use-content.ts +0 -146
  364. package/src/runtime/composables/use-cookie.ts +0 -135
  365. package/src/runtime/composables/use-fetch.ts +0 -438
  366. package/src/runtime/composables/use-head.ts +0 -234
  367. package/src/runtime/composables/use-inject.ts +0 -49
  368. package/src/runtime/composables/use-locale.ts +0 -109
  369. package/src/runtime/composables/use-navigate.ts +0 -58
  370. package/src/runtime/composables/use-page-data.ts +0 -93
  371. package/src/runtime/composables/use-route.ts +0 -71
  372. package/src/runtime/composables/use-runtime-config.ts +0 -123
  373. package/src/runtime/composables/use-seo-meta.ts +0 -80
  374. package/src/runtime/composables/use-session.ts +0 -186
  375. package/src/runtime/composables/use-state.ts +0 -92
  376. package/src/runtime/content/client.ts +0 -168
  377. package/src/runtime/entry-client-template.ts +0 -39
  378. package/src/runtime/entry-server-template.ts +0 -493
  379. package/src/runtime/isr-handler.ts +0 -184
  380. package/src/runtime/oauth/handler.ts +0 -407
  381. package/src/runtime/oauth/index.ts +0 -49
  382. package/src/runtime/oauth/providers.ts +0 -38
  383. package/src/types/api.ts +0 -40
  384. package/src/types/config.ts +0 -379
  385. package/src/types/content.ts +0 -66
  386. package/src/types/index.ts +0 -7
  387. package/src/types/middleware.ts +0 -63
  388. package/src/types/page.ts +0 -117
  389. package/src/types/plugin.ts +0 -34
  390. package/tsconfig.build.json +0 -10
  391. package/tsconfig.json +0 -19
  392. package/vitest.config.ts +0 -33
@@ -1,403 +0,0 @@
1
- import { writeFile, mkdir, readFile } from 'node:fs/promises'
2
- import { existsSync } from 'node:fs'
3
- import { join } from 'pathe'
4
- import {
5
- injectFaviconLink,
6
- injectCanonicalLink,
7
- addNoopenerToExternalLinks,
8
- generateRobotsTxt,
9
- } from './html-post-process.js'
10
- import { createServer, type UserConfig } from 'vite'
11
- import type { ResolvedCerConfig } from './dev-server.js'
12
- import type { ContentItem } from '../types/content.js'
13
- import { buildSSR } from './build-ssr.js'
14
- import { buildRouteEntry } from './path-utils.js'
15
- import fg from 'fast-glob'
16
-
17
- interface SsgManifest {
18
- generatedAt: string
19
- paths: string[]
20
- errors: Array<{ path: string; error: string }>
21
- }
22
-
23
- const CONTENT_STORE_KEY = '__CER_CONTENT_STORE__'
24
-
25
-
26
- /**
27
- * Collects all static paths to generate.
28
- * For 'auto' mode: scans app/pages/ and collects only static (non-dynamic) routes
29
- * plus any dynamic routes that provide ssg.paths().
30
- * For explicit string[] mode: uses those paths directly.
31
- */
32
- /**
33
- * Expands a set of base paths into locale-prefixed variants when i18n is
34
- * configured. Skips expansion for `no_prefix` strategy.
35
- */
36
- function _expandWithLocales(
37
- paths: string[],
38
- i18n: ResolvedCerConfig['i18n'],
39
- ): string[] {
40
- if (!i18n || i18n.strategy === 'no_prefix') return paths
41
- const { locales, defaultLocale, strategy } = i18n
42
- const expanded: string[] = []
43
- for (const p of paths) {
44
- for (const locale of locales) {
45
- const isDefault = locale === defaultLocale
46
- if (isDefault && strategy === 'prefix_except_default') {
47
- expanded.push(p)
48
- } else {
49
- expanded.push(`/${locale}${p === '/' ? '' : p}`)
50
- }
51
- }
52
- }
53
- return [...new Set(expanded)]
54
- }
55
-
56
- async function collectSsgPaths(
57
- config: ResolvedCerConfig,
58
- viteUserConfig: UserConfig,
59
- ): Promise<string[]> {
60
- const ssgConfig = config.ssg
61
-
62
- if (Array.isArray(ssgConfig.routes) && ssgConfig.routes.length > 0) {
63
- return _expandWithLocales(ssgConfig.routes, config.i18n)
64
- }
65
-
66
- // Auto-discover paths
67
- const paths: string[] = ['/']
68
-
69
- if (!existsSync(config.pagesDir)) return paths
70
-
71
- const files = await fg('**/*.ts', {
72
- cwd: config.pagesDir,
73
- absolute: true,
74
- onlyFiles: true,
75
- })
76
-
77
- const staticFiles: string[] = []
78
- const dynamicFiles: Array<{
79
- file: string
80
- entry: ReturnType<typeof buildRouteEntry>
81
- usesQueryContent: boolean
82
- }> = []
83
-
84
- for (const file of files) {
85
- // Skip routes that declare render: 'server' or render: 'spa' — they are
86
- // either always-SSR or client-only and must not be pre-rendered.
87
- let src = ''
88
- try {
89
- src = await readFile(file, 'utf-8')
90
- const renderMatch = src.match(/render\s*:\s*['"]([^'"]+)['"]/)
91
- const renderMode = renderMatch ? renderMatch[1] : null
92
- if (renderMode === 'server' || renderMode === 'spa') continue
93
- } catch { /* ignore read errors */ }
94
-
95
- const entry = buildRouteEntry(file, config.pagesDir)
96
- const usesQueryContent = /\bqueryContent\s*\(/.test(src)
97
-
98
- if (!entry.isDynamic && !entry.isCatchAll) {
99
- staticFiles.push(file)
100
- if (entry.routePath !== '/') {
101
- paths.push(entry.routePath)
102
- }
103
- } else if (entry.isDynamic) {
104
- dynamicFiles.push({ file, entry, usesQueryContent })
105
- }
106
- }
107
-
108
- if (dynamicFiles.length > 0) {
109
- // Use a Vite SSR dev server to load page modules with auto-imports applied
110
- const viteServer = await createServer({
111
- ...viteUserConfig,
112
- root: config.root,
113
- server: { middlewareMode: true },
114
- appType: 'custom',
115
- logLevel: 'silent',
116
- })
117
-
118
- try {
119
- for (const { file, entry, usesQueryContent } of dynamicFiles) {
120
- try {
121
- const pageMod = await viteServer.ssrLoadModule(file)
122
- const pageMeta = pageMod.meta ?? pageMod.pageMeta
123
-
124
- if (pageMeta?.render === 'server' || pageMeta?.render === 'spa') continue
125
- if (pageMeta?.ssg?.paths) {
126
- const pathsResult = await pageMeta.ssg.paths()
127
- for (const ctx of pathsResult) {
128
- let resolvedPath = entry.routePath
129
- for (const [key, value] of Object.entries(ctx.params as Record<string, unknown>)) {
130
- resolvedPath = resolvedPath.replace(`:${key}*`, String(value))
131
- resolvedPath = resolvedPath.replace(`:${key}`, String(value))
132
- }
133
- paths.push(resolvedPath)
134
- }
135
- continue
136
- }
137
-
138
- if (entry.isCatchAll && usesQueryContent) {
139
- const contentStore = (globalThis as Record<string, unknown>)[CONTENT_STORE_KEY] as ContentItem[] | undefined
140
- const catchAllPaths = _collectCatchAllContentPaths(entry.routePath, contentStore ?? [])
141
- paths.push(...catchAllPaths)
142
- }
143
- } catch {
144
- console.warn(`[cer-app] Could not enumerate paths for ${file}`)
145
- }
146
- }
147
- } finally {
148
- await viteServer.close()
149
- }
150
- }
151
-
152
- // When i18n is configured, expand every collected path into locale-prefixed
153
- // variants so each locale gets its own pre-rendered HTML file.
154
- // strategy 'prefix' → /en/about, /fr/about
155
- // strategy 'prefix_except_default' → /about, /fr/about
156
- // strategy 'no_prefix' → no expansion (locale detected from header/cookie only)
157
- if (config.i18n && config.i18n.strategy !== 'no_prefix') {
158
- const { locales, defaultLocale, strategy } = config.i18n
159
- const expanded: string[] = []
160
- for (const p of paths) {
161
- for (const locale of locales) {
162
- const isDefault = locale === defaultLocale
163
- if (isDefault && strategy === 'prefix_except_default') {
164
- expanded.push(p)
165
- } else {
166
- expanded.push(`/${locale}${p === '/' ? '' : p}`)
167
- }
168
- }
169
- }
170
- return [...new Set(expanded)]
171
- }
172
-
173
- return [...new Set(paths)] // deduplicate
174
- }
175
-
176
- function _collectCatchAllContentPaths(routePath: string, store: ContentItem[]): string[] {
177
- if (store.length === 0) return []
178
-
179
- const prefix = routePath
180
- .replace(/:[^/]+\*$/, '')
181
- .replace(/\/+$/, '') || '/'
182
-
183
- return store
184
- .map((item) => item._path)
185
- .filter((contentPath) => {
186
- if (prefix === '/') return true
187
- return contentPath === prefix || contentPath.startsWith(prefix + '/')
188
- })
189
- }
190
-
191
- // Cache the server module across renderPath calls (loaded once per SSG run)
192
- let _serverMod: Record<string, unknown> | null = null
193
-
194
- /**
195
- * Renders a single path using the SSR server bundle and returns the HTML.
196
- *
197
- * The server bundle's handler already merges the SSR output with
198
- * dist/client/index.html internally (via the _mergeWithClientTemplate helper
199
- * it embeds at build time), so this function simply captures the response.
200
- */
201
- async function renderPath(
202
- path: string,
203
- serverBundlePath: string,
204
- ): Promise<string> {
205
- // Load server bundle once
206
- if (!_serverMod) {
207
- try {
208
- _serverMod = await import(serverBundlePath) as Record<string, unknown>
209
- } catch (err) {
210
- throw new Error(`Failed to load server bundle at ${serverBundlePath}: ${err}`)
211
- }
212
- }
213
-
214
- const handlerFn =
215
- (typeof _serverMod['handler'] === 'function' ? _serverMod['handler'] : null) ??
216
- (typeof (_serverMod['default'] as Record<string, unknown> | undefined)?.['handler'] === 'function'
217
- ? (_serverMod['default'] as Record<string, unknown>)['handler']
218
- : null)
219
-
220
- if (typeof handlerFn !== 'function') {
221
- console.warn(`[cer-app] No handler function found in server bundle for path: ${path}`)
222
- return ''
223
- }
224
-
225
- // Mock req/res for the Express-style handler.
226
- // The handler internally merges with dist/client/index.html, so we just
227
- // capture whatever it writes/ends with.
228
- const mockReq = { url: path, headers: {} }
229
- return new Promise<string>((resolve, reject) => {
230
- const chunks: string[] = []
231
- const mockRes = {
232
- setHeader: () => {},
233
- write: (chunk: string) => { chunks.push(chunk) },
234
- end: (body?: string) => resolve(chunks.join('') + (body ?? '')),
235
- }
236
- ;(handlerFn as (req: unknown, res: unknown) => Promise<void>)(mockReq, mockRes).catch(reject)
237
- })
238
- }
239
-
240
- /**
241
- * Writes the rendered HTML to the output directory.
242
- * path '/' -> dist/index.html
243
- * path '/about' -> dist/about/index.html
244
- * @internal exported for unit testing
245
- */
246
- export async function writeRenderedPath(
247
- path: string,
248
- html: string,
249
- distDir: string,
250
- ): Promise<void> {
251
- let outputPath: string
252
- if (path === '/') {
253
- outputPath = join(distDir, 'index.html')
254
- } else {
255
- // Normalize path and create directory
256
- const cleanPath = path.replace(/^\//, '').replace(/\/$/, '')
257
- outputPath = join(distDir, cleanPath, 'index.html')
258
- }
259
-
260
- await mkdir(join(outputPath, '..'), { recursive: true })
261
- await writeFile(outputPath, html, 'utf-8')
262
- }
263
-
264
- /**
265
- * Detects which favicon href to use from the project's public directory.
266
- * Prefers .svg > .ico > .png. Returns null when none is found.
267
- */
268
- function detectFaviconHref(root: string): string | null {
269
- const candidates = ['/favicon.svg', '/favicon.ico', '/favicon.png']
270
- for (const href of candidates) {
271
- if (existsSync(join(root, 'public', href.slice(1)))) return href
272
- }
273
- return null
274
- }
275
-
276
- /**
277
- * Applies all HTML post-processing transforms to a rendered page.
278
- *
279
- * - Injects `<link rel="icon">` when a favicon exists in public/ and none
280
- * is already declared in the HTML.
281
- * - Injects `<link rel="canonical">` when `config.siteUrl` is set and none
282
- * is already declared.
283
- * - Adds `rel="noopener noreferrer"` to every `<a target="_blank">` link
284
- * that is missing it.
285
- */
286
- function postProcessHtml(
287
- html: string,
288
- path: string,
289
- config: ResolvedCerConfig,
290
- faviconHref: string | null,
291
- ): string {
292
- let out = html
293
-
294
- if (faviconHref) {
295
- out = injectFaviconLink(out, faviconHref)
296
- }
297
-
298
- if (config.siteUrl) {
299
- const canonicalUrl = config.siteUrl + (path === '/' ? '' : path)
300
- out = injectCanonicalLink(out, canonicalUrl)
301
- }
302
-
303
- out = addNoopenerToExternalLinks(out)
304
-
305
- return out
306
- }
307
-
308
- /**
309
- * Full SSG build pipeline:
310
- * 1. Run the SSR dual-build (client + server bundles)
311
- * 2. Enumerate all paths to generate
312
- * 3. Render each path using the server bundle
313
- * 4. Post-process HTML (favicon, canonical, noopener)
314
- * 5. Write HTML files to dist/
315
- * 6. Write robots.txt (when not already present in public/)
316
- * 7. Write ssg-manifest.json
317
- */
318
- export async function buildSSG(
319
- config: ResolvedCerConfig,
320
- viteUserConfig: UserConfig = {},
321
- ): Promise<void> {
322
- const distDir = join(config.root, 'dist')
323
- const serverDistDir = join(distDir, 'server')
324
- const serverBundlePath = join(serverDistDir, 'server.js')
325
-
326
- console.log('[cer-app] Starting SSG build...')
327
-
328
- // Step 1: Run the SSR build to produce client + server bundles
329
- await buildSSR(config, viteUserConfig)
330
-
331
- // Step 2: Collect paths to generate
332
- console.log('[cer-app] Collecting SSG paths...')
333
- const paths = await collectSsgPaths(config, viteUserConfig)
334
- console.log(`[cer-app] Found ${paths.length} path(s) to generate:`, paths)
335
-
336
- // Detect favicon once for use in every page's post-processing pass.
337
- const faviconHref = detectFaviconHref(config.root)
338
-
339
- // Step 3+4+5: Render, post-process, and write paths with bounded concurrency.
340
- // The server bundle uses per-request router instances (initRouter returns the
341
- // router; the factory passes it to createStreamingSSRHandler as { vnode, router })
342
- // so concurrent renders are safe — each request carries its own router with its
343
- // own URL state and never reads from the shared activeRouterProxy singleton.
344
- const concurrency = config.ssg?.concurrency ?? 4
345
- console.log(`[cer-app] Rendering ${paths.length} path(s) with concurrency ${concurrency}...`)
346
-
347
- const generatedPaths: string[] = []
348
- const errors: Array<{ path: string; error: string }> = []
349
-
350
- // Process paths in chunks of `concurrency` so we don't overwhelm the process
351
- // with hundreds of simultaneous renders on very large sites.
352
- for (let i = 0; i < paths.length; i += concurrency) {
353
- const chunk = paths.slice(i, i + concurrency)
354
- const results = await Promise.allSettled(
355
- chunk.map(async (path) => {
356
- console.log(`[cer-app] Generating: ${path}`)
357
- const raw = await renderPath(path, serverBundlePath)
358
- const html = postProcessHtml(raw, path, config, faviconHref)
359
- await writeRenderedPath(path, html, distDir)
360
- return path
361
- }),
362
- )
363
- for (let j = 0; j < results.length; j++) {
364
- const result = results[j]
365
- if (result.status === 'fulfilled') {
366
- generatedPaths.push(result.value)
367
- } else {
368
- const errorMsg = String(result.reason)
369
- console.error(`[cer-app] Failed to generate ${chunk[j]}: ${errorMsg}`)
370
- errors.push({ path: chunk[j], error: errorMsg })
371
- }
372
- }
373
- }
374
-
375
- // Step 6: Write robots.txt unless the project supplies its own via public/robots.txt,
376
- // which Vite copies to dist/ as-is. Always overwrite any previously generated file so
377
- // that siteUrl changes (e.g. adding the Sitemap directive) take effect on rebuild.
378
- const publicRobots = join(config.root, 'public', 'robots.txt')
379
- if (!existsSync(publicRobots)) {
380
- const distRobots = join(distDir, 'robots.txt')
381
- await mkdir(distDir, { recursive: true })
382
- await writeFile(distRobots, generateRobotsTxt(config.siteUrl), 'utf-8')
383
- console.log('[cer-app] Generated robots.txt')
384
- }
385
-
386
- // Step 7: Write SSG manifest
387
- const manifest: SsgManifest = {
388
- generatedAt: new Date().toISOString(),
389
- paths: generatedPaths,
390
- errors,
391
- }
392
-
393
- const manifestPath = join(distDir, 'ssg-manifest.json')
394
- await mkdir(distDir, { recursive: true })
395
- await writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8')
396
-
397
- console.log(`[cer-app] SSG build complete.`)
398
- console.log(` Generated ${generatedPaths.length} page(s).`)
399
- if (errors.length > 0) {
400
- console.warn(` ${errors.length} error(s) — see ${manifestPath} for details.`)
401
- }
402
- console.log(` Manifest: ${manifestPath}`)
403
- }
@@ -1,134 +0,0 @@
1
- import { build, type UserConfig } from 'vite'
2
- import { join, resolve } from 'pathe'
3
- import { existsSync, renameSync } from 'node:fs'
4
- import type { ResolvedCerConfig } from './dev-server.js'
5
- import { getGeneratedDir, writeGeneratedDir } from './generated-dir.js'
6
- import { ENTRY_SERVER_TEMPLATE } from '../runtime/entry-server-template.js'
7
-
8
- /**
9
- * Resolves the client build entry point for an SSR/SSG build.
10
- *
11
- * Priority order:
12
- * 1. `index.html` at the project root — consumer-provided HTML shell.
13
- * 2. `.cer/index.html` — auto-generated HTML shell (Nuxt-style magic).
14
- * 3. `app/entry-client.ts` — fallback for projects that manage HTML externally.
15
- * 4. `app/app.ts` — last resort (same bundle, no DSD hydration preamble).
16
- */
17
- export function resolveClientEntry(config: ResolvedCerConfig): string {
18
- const indexHtml = resolve(config.root, 'index.html')
19
- if (existsSync(indexHtml)) return indexHtml
20
- const cerIndexHtml = join(getGeneratedDir(config.root), 'index.html')
21
- if (existsSync(cerIndexHtml)) return cerIndexHtml
22
- const entryClient = resolve(config.srcDir, 'entry-client.ts')
23
- if (existsSync(entryClient)) return entryClient
24
- return resolve(config.srcDir, 'app.ts')
25
- }
26
-
27
- function generateServerEntryCode(): string {
28
- return ENTRY_SERVER_TEMPLATE
29
- }
30
-
31
- /**
32
- * Runs the dual (client + server) SSR build using Vite's programmatic API.
33
- *
34
- * 1. Client bundle: normal Vite build (outputs to dist/client)
35
- * 2. Server bundle: SSR build (outputs to dist/server), uses a generated entry
36
- */
37
- export async function buildSSR(
38
- config: ResolvedCerConfig,
39
- viteUserConfig: UserConfig = {},
40
- ): Promise<void> {
41
- const clientOutDir = join(config.root, 'dist/client')
42
- const serverOutDir = join(config.root, 'dist/server')
43
-
44
- // Write .cer/ generated files BEFORE resolving the client entry so that
45
- // .cer/index.html is on disk when resolveClientEntry checks for it.
46
- writeGeneratedDir(config)
47
-
48
- // Resolve the client entry — index.html is preferred so Vite writes a
49
- // processed index.html to dist/client/ for use as the SSG shell template.
50
- const clientEntry = resolveClientEntry(config)
51
-
52
- // Build the client bundle
53
- console.log('[cer-app] Building client bundle...')
54
- await build({
55
- ...viteUserConfig,
56
- root: config.root,
57
- build: {
58
- ...viteUserConfig.build,
59
- outDir: clientOutDir,
60
- ssrManifest: true,
61
- rollupOptions: {
62
- input: clientEntry,
63
- },
64
- },
65
- })
66
-
67
- // If the client entry was .cer/index.html, Vite outputs it as
68
- // dist/client/.cer/index.html (preserving relative path). The SSR server
69
- // template expects dist/client/index.html, so rename it into place.
70
- const generatedHtmlOut = join(clientOutDir, '.cer/index.html')
71
- const rootHtmlOut = join(clientOutDir, 'index.html')
72
- if (existsSync(generatedHtmlOut) && !existsSync(rootHtmlOut)) {
73
- renameSync(generatedHtmlOut, rootHtmlOut)
74
- }
75
-
76
- // Generate server entry source inline via a virtual plugin
77
- const serverEntryCode = generateServerEntryCode()
78
- const VIRTUAL_SERVER_ENTRY = 'virtual:cer-server-entry'
79
- const RESOLVED_SERVER_ENTRY = '\0virtual:cer-server-entry'
80
-
81
- // Build the server (SSR) bundle
82
- console.log('[cer-app] Building server bundle...')
83
- await build({
84
- ...viteUserConfig,
85
- root: config.root,
86
- plugins: [
87
- ...(viteUserConfig.plugins ?? []),
88
- {
89
- name: 'vite-plugin-cer-server-entry',
90
- enforce: 'pre' as const,
91
- resolveId(id: string) {
92
- if (id === VIRTUAL_SERVER_ENTRY) return RESOLVED_SERVER_ENTRY
93
- },
94
- load(id: string) {
95
- if (id === RESOLVED_SERVER_ENTRY) return serverEntryCode
96
- },
97
- },
98
- ],
99
- build: {
100
- ...viteUserConfig.build,
101
- outDir: serverOutDir,
102
- ssr: true,
103
- rollupOptions: {
104
- input: VIRTUAL_SERVER_ENTRY,
105
- output: {
106
- entryFileNames: 'server.js',
107
- },
108
- },
109
- },
110
- ssr: {
111
- // Keep vite-plugin-cer-app inlined so its virtual-module composables
112
- // (useRoute, useState, useFetch, etc.) are available in the server bundle.
113
- //
114
- // Do NOT add @jasonshimmy/custom-elements-runtime here. Inlining it
115
- // creates a second, isolated copy of the component registry (the module-
116
- // level Map in namespace-helpers). Third-party CER component libraries
117
- // (e.g. @jasonshimmy/cer-material) are external and resolve the runtime
118
- // from node_modules at runtime, giving them a *different* Map instance.
119
- // That means components registered by plugins never appear in the
120
- // renderer's registry → renderToStreamWithJITCSSDSD emits bare stubs
121
- // with no DSD → FOUC when the browser upgrades those elements.
122
- //
123
- // By keeping the runtime external both the server bundle and all
124
- // third-party plugins resolve it from node_modules at runtime, sharing
125
- // one Map and one registry, so DSD is generated for all registered
126
- // components regardless of which package called component().
127
- noExternal: ['@jasonshimmy/vite-plugin-cer-app'],
128
- },
129
- })
130
-
131
- console.log('[cer-app] SSR build complete.')
132
- console.log(` Client: ${clientOutDir}`)
133
- console.log(` Server: ${serverOutDir}`)
134
- }
@@ -1,50 +0,0 @@
1
- import { writeFileSync, mkdirSync } from 'node:fs'
2
- import { join, dirname } from 'pathe'
3
- import type { ContentItem, ContentMeta } from '../../types/content.js'
4
- import { toContentMeta } from './parser.js'
5
-
6
- /**
7
- * Converts a `_path` to the relative file path under `_content/`.
8
- *
9
- * Special case: `_path === '/'` writes to `_content/index.json` rather than
10
- * `_content/.json` (which would be invalid on most filesystems and confusing).
11
- */
12
- export function contentPathToFile(path: string): string {
13
- if (path === '/') return 'index.json'
14
- // Remove leading slash, append .json
15
- return path.slice(1) + '.json'
16
- }
17
-
18
- /**
19
- * Writes all content output files to `<outDir>/_content/`:
20
- *
21
- * - `manifest.json` — `ContentMeta[]` (no body, no toc, no excerpt)
22
- * - `search-index.json` — serialised MiniSearch index string
23
- * - `[path].json` — full `ContentItem` per document
24
- *
25
- * `router.base` is NOT prepended here — that is a client-side fetch concern.
26
- */
27
- export function emitContentFiles(
28
- items: ContentItem[],
29
- outDir: string,
30
- searchIndexJson: string,
31
- ): void {
32
- const contentDir = join(outDir, '_content')
33
- mkdirSync(contentDir, { recursive: true })
34
-
35
- // manifest.json — lean metadata only
36
- const manifest: ContentMeta[] = items.map(toContentMeta)
37
- writeFileSync(join(contentDir, 'manifest.json'), JSON.stringify(manifest), 'utf-8')
38
-
39
- // search-index.json
40
- writeFileSync(join(contentDir, 'search-index.json'), searchIndexJson, 'utf-8')
41
-
42
- // Per-document full JSON files
43
- for (const item of items) {
44
- const relFile = contentPathToFile(item._path)
45
- const absFile = join(contentDir, relFile)
46
- // Ensure subdirectory exists (e.g. _content/blog/ for _path: /blog/hello)
47
- mkdirSync(dirname(absFile), { recursive: true })
48
- writeFileSync(absFile, JSON.stringify(item), 'utf-8')
49
- }
50
- }