@jasonshimmy/vite-plugin-cer-app 0.23.1 → 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 (397) 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/commands/preview.d.ts.map +1 -1
  18. package/dist/cli/commands/preview.js +37 -4
  19. package/dist/cli/commands/preview.js.map +1 -1
  20. package/dist/cli/create/index.d.ts +11 -1
  21. package/dist/cli/create/index.d.ts.map +1 -1
  22. package/dist/cli/create/index.js +135 -65
  23. package/dist/cli/create/index.js.map +1 -1
  24. package/dist/cli/create/templates/spa/package.json.tpl +5 -3
  25. package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
  26. package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
  27. package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
  28. package/dist/cli/index.js +2 -0
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/index.d.ts +3 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/plugin/build-ssg.d.ts +22 -4
  33. package/dist/plugin/build-ssg.d.ts.map +1 -1
  34. package/dist/plugin/build-ssg.js +273 -13
  35. package/dist/plugin/build-ssg.js.map +1 -1
  36. package/dist/plugin/content/parser.d.ts.map +1 -1
  37. package/dist/plugin/content/parser.js +54 -10
  38. package/dist/plugin/content/parser.js.map +1 -1
  39. package/dist/plugin/dev-server.d.ts +6 -1
  40. package/dist/plugin/dev-server.d.ts.map +1 -1
  41. package/dist/plugin/dev-server.js.map +1 -1
  42. package/dist/plugin/dts-generator.d.ts.map +1 -1
  43. package/dist/plugin/dts-generator.js +50 -8
  44. package/dist/plugin/dts-generator.js.map +1 -1
  45. package/dist/plugin/generated-dir.d.ts +2 -0
  46. package/dist/plugin/generated-dir.d.ts.map +1 -1
  47. package/dist/plugin/generated-dir.js +17 -6
  48. package/dist/plugin/generated-dir.js.map +1 -1
  49. package/dist/plugin/html-post-process.d.ts +35 -0
  50. package/dist/plugin/html-post-process.d.ts.map +1 -0
  51. package/dist/plugin/html-post-process.js +112 -0
  52. package/dist/plugin/html-post-process.js.map +1 -0
  53. package/dist/plugin/index.d.ts +9 -0
  54. package/dist/plugin/index.d.ts.map +1 -1
  55. package/dist/plugin/index.js +89 -14
  56. package/dist/plugin/index.js.map +1 -1
  57. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  58. package/dist/plugin/transforms/auto-import.js +7 -0
  59. package/dist/plugin/transforms/auto-import.js.map +1 -1
  60. package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
  61. package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
  62. package/dist/plugin/transforms/prune-runtime-css.js +40 -0
  63. package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
  64. package/dist/runtime/app-template.d.ts +1 -4
  65. package/dist/runtime/app-template.d.ts.map +1 -1
  66. package/dist/runtime/app-template.js +211 -40
  67. package/dist/runtime/app-template.js.map +1 -1
  68. package/dist/runtime/composables/index.d.ts +4 -0
  69. package/dist/runtime/composables/index.d.ts.map +1 -1
  70. package/dist/runtime/composables/index.js +2 -0
  71. package/dist/runtime/composables/index.js.map +1 -1
  72. package/dist/runtime/composables/use-active-headings.d.ts +24 -0
  73. package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
  74. package/dist/runtime/composables/use-active-headings.js +112 -0
  75. package/dist/runtime/composables/use-active-headings.js.map +1 -0
  76. package/dist/runtime/composables/use-content-page.d.ts +45 -0
  77. package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
  78. package/dist/runtime/composables/use-content-page.js +179 -0
  79. package/dist/runtime/composables/use-content-page.js.map +1 -0
  80. package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
  81. package/dist/runtime/composables/use-content-search.js +1 -5
  82. package/dist/runtime/composables/use-content-search.js.map +1 -1
  83. package/dist/runtime/composables/use-fetch.d.ts +2 -1
  84. package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
  85. package/dist/runtime/composables/use-fetch.js +112 -43
  86. package/dist/runtime/composables/use-fetch.js.map +1 -1
  87. package/dist/runtime/composables/use-head.d.ts.map +1 -1
  88. package/dist/runtime/composables/use-head.js +30 -6
  89. package/dist/runtime/composables/use-head.js.map +1 -1
  90. package/dist/runtime/composables/use-route.d.ts.map +1 -1
  91. package/dist/runtime/composables/use-route.js +39 -11
  92. package/dist/runtime/composables/use-route.js.map +1 -1
  93. package/dist/runtime/content/client.js +2 -2
  94. package/dist/runtime/content/client.js.map +1 -1
  95. package/dist/runtime/entry-server-template.d.ts +16 -1
  96. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  97. package/dist/runtime/entry-server-template.js +120 -13
  98. package/dist/runtime/entry-server-template.js.map +1 -1
  99. package/dist/types/config.d.ts +53 -4
  100. package/dist/types/config.d.ts.map +1 -1
  101. package/dist/types/config.js.map +1 -1
  102. package/dist/types/middleware.d.ts +2 -2
  103. package/dist/types/middleware.d.ts.map +1 -1
  104. package/package.json +22 -19
  105. package/.github/copilot-instructions.md +0 -169
  106. package/.github/workflows/publish.yml +0 -257
  107. package/.nvmrc +0 -1
  108. package/CHANGELOG.md +0 -232
  109. package/CLAUDE.md +0 -113
  110. package/commits.txt +0 -1
  111. package/cypress.config.ts +0 -16
  112. package/docs/authentication.md +0 -285
  113. package/docs/cli.md +0 -324
  114. package/docs/components.md +0 -237
  115. package/docs/composables.md +0 -907
  116. package/docs/configuration.md +0 -667
  117. package/docs/content.md +0 -570
  118. package/docs/data-loading.md +0 -336
  119. package/docs/getting-started.md +0 -237
  120. package/docs/head-management.md +0 -212
  121. package/docs/i18n.md +0 -159
  122. package/docs/layouts.md +0 -224
  123. package/docs/middleware.md +0 -234
  124. package/docs/plugins.md +0 -170
  125. package/docs/rendering-modes.md +0 -377
  126. package/docs/routing.md +0 -485
  127. package/docs/server-api.md +0 -253
  128. package/docs/testing.md +0 -455
  129. package/docs/use-fetch.md +0 -183
  130. package/e2e/cypress/e2e/api.cy.ts +0 -123
  131. package/e2e/cypress/e2e/async-component.cy.ts +0 -27
  132. package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
  133. package/e2e/cypress/e2e/content.cy.ts +0 -425
  134. package/e2e/cypress/e2e/cookie.cy.ts +0 -85
  135. package/e2e/cypress/e2e/data.cy.ts +0 -158
  136. package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
  137. package/e2e/cypress/e2e/fouc.cy.ts +0 -254
  138. package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
  139. package/e2e/cypress/e2e/head.cy.ts +0 -89
  140. package/e2e/cypress/e2e/i18n.cy.ts +0 -79
  141. package/e2e/cypress/e2e/interactive.cy.ts +0 -137
  142. package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
  143. package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
  144. package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
  145. package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
  146. package/e2e/cypress/e2e/middleware.cy.ts +0 -45
  147. package/e2e/cypress/e2e/navigate.cy.ts +0 -39
  148. package/e2e/cypress/e2e/observability.cy.ts +0 -77
  149. package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
  150. package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
  151. package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
  152. package/e2e/cypress/e2e/routes.cy.ts +0 -128
  153. package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
  154. package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
  155. package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
  156. package/e2e/cypress/e2e/session.cy.ts +0 -73
  157. package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
  158. package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
  159. package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
  160. package/e2e/cypress/e2e/use-state.cy.ts +0 -138
  161. package/e2e/cypress/support/commands.ts +0 -120
  162. package/e2e/cypress/support/e2e.ts +0 -10
  163. package/e2e/cypress/tsconfig.json +0 -14
  164. package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
  165. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
  166. package/e2e/kitchen-sink/app/error.ts +0 -18
  167. package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
  168. package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
  169. package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
  170. package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
  171. package/e2e/kitchen-sink/app/loading.ts +0 -9
  172. package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
  173. package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
  174. package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
  175. package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
  176. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
  177. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
  178. package/e2e/kitchen-sink/app/pages/404.ts +0 -9
  179. package/e2e/kitchen-sink/app/pages/about.ts +0 -17
  180. package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
  181. package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
  182. package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
  183. package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
  184. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
  185. package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
  186. package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
  187. package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
  188. package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
  189. package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
  190. package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
  191. package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
  192. package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
  193. package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
  194. package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
  195. package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
  196. package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
  197. package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
  198. package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
  199. package/e2e/kitchen-sink/app/pages/head.ts +0 -20
  200. package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
  201. package/e2e/kitchen-sink/app/pages/index.ts +0 -27
  202. package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
  203. package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
  204. package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
  205. package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
  206. package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
  207. package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
  208. package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
  209. package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
  210. package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
  211. package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
  212. package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
  213. package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
  214. package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
  215. package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
  216. package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
  217. package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
  218. package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
  219. package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
  220. package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
  221. package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
  222. package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
  223. package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
  224. package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
  225. package/e2e/kitchen-sink/cer-env.d.ts +0 -35
  226. package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
  227. package/e2e/kitchen-sink/cer.config.ts +0 -43
  228. package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
  229. package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
  230. package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
  231. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
  232. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
  233. package/e2e/kitchen-sink/content/blog/index.md +0 -8
  234. package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
  235. package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
  236. package/e2e/kitchen-sink/content/index.md +0 -16
  237. package/e2e/kitchen-sink/server/api/echo.ts +0 -12
  238. package/e2e/kitchen-sink/server/api/health.ts +0 -3
  239. package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
  240. package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
  241. package/e2e/kitchen-sink/server/api/session.ts +0 -23
  242. package/e2e/kitchen-sink/server/data/posts.ts +0 -21
  243. package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
  244. package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
  245. package/e2e/kitchen-sink/tsconfig.json +0 -3
  246. package/e2e/scripts/clean.mjs +0 -14
  247. package/eslint.config.ts +0 -22
  248. package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
  249. package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
  250. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
  251. package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
  252. package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
  253. package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
  254. package/src/__tests__/cli/preview-hardening.test.ts +0 -265
  255. package/src/__tests__/cli/preview-isr.test.ts +0 -320
  256. package/src/__tests__/index.test.ts +0 -21
  257. package/src/__tests__/plugin/app-template.test.ts +0 -112
  258. package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
  259. package/src/__tests__/plugin/build-ssg.test.ts +0 -598
  260. package/src/__tests__/plugin/build-ssr.test.ts +0 -192
  261. package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
  262. package/src/__tests__/plugin/content/emitter.test.ts +0 -117
  263. package/src/__tests__/plugin/content/loader.test.ts +0 -154
  264. package/src/__tests__/plugin/content/parser.test.ts +0 -381
  265. package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
  266. package/src/__tests__/plugin/content/search.test.ts +0 -119
  267. package/src/__tests__/plugin/dev-server.test.ts +0 -813
  268. package/src/__tests__/plugin/dts-generator.test.ts +0 -394
  269. package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
  270. package/src/__tests__/plugin/generated-dir.test.ts +0 -144
  271. package/src/__tests__/plugin/path-utils.test.ts +0 -411
  272. package/src/__tests__/plugin/resolve-config.test.ts +0 -200
  273. package/src/__tests__/plugin/scanner.test.ts +0 -186
  274. package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
  275. package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
  276. package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
  277. package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
  278. package/src/__tests__/plugin/virtual/error.test.ts +0 -71
  279. package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
  280. package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
  281. package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
  282. package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
  283. package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
  284. package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
  285. package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
  286. package/src/__tests__/runtime/app-template.test.ts +0 -198
  287. package/src/__tests__/runtime/define-middleware.test.ts +0 -64
  288. package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
  289. package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
  290. package/src/__tests__/runtime/isr-handler.test.ts +0 -338
  291. package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
  292. package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
  293. package/src/__tests__/runtime/oauth-index.test.ts +0 -43
  294. package/src/__tests__/runtime/use-auth.test.ts +0 -169
  295. package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
  296. package/src/__tests__/runtime/use-content-search.test.ts +0 -163
  297. package/src/__tests__/runtime/use-content.test.ts +0 -226
  298. package/src/__tests__/runtime/use-cookie.test.ts +0 -277
  299. package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
  300. package/src/__tests__/runtime/use-fetch.test.ts +0 -377
  301. package/src/__tests__/runtime/use-head.test.ts +0 -266
  302. package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
  303. package/src/__tests__/runtime/use-inject.test.ts +0 -66
  304. package/src/__tests__/runtime/use-locale.test.ts +0 -152
  305. package/src/__tests__/runtime/use-navigate.test.ts +0 -121
  306. package/src/__tests__/runtime/use-page-data.test.ts +0 -298
  307. package/src/__tests__/runtime/use-route.test.ts +0 -156
  308. package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
  309. package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
  310. package/src/__tests__/runtime/use-session.test.ts +0 -320
  311. package/src/__tests__/runtime/use-state.test.ts +0 -340
  312. package/src/__tests__/types/config.test.ts +0 -18
  313. package/src/cli/adapters/cloudflare.ts +0 -335
  314. package/src/cli/adapters/netlify.ts +0 -326
  315. package/src/cli/adapters/vercel.ts +0 -311
  316. package/src/cli/commands/adapt.ts +0 -84
  317. package/src/cli/commands/build.ts +0 -165
  318. package/src/cli/commands/dev.ts +0 -125
  319. package/src/cli/commands/generate.ts +0 -91
  320. package/src/cli/commands/preview-isr.ts +0 -172
  321. package/src/cli/commands/preview.ts +0 -489
  322. package/src/cli/create/index.ts +0 -275
  323. package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
  324. package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
  325. package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
  326. package/src/cli/create/templates/shared/index.html.tpl +0 -12
  327. package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
  328. package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
  329. package/src/cli/create/templates/spa/package.json.tpl +0 -18
  330. package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
  331. package/src/cli/create/templates/ssg/package.json.tpl +0 -19
  332. package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
  333. package/src/cli/create/templates/ssr/package.json.tpl +0 -18
  334. package/src/cli/index.ts +0 -22
  335. package/src/index.ts +0 -20
  336. package/src/plugin/build-ssg.ts +0 -336
  337. package/src/plugin/build-ssr.ts +0 -134
  338. package/src/plugin/content/emitter.ts +0 -50
  339. package/src/plugin/content/index.ts +0 -233
  340. package/src/plugin/content/parser.ts +0 -259
  341. package/src/plugin/content/path-utils.ts +0 -55
  342. package/src/plugin/content/scanner.ts +0 -26
  343. package/src/plugin/content/search.ts +0 -28
  344. package/src/plugin/dev-server.ts +0 -377
  345. package/src/plugin/dts-generator.ts +0 -273
  346. package/src/plugin/generated-dir.ts +0 -121
  347. package/src/plugin/index.ts +0 -553
  348. package/src/plugin/path-utils.ts +0 -186
  349. package/src/plugin/scanner.ts +0 -65
  350. package/src/plugin/transforms/auto-import.ts +0 -206
  351. package/src/plugin/transforms/head-inject.ts +0 -161
  352. package/src/plugin/virtual/composables.ts +0 -28
  353. package/src/plugin/virtual/content-components.ts +0 -83
  354. package/src/plugin/virtual/error.ts +0 -34
  355. package/src/plugin/virtual/layouts.ts +0 -41
  356. package/src/plugin/virtual/loading.ts +0 -32
  357. package/src/plugin/virtual/middleware.ts +0 -45
  358. package/src/plugin/virtual/plugins.ts +0 -46
  359. package/src/plugin/virtual/routes.ts +0 -514
  360. package/src/plugin/virtual/server-api.ts +0 -85
  361. package/src/plugin/virtual/server-middleware.ts +0 -44
  362. package/src/runtime/app-template.ts +0 -380
  363. package/src/runtime/composables/define-middleware.ts +0 -17
  364. package/src/runtime/composables/define-server-middleware.ts +0 -18
  365. package/src/runtime/composables/index.ts +0 -27
  366. package/src/runtime/composables/use-auth.ts +0 -125
  367. package/src/runtime/composables/use-content-search.ts +0 -205
  368. package/src/runtime/composables/use-content.ts +0 -146
  369. package/src/runtime/composables/use-cookie.ts +0 -135
  370. package/src/runtime/composables/use-fetch.ts +0 -438
  371. package/src/runtime/composables/use-head.ts +0 -212
  372. package/src/runtime/composables/use-inject.ts +0 -49
  373. package/src/runtime/composables/use-locale.ts +0 -109
  374. package/src/runtime/composables/use-navigate.ts +0 -58
  375. package/src/runtime/composables/use-page-data.ts +0 -93
  376. package/src/runtime/composables/use-route.ts +0 -71
  377. package/src/runtime/composables/use-runtime-config.ts +0 -123
  378. package/src/runtime/composables/use-seo-meta.ts +0 -80
  379. package/src/runtime/composables/use-session.ts +0 -186
  380. package/src/runtime/composables/use-state.ts +0 -92
  381. package/src/runtime/content/client.ts +0 -168
  382. package/src/runtime/entry-client-template.ts +0 -39
  383. package/src/runtime/entry-server-template.ts +0 -493
  384. package/src/runtime/isr-handler.ts +0 -184
  385. package/src/runtime/oauth/handler.ts +0 -407
  386. package/src/runtime/oauth/index.ts +0 -49
  387. package/src/runtime/oauth/providers.ts +0 -38
  388. package/src/types/api.ts +0 -40
  389. package/src/types/config.ts +0 -371
  390. package/src/types/content.ts +0 -66
  391. package/src/types/index.ts +0 -7
  392. package/src/types/middleware.ts +0 -63
  393. package/src/types/page.ts +0 -117
  394. package/src/types/plugin.ts +0 -34
  395. package/tsconfig.build.json +0 -10
  396. package/tsconfig.json +0 -19
  397. package/vitest.config.ts +0 -33
@@ -1,121 +0,0 @@
1
- import { writeFileSync, existsSync, mkdirSync, readFileSync, appendFileSync } from 'node:fs'
2
- import { join } from 'pathe'
3
- import type { ResolvedCerConfig } from './dev-server.js'
4
- import { generateAppEntryTemplate } from '../runtime/app-template.js'
5
- import { ENTRY_SERVER_TEMPLATE } from '../runtime/entry-server-template.js'
6
-
7
- /** The name of the generated directory relative to the project root. */
8
- export const GENERATED_DIR_NAME = '.cer'
9
-
10
- /**
11
- * Returns the absolute path to the .cer/ generated directory.
12
- */
13
- export function getGeneratedDir(root: string): string {
14
- return join(root, GENERATED_DIR_NAME)
15
- }
16
-
17
- /**
18
- * Returns the HTML entry path to use for builds.
19
- * Prefers the consumer's root-level `index.html` when it exists;
20
- * falls back to `.cer/index.html`.
21
- */
22
- export function resolveHtmlEntry(config: ResolvedCerConfig): string {
23
- const userHtml = join(config.root, 'index.html')
24
- if (existsSync(userHtml)) return userHtml
25
- return join(getGeneratedDir(config.root), 'index.html')
26
- }
27
-
28
- /**
29
- * Generates the content for the default `.cer/index.html`.
30
- * Always points to the virtual `/@cer/app.ts` entry.
31
- */
32
- export function generateDefaultHtml(): string {
33
- return `<!DOCTYPE html>
34
- <html lang="en">
35
- <head>
36
- <meta charset="UTF-8" />
37
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
38
- <title>CER App</title>
39
- </head>
40
- <body>
41
- <cer-layout-view></cer-layout-view>
42
- <script type="module" src="/@cer/app.ts"></script>
43
- </body>
44
- </html>
45
- `
46
- }
47
-
48
- const GITIGNORE_DEFAULTS = `# Dependencies
49
- node_modules/
50
-
51
- # Build output
52
- dist/
53
-
54
- # CER App generated directory
55
- .cer/
56
-
57
- # Environment variables
58
- .env.local
59
- .env.*.local
60
-
61
- # Editor
62
- .vscode/
63
- .idea/
64
- *.suo
65
- *.sw?
66
-
67
- # OS
68
- .DS_Store
69
- Thumbs.db
70
-
71
- # Logs
72
- *.log
73
- `
74
-
75
- /**
76
- * Ensures `.cer/`, `node_modules/`, `dist/`, and other common entries are
77
- * listed in the project's `.gitignore`. Creates `.gitignore` if it does not exist.
78
- */
79
- function ensureGitignore(root: string): void {
80
- const gitignorePath = join(root, '.gitignore')
81
- const cerEntry = `${GENERATED_DIR_NAME}/`
82
-
83
- if (existsSync(gitignorePath)) {
84
- const content = readFileSync(gitignorePath, 'utf-8')
85
- if (!content.includes(cerEntry) && !content.includes(`${GENERATED_DIR_NAME}\n`)) {
86
- appendFileSync(gitignorePath, `\n# CER App generated directory\n${cerEntry}\n`)
87
- }
88
- } else {
89
- writeFileSync(gitignorePath, GITIGNORE_DEFAULTS)
90
- }
91
- }
92
-
93
- /**
94
- * Writes all generated files to `.cer/`:
95
- * - `.cer/app.ts` — framework entry (always regenerated)
96
- * - `.cer/index.html` — default HTML shell (always regenerated)
97
- * - `.cer/tsconfig.json` — written by dts-generator via writeTsconfigPaths
98
- *
99
- * Also ensures `.cer/` is listed in `.gitignore`.
100
- */
101
- export function writeGeneratedDir(config: ResolvedCerConfig): void {
102
- const dir = getGeneratedDir(config.root)
103
- if (!existsSync(dir)) {
104
- mkdirSync(dir, { recursive: true })
105
- }
106
-
107
- // Always write the generated app.ts — this is the framework entry point and
108
- // is never user-owned. Regenerating it on every dev/build ensures consumers
109
- // automatically get the latest bootstrap code on plugin update (Nuxt-style).
110
- writeFileSync(join(dir, 'app.ts'), generateAppEntryTemplate(config.jitCss.customColors), 'utf-8')
111
-
112
- // Always write the SSR entry — used by the dev server's ssrLoadModule call.
113
- // The production build injects this as a virtual module, but the dev server
114
- // needs a real file on disk because ssrLoadModule resolves by file path.
115
- writeFileSync(join(dir, 'entry-server.ts'), ENTRY_SERVER_TEMPLATE, 'utf-8')
116
-
117
- // Always write the default index.html so builds and the dev server can use it.
118
- writeFileSync(join(dir, 'index.html'), generateDefaultHtml(), 'utf-8')
119
-
120
- ensureGitignore(config.root)
121
- }
@@ -1,553 +0,0 @@
1
- import { resolve, join, dirname } from 'pathe'
2
- import { existsSync, readFileSync } from 'node:fs'
3
- import type { Plugin, ViteDevServer } from 'vite'
4
- import type { CerAppConfig } from '../types/config.js'
5
- import type { ResolvedCerConfig } from './dev-server.js'
6
- import { cerPlugin, cerComponentImports } from '@jasonshimmy/custom-elements-runtime/vite-plugin'
7
- import { autoImportTransform } from './transforms/auto-import.js'
8
- import { scanComposableExports, writeAutoImportDts, writeTsconfigPaths } from './dts-generator.js'
9
- import { configureCerDevServer } from './dev-server.js'
10
- import { writeGeneratedDir, getGeneratedDir } from './generated-dir.js'
11
- import { generateAppEntryTemplate } from '../runtime/app-template.js'
12
- import { generateRoutesCode } from './virtual/routes.js'
13
- import { generateLayoutsCode } from './virtual/layouts.js'
14
- import { generateComposablesCode } from './virtual/composables.js'
15
- import { generatePluginsCode } from './virtual/plugins.js'
16
- import { generateMiddlewareCode } from './virtual/middleware.js'
17
- import { generateServerApiCode } from './virtual/server-api.js'
18
- import { generateServerMiddlewareCode } from './virtual/server-middleware.js'
19
- import { generateLoadingCode } from './virtual/loading.js'
20
- import { generateErrorCode } from './virtual/error.js'
21
- import { generateContentComponentsCode } from './virtual/content-components.js'
22
- import { createWatcher } from './scanner.js'
23
- import { cerContent } from './content/index.js'
24
-
25
- // Virtual module IDs (raw)
26
- const VIRTUAL_IDS = {
27
- routes: 'virtual:cer-routes',
28
- layouts: 'virtual:cer-layouts',
29
- composables: 'virtual:cer-composables',
30
- plugins: 'virtual:cer-plugins',
31
- middleware: 'virtual:cer-middleware',
32
- serverApi: 'virtual:cer-server-api',
33
- serverMiddleware: 'virtual:cer-server-middleware',
34
- appConfig: 'virtual:cer-app-config',
35
- loading: 'virtual:cer-loading',
36
- error: 'virtual:cer-error',
37
- contentComponents: 'virtual:cer-content-components',
38
- i18n: 'virtual:cer-i18n',
39
- } as const
40
-
41
- // Resolved virtual module IDs (prefixed with \0)
42
- const RESOLVED_IDS = Object.fromEntries(
43
- Object.entries(VIRTUAL_IDS).map(([k, v]) => [k, `\0${v}`]),
44
- ) as Record<keyof typeof VIRTUAL_IDS, string>
45
-
46
- // The app entry is served via a virtual module at /@cer/app.ts.
47
- // Using /@ avoids Vite's dot-directory fs security restriction that blocks /.cer/
48
- // from being served through the transform middleware. The physical .cer/app.ts
49
- // is still written to disk for IDE/TypeScript support, but the browser fetches
50
- // /@cer/app.ts which resolves to this virtual module.
51
- const APP_ENTRY_URL = '/@cer/app.ts'
52
- const RESOLVED_APP_ENTRY = '\0cer-app-entry'
53
-
54
- /**
55
- * Fills in default values for all config fields and resolves absolute paths.
56
- */
57
- export function resolveConfig(userConfig: CerAppConfig, root: string = process.cwd()): ResolvedCerConfig {
58
- const mode = userConfig.mode ?? 'spa'
59
- const srcDir = resolve(root, userConfig.srcDir ?? 'app')
60
-
61
- return {
62
- mode,
63
- srcDir,
64
- root,
65
- contentDir: resolve(root, userConfig.content?.dir ?? 'content'),
66
- pagesDir: join(srcDir, 'pages'),
67
- layoutsDir: join(srcDir, 'layouts'),
68
- componentsDir: join(srcDir, 'components'),
69
- composablesDir: join(srcDir, 'composables'),
70
- pluginsDir: join(srcDir, 'plugins'),
71
- middlewareDir: join(srcDir, 'middleware'),
72
- serverApiDir: join(root, 'server/api'),
73
- serverMiddlewareDir: join(root, 'server/middleware'),
74
- port: userConfig.port ?? 3000,
75
- ssg: {
76
- routes: userConfig.ssg?.routes ?? 'auto',
77
- concurrency: userConfig.ssg?.concurrency ?? 4,
78
- fallback: userConfig.ssg?.fallback ?? false,
79
- },
80
- router: {
81
- base: userConfig.router?.base,
82
- scrollToFragment: userConfig.router?.scrollToFragment,
83
- },
84
- jitCss: {
85
- content: userConfig.jitCss?.content ?? [
86
- `${srcDir}/pages/**/*.ts`,
87
- `${srcDir}/components/**/*.ts`,
88
- `${srcDir}/layouts/**/*.ts`,
89
- ],
90
- extendedColors: userConfig.jitCss?.extendedColors ?? false,
91
- customColors: userConfig.jitCss?.customColors,
92
- },
93
- autoImports: {
94
- components: userConfig.autoImports?.components ?? true,
95
- composables: userConfig.autoImports?.composables ?? true,
96
- directives: userConfig.autoImports?.directives ?? true,
97
- runtime: userConfig.autoImports?.runtime ?? true,
98
- },
99
- runtimeConfig: {
100
- public: userConfig.runtimeConfig?.public ?? {},
101
- private: userConfig.runtimeConfig?.private ?? {},
102
- },
103
- auth: userConfig.auth ?? null,
104
- i18n: userConfig.i18n
105
- ? {
106
- locales: userConfig.i18n.locales,
107
- defaultLocale: userConfig.i18n.defaultLocale,
108
- strategy: userConfig.i18n.strategy ?? 'prefix_except_default',
109
- }
110
- : null,
111
- }
112
- }
113
-
114
- /**
115
- * Maps a resolved virtual ID to the appropriate generator function.
116
- */
117
- async function generateVirtualModule(
118
- id: string,
119
- config: ResolvedCerConfig,
120
- ssr = false,
121
- ): Promise<string | null> {
122
- switch (id) {
123
- case RESOLVED_IDS.routes:
124
- return generateRoutesCode(config.pagesDir, config.i18n)
125
- case RESOLVED_IDS.layouts:
126
- return generateLayoutsCode(config.layoutsDir)
127
- case RESOLVED_IDS.composables:
128
- return generateComposablesCode(config.composablesDir)
129
- case RESOLVED_IDS.plugins:
130
- return generatePluginsCode(config.pluginsDir, ssr)
131
- case RESOLVED_IDS.middleware:
132
- return generateMiddlewareCode(config.middlewareDir)
133
- case RESOLVED_IDS.serverApi:
134
- return generateServerApiCode(config.serverApiDir, config.auth)
135
- case RESOLVED_IDS.serverMiddleware:
136
- return generateServerMiddlewareCode(config.serverMiddlewareDir)
137
- case RESOLVED_IDS.appConfig:
138
- return generateAppConfigModule(config, ssr)
139
- case RESOLVED_IDS.loading:
140
- return generateLoadingCode(config.srcDir)
141
- case RESOLVED_IDS.error:
142
- return generateErrorCode(config.srcDir)
143
- case RESOLVED_IDS.contentComponents:
144
- return generateContentComponentsCode(config.componentsDir, config.contentDir)
145
- case RESOLVED_IDS.i18n:
146
- return generateI18nModule(config.i18n)
147
- default:
148
- return null
149
- }
150
- }
151
-
152
- /**
153
- * Generates the virtual:cer-i18n module that exports the resolved i18n config.
154
- * Exports a null config when i18n is not configured so useLocale() degrades
155
- * gracefully in apps that don't need internationalisation.
156
- */
157
- function generateI18nModule(
158
- i18n: ResolvedCerConfig['i18n'],
159
- ): string {
160
- const value = i18n
161
- ? JSON.stringify({ locales: i18n.locales, defaultLocale: i18n.defaultLocale, strategy: i18n.strategy }, null, 2)
162
- : 'null'
163
- return (
164
- `// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\n` +
165
- `export const i18nConfig = ${value}\n` +
166
- `export default i18nConfig\n`
167
- )
168
- }
169
-
170
- /**
171
- * Generates a virtual module that exports the resolved app config.
172
- * When `ssr` is true, also exports `_runtimePrivateDefaults` (server-only).
173
- * The client bundle never receives private keys.
174
- */
175
- function generateAppConfigModule(config: ResolvedCerConfig, ssr = false): string {
176
- const exportedConfig = {
177
- mode: config.mode,
178
- router: config.router,
179
- ssg: config.ssg,
180
- }
181
- const publicConfig = config.runtimeConfig.public
182
- const i18nValue = config.i18n ? JSON.stringify(config.i18n) : 'null'
183
- let code =
184
- `// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\n` +
185
- `export const appConfig = ${JSON.stringify(exportedConfig, null, 2)}\n` +
186
- `export default appConfig\n` +
187
- `\n` +
188
- `export const runtimeConfig = { public: ${JSON.stringify(publicConfig, null, 2)} }\n` +
189
- `\n` +
190
- `export const i18nConfig = ${i18nValue}\n` +
191
- `;(globalThis).__CER_I18N_CONFIG__ = i18nConfig\n` +
192
- `;(globalThis).__CER_APP_CONFIG__ = appConfig\n`
193
-
194
- if (ssr) {
195
- const privateDefaults = config.runtimeConfig.private
196
- code += `\nexport const _runtimePrivateDefaults = ${JSON.stringify(privateDefaults, null, 2)}\n`
197
- // Expose the auth session key so the entry-server template can pre-resolve
198
- // the authenticated user without duplicating config knowledge.
199
- const authSessionKey = config.auth?.sessionKey ?? (config.auth ? 'auth' : null)
200
- code += `\nexport const _authSessionKey = ${JSON.stringify(authSessionKey)}\n`
201
- // Thread observability hooks by re-importing the user's cer.config.ts.
202
- // Functions can't be JSON-serialised, so we import directly and re-export.
203
- const configFilePath = join(config.root, 'cer.config.ts')
204
- if (existsSync(configFilePath)) {
205
- code += `\nimport _cerUserConfig from ${JSON.stringify(configFilePath)}\n`
206
- code += `export const _hooks = {\n`
207
- code += ` onError: _cerUserConfig.onError ?? null,\n`
208
- code += ` onRequest: _cerUserConfig.onRequest ?? null,\n`
209
- code += ` onResponse: _cerUserConfig.onResponse ?? null,\n`
210
- code += `}\n`
211
- } else {
212
- code += `\nexport const _hooks = { onError: null, onRequest: null, onResponse: null }\n`
213
- }
214
- }
215
-
216
- return code
217
- }
218
-
219
- /**
220
- * Determines which virtual module IDs should be invalidated when a file changes
221
- * in a given directory.
222
- */
223
- function getDirtyVirtualIds(filePath: string, config: ResolvedCerConfig): string[] {
224
- const dirty: string[] = []
225
-
226
- if (filePath.startsWith(config.pagesDir)) {
227
- dirty.push(RESOLVED_IDS.routes)
228
- }
229
- if (filePath.startsWith(config.layoutsDir)) {
230
- dirty.push(RESOLVED_IDS.layouts)
231
- }
232
- if (filePath.startsWith(config.componentsDir)) {
233
- dirty.push(RESOLVED_IDS.contentComponents)
234
- }
235
- if (filePath.startsWith(config.composablesDir)) {
236
- dirty.push(RESOLVED_IDS.composables)
237
- }
238
- if (filePath.startsWith(config.pluginsDir)) {
239
- dirty.push(RESOLVED_IDS.plugins)
240
- }
241
- if (filePath.startsWith(config.middlewareDir)) {
242
- dirty.push(RESOLVED_IDS.middleware)
243
- }
244
- if (filePath.startsWith(config.serverApiDir)) {
245
- dirty.push(RESOLVED_IDS.serverApi)
246
- }
247
- if (filePath.startsWith(config.serverMiddlewareDir)) {
248
- dirty.push(RESOLVED_IDS.serverMiddleware)
249
- }
250
- if (filePath.startsWith(config.contentDir)) {
251
- dirty.push(RESOLVED_IDS.contentComponents)
252
- }
253
-
254
- return dirty
255
- }
256
-
257
- /**
258
- * The main cerApp() Vite plugin factory.
259
- * Returns an array of plugins: the cer-app orchestrator + the runtime JIT CSS plugin(s).
260
- */
261
- export function cerApp(userConfig: CerAppConfig = {}): Plugin[] {
262
- let config: ResolvedCerConfig
263
- let composableExports = new Map<string, string>()
264
-
265
- // Cache for generated virtual module code (invalidated on file changes)
266
- const moduleCache = new Map<string, string>()
267
-
268
- const cerAppPlugin: Plugin = {
269
- name: '@jasonshimmy/vite-plugin-cer-app',
270
-
271
- config(viteConfig) {
272
- const root = viteConfig.root ? resolve(viteConfig.root) : process.cwd()
273
- config = resolveConfig(userConfig, root)
274
- return {
275
- build: {
276
- target: 'esnext',
277
- rollupOptions: {
278
- onwarn(warning, warn) {
279
- // loader and meta are optional exports from page files — suppress noise
280
- if (
281
- warning.code === 'MISSING_EXPORT' &&
282
- (warning.binding === 'loader' || warning.binding === 'meta')
283
- ) {
284
- return
285
- }
286
- warn(warning)
287
- },
288
- },
289
- },
290
- }
291
- },
292
-
293
- configResolved(resolvedConfig) {
294
- // Re-resolve with the final root
295
- config = resolveConfig(userConfig, resolvedConfig.root)
296
- // Write .cer/ immediately after config is resolved so the physical
297
- // app.ts exists for IDE/TypeScript support before any Vite hooks fire.
298
- writeGeneratedDir(config)
299
- },
300
-
301
- transformIndexHtml(html: string) {
302
- // Rewrite any existing /.cer/app.ts src reference (older projects or
303
- // the scaffold template) to /@cer/app.ts so Vite's transform middleware
304
- // processes it. Vite blocks /.* paths from the transform pipeline.
305
- return html.replace(/src=["']\/\.cer\/app\.ts["']/g, 'src="/@cer/app.ts"')
306
- },
307
-
308
- resolveId(id: string) {
309
- if (id === APP_ENTRY_URL) return RESOLVED_APP_ENTRY
310
- if ((Object.values(VIRTUAL_IDS) as string[]).includes(id)) {
311
- return `\0${id}`
312
- }
313
- },
314
-
315
- async load(id: string, options?: { ssr?: boolean }) {
316
- if (id === RESOLVED_APP_ENTRY) return generateAppEntryTemplate(config.jitCss.customColors)
317
-
318
- const allResolved = Object.values(RESOLVED_IDS) as string[]
319
- if (!allResolved.includes(id)) return null
320
-
321
- const ssr = options?.ssr ?? false
322
- // For virtual:cer-app-config and virtual:cer-plugins the SSR and client
323
- // variants differ: app-config includes private defaults in SSR; plugins
324
- // excludes .client.ts files in SSR. Use separate cache keys for both.
325
- const cacheKey = (id === RESOLVED_IDS.appConfig || id === RESOLVED_IDS.plugins)
326
- ? `${id}:${ssr ? 'ssr' : 'client'}`
327
- : id
328
-
329
- // Return from cache if available
330
- if (moduleCache.has(cacheKey)) {
331
- return moduleCache.get(cacheKey)!
332
- }
333
-
334
- // Generate and cache
335
- const code = await generateVirtualModule(id, config, ssr)
336
- if (code !== null) {
337
- moduleCache.set(cacheKey, code)
338
- return code
339
- }
340
-
341
- return null
342
- },
343
-
344
- transform(code: string, id: string) {
345
- if (!config) return null
346
- if (config.autoImports?.runtime === false) return null
347
- // Skip virtual modules
348
- if (id.startsWith('\0')) return null
349
-
350
- const result = autoImportTransform(code, id, {
351
- srcDir: config.srcDir,
352
- serverMiddlewareDir: config.serverMiddlewareDir,
353
- composableExports: config.autoImports?.composables !== false ? composableExports : undefined,
354
- })
355
- if (result === null) return null
356
- return { code: result, map: null }
357
- },
358
-
359
- async configureServer(server: ViteDevServer) {
360
- if (!config) {
361
- // config might not be set yet; resolve with cwd
362
- config = resolveConfig(userConfig, process.cwd())
363
- }
364
-
365
- // Write .cer/ generated files (app.ts fallback, index.html, .gitignore)
366
- writeGeneratedDir(config)
367
-
368
- // Scan composables and write .d.ts + tsconfig paths on dev server start
369
- composableExports = await scanComposableExports(config.composablesDir)
370
- await writeAutoImportDts(config.root, config.composablesDir, composableExports)
371
- writeTsconfigPaths(config.root, config.srcDir)
372
-
373
- // Serve a generated index.html for HTML requests when the consumer has
374
- // not provided one. This runs BEFORE configureCerDevServer so that the
375
- // Vite HTML pipeline (HMR injection, module preprocessing) is applied.
376
- const userHtml = resolve(config.root, 'index.html')
377
- if (!existsSync(userHtml)) {
378
- const cerHtmlPath = join(getGeneratedDir(config.root), 'index.html')
379
- server.middlewares.use(async (req, res, next) => {
380
- // In SSR/SSG mode, HTML requests must fall through to configureCerDevServer
381
- // so the SSR handler can run loaders and inject __CER_DATA__ into the response.
382
- // Only SPA mode (no server rendering) should serve the raw SPA shell here.
383
- if (config.mode === 'ssr' || config.mode === 'ssg') {
384
- next()
385
- return
386
- }
387
- const url = (req as { url?: string }).url ?? '/'
388
- const isHtmlRequest =
389
- url === '/' ||
390
- url === '/index.html' ||
391
- (!url.includes('.') && !url.startsWith('/api/'))
392
- if (isHtmlRequest && existsSync(cerHtmlPath)) {
393
- const rawHtml = readFileSync(cerHtmlPath, 'utf-8')
394
- const transformed = await server.transformIndexHtml(url, rawHtml)
395
- res.setHeader('Content-Type', 'text/html; charset=utf-8')
396
- res.end(transformed)
397
- return
398
- }
399
- next()
400
- })
401
- }
402
-
403
- // Watch app/ and server/ directories for file changes
404
- const watchDirs = [
405
- config.pagesDir,
406
- config.layoutsDir,
407
- config.componentsDir,
408
- config.contentDir,
409
- config.composablesDir,
410
- config.pluginsDir,
411
- config.middlewareDir,
412
- config.serverApiDir,
413
- config.serverMiddlewareDir,
414
- ]
415
-
416
- createWatcher(server.watcher, watchDirs, async (event, file) => {
417
- if (event === 'add' || event === 'unlink') {
418
- // Re-scan composables and regenerate .d.ts if a composable changed
419
- if (file.startsWith(config.composablesDir)) {
420
- composableExports = await scanComposableExports(config.composablesDir)
421
- await writeAutoImportDts(config.root, config.composablesDir, composableExports)
422
- }
423
- // Invalidate relevant virtual modules
424
- const dirtyIds = getDirtyVirtualIds(file, config)
425
- for (const resolvedId of dirtyIds) {
426
- moduleCache.delete(resolvedId)
427
- const mod = server.moduleGraph.getModuleById(resolvedId)
428
- if (mod) {
429
- server.moduleGraph.invalidateModule(mod)
430
- }
431
- }
432
- // Trigger HMR
433
- server.ws.send({ type: 'full-reload' })
434
- }
435
- })
436
-
437
- // Register dev server middleware for API routes + SSR
438
- configureCerDevServer(server, config)
439
- },
440
-
441
- async buildStart() {
442
- if (!config) {
443
- config = resolveConfig(userConfig, process.cwd())
444
- }
445
- // Write .cer/ generated files before the build begins
446
- writeGeneratedDir(config)
447
- // Scan composables and generate type declarations + tsconfig paths
448
- composableExports = await scanComposableExports(config.composablesDir)
449
- await writeAutoImportDts(config.root, config.composablesDir, composableExports)
450
- writeTsconfigPaths(config.root, config.srcDir)
451
- // Warm the virtual module cache.
452
- // virtual:cer-app-config is cached under separate :client/:ssr keys because
453
- // the SSR variant includes _runtimePrivateDefaults (private env var defaults)
454
- // that must never appear in the client bundle. Warm both variants here so
455
- // neither the client build nor the SSR build incurs a cache miss on first load.
456
- for (const resolvedId of Object.values(RESOLVED_IDS)) {
457
- if (resolvedId === RESOLVED_IDS.appConfig) {
458
- const clientCode = await generateVirtualModule(resolvedId, config, false)
459
- if (clientCode !== null) moduleCache.set(`${resolvedId}:client`, clientCode)
460
- const ssrCode = await generateVirtualModule(resolvedId, config, true)
461
- if (ssrCode !== null) moduleCache.set(`${resolvedId}:ssr`, ssrCode)
462
- } else {
463
- const code = await generateVirtualModule(resolvedId, config)
464
- if (code !== null) moduleCache.set(resolvedId, code)
465
- }
466
- }
467
- },
468
- }
469
-
470
- // Include cerPlugin from the runtime for JIT CSS support
471
- // Resolve config eagerly so cerPlugin can use the final resolved values
472
- const resolvedForJit = resolveConfig(userConfig)
473
- const { content, ...jitOptions } = resolvedForJit.jitCss
474
- const jitPlugins = cerPlugin({
475
- content,
476
- ...jitOptions,
477
- ssr: {
478
- dsd: true,
479
- jit: jitOptions,
480
- },
481
- })
482
-
483
- // cerComponentImports must be initialized lazily — it needs the root-resolved
484
- // config.componentsDir and config.srcDir, which are only available after Vite
485
- // calls configResolved (where `config` is finalized with the correct root).
486
- // Initializing with resolvedForJit (which uses process.cwd() as root) would
487
- // point to wrong paths when the CLI builds with --root pointing elsewhere.
488
- let _componentImports: Plugin | null = null
489
-
490
- const componentImportsProxy: Plugin = {
491
- name: 'cer-component-imports',
492
- enforce: 'pre' as const,
493
- resolveId(id: string, importer: string | undefined) {
494
- // The library root package.json has "sideEffects": ["**/*.css"], which causes
495
- // Rollup to tree-shake side-effect-only imports of .ts files (e.g. component
496
- // registrations) when those files reside inside the same package boundary.
497
- // Override this for all app .ts files so their component() calls are retained.
498
- //
499
- // Two import forms need coverage:
500
- // 1. Relative imports from page/component files: e.g. './ks-badge.ts'
501
- // 2. Absolute imports from virtual modules: e.g. virtual:cer-layouts generates
502
- // `import "/abs/path/app/layouts/default.ts"` as a side-effect import.
503
- if (!importer || !config) return null
504
- const appRoot = config.srcDir.replace(/\\/g, '/').replace(/\/?$/, '/')
505
- let resolved: string
506
- if (id.startsWith('/')) {
507
- // Absolute path (used by virtual module generators like virtual:cer-layouts)
508
- resolved = id.replace(/\\/g, '/')
509
- } else if (id.startsWith('.')) {
510
- // Relative path from the importing file
511
- const importerDir = dirname(importer.split('?')[0])
512
- resolved = resolve(importerDir, id).replace(/\\/g, '/')
513
- } else {
514
- return null
515
- }
516
- if (resolved.startsWith(appRoot) && resolved.endsWith('.ts')) {
517
- return { id: resolved, moduleSideEffects: true }
518
- }
519
- return null
520
- },
521
- buildStart(opts) {
522
- // Initialize here so config is guaranteed to be fully resolved.
523
- // All configResolved hooks (including cerAppPlugin's) fire before any buildStart.
524
- _componentImports = cerComponentImports({
525
- componentsDir: config.componentsDir,
526
- appRoot: config.srcDir,
527
- }) as Plugin
528
- return (_componentImports?.buildStart as ((this: unknown, o: unknown) => void) | undefined)
529
- ?.call(this, opts)
530
- },
531
- watchChange(id: string, change: { event: 'create' | 'update' | 'delete' }) {
532
- return (_componentImports?.watchChange as ((this: unknown, id: string, change: unknown) => void) | undefined)
533
- ?.call(this, id, change)
534
- },
535
- transform(code: string, id: string) {
536
- return (_componentImports?.transform as ((this: unknown, code: string, id: string) => unknown) | undefined)
537
- ?.call(this, code, id) ?? null
538
- },
539
- handleHotUpdate(ctx: unknown) {
540
- ;(_componentImports?.handleHotUpdate as ((this: unknown, ctx: unknown) => void) | undefined)
541
- ?.call(this, ctx)
542
- },
543
- }
544
-
545
- return [
546
- cerAppPlugin,
547
- ...jitPlugins,
548
- ...(userConfig.autoImports?.components !== false ? [componentImportsProxy] : []),
549
- cerContent(
550
- userConfig.content,
551
- ),
552
- ]
553
- }