@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,552 +0,0 @@
1
- import { vi, describe, it, expect, beforeEach } from 'vitest'
2
-
3
- vi.mock('@jasonshimmy/custom-elements-runtime/vite-plugin', () => ({
4
- cerPlugin: vi.fn().mockReturnValue([{ name: 'cer-runtime-plugin' }]),
5
- cerComponentImports: vi.fn().mockReturnValue({ name: 'cer-component-imports' }),
6
- }))
7
- vi.mock('node:fs', async (importOriginal) => {
8
- const actual = await importOriginal<typeof import('node:fs')>()
9
- return { ...actual, existsSync: vi.fn().mockReturnValue(true), readFileSync: vi.fn().mockReturnValue('') }
10
- })
11
- vi.mock('../../plugin/dev-server.js', () => ({
12
- configureCerDevServer: vi.fn().mockResolvedValue(undefined),
13
- }))
14
- vi.mock('../../plugin/scanner.js', () => ({
15
- createWatcher: vi.fn().mockReturnValue({ on: vi.fn(), close: vi.fn() }),
16
- scanDirectory: vi.fn().mockResolvedValue([]),
17
- }))
18
- vi.mock('../../plugin/dts-generator.js', () => ({
19
- scanComposableExports: vi.fn().mockResolvedValue(new Map()),
20
- writeAutoImportDts: vi.fn().mockResolvedValue(undefined),
21
- writeTsconfigPaths: vi.fn(),
22
- }))
23
- vi.mock('../../plugin/generated-dir.js', () => ({
24
- writeGeneratedDir: vi.fn(),
25
- getGeneratedDir: vi.fn().mockReturnValue('/project/.cer'),
26
- GENERATED_DIR_NAME: '.cer',
27
- }))
28
- vi.mock('../../plugin/virtual/routes.js', () => ({ generateRoutesCode: vi.fn().mockResolvedValue('// routes') }))
29
- vi.mock('../../plugin/virtual/layouts.js', () => ({ generateLayoutsCode: vi.fn().mockResolvedValue('// layouts') }))
30
- vi.mock('../../plugin/virtual/composables.js', () => ({ generateComposablesCode: vi.fn().mockResolvedValue('// composables') }))
31
- vi.mock('../../plugin/virtual/plugins.js', () => ({ generatePluginsCode: vi.fn().mockResolvedValue('// plugins') }))
32
- vi.mock('../../plugin/virtual/middleware.js', () => ({ generateMiddlewareCode: vi.fn().mockResolvedValue('// middleware') }))
33
- vi.mock('../../plugin/virtual/server-api.js', () => ({ generateServerApiCode: vi.fn().mockResolvedValue('// server-api') }))
34
- vi.mock('../../plugin/virtual/server-middleware.js', () => ({ generateServerMiddlewareCode: vi.fn().mockResolvedValue('// server-middleware') }))
35
- vi.mock('../../plugin/virtual/loading.js', () => ({ generateLoadingCode: vi.fn().mockResolvedValue('// loading') }))
36
- vi.mock('../../plugin/virtual/error.js', () => ({ generateErrorCode: vi.fn().mockResolvedValue('// error') }))
37
- vi.mock('../../plugin/virtual/content-components.js', () => ({ generateContentComponentsCode: vi.fn().mockResolvedValue('// content-components') }))
38
- vi.mock('../../plugin/transforms/auto-import.js', () => ({ autoImportTransform: vi.fn().mockReturnValue(null) }))
39
-
40
- import { cerApp } from '../../plugin/index.js'
41
- import { generateAppEntryTemplate } from '../../runtime/app-template.js'
42
-
43
-
44
- type TestPlugin = {
45
- name: string
46
- config: (viteConfig: Record<string, unknown>, env: Record<string, unknown>) => unknown
47
- configResolved: (resolved: Record<string, unknown>) => void
48
- resolveId: (id: string) => string | undefined
49
- load: (id: string, options?: { ssr?: boolean }) => Promise<string | null>
50
- transform: (code: string, id: string) => unknown
51
- transformIndexHtml: (html: string) => string
52
- buildStart: () => Promise<void>
53
- configureServer: (server: unknown) => Promise<void>
54
- }
55
-
56
- // Helper to get the cerAppPlugin (first plugin in the returned array)
57
- function getCerPlugin(userConfig = {}): TestPlugin {
58
- return cerApp(userConfig)[0] as unknown as TestPlugin
59
- }
60
-
61
- // Minimal resolved config that mirrors what Vite passes to configResolved
62
- const FAKE_RESOLVED = { root: '/project' }
63
-
64
- describe('cerApp()', () => {
65
- it('returns an array of plugins', () => {
66
- const plugins = cerApp()
67
- expect(Array.isArray(plugins)).toBe(true)
68
- expect(plugins.length).toBeGreaterThan(0)
69
- })
70
-
71
- it('first plugin is named @jasonshimmy/vite-plugin-cer-app', () => {
72
- const plugin = getCerPlugin()
73
- expect(plugin.name).toBe('@jasonshimmy/vite-plugin-cer-app')
74
- })
75
-
76
- it('includes cerComponentImports plugin when autoImports.components is unset', () => {
77
- const plugins = cerApp()
78
- const names = plugins.map((p) => (p as { name: string }).name)
79
- expect(names).toContain('cer-component-imports')
80
- })
81
-
82
- it('includes cerComponentImports plugin when autoImports.components is true', () => {
83
- const plugins = cerApp({ autoImports: { components: true } })
84
- const names = plugins.map((p) => (p as { name: string }).name)
85
- expect(names).toContain('cer-component-imports')
86
- })
87
-
88
- it('excludes cerComponentImports plugin when autoImports.components is false', () => {
89
- const plugins = cerApp({ autoImports: { components: false } })
90
- const names = plugins.map((p) => (p as { name: string }).name)
91
- expect(names).not.toContain('cer-component-imports')
92
- })
93
- })
94
-
95
- describe('cerApp plugin — config hook', () => {
96
- it('returns build.target: esnext', () => {
97
- const plugin = getCerPlugin()
98
- const result = plugin.config({ root: '/project' }, { command: 'build', mode: 'production' }) as Record<string, unknown>
99
- expect((result.build as Record<string, unknown>).target).toBe('esnext')
100
- })
101
-
102
- it('config hook resolves the root', () => {
103
- const plugin = getCerPlugin()
104
- const result = plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
105
- expect(result).toBeDefined()
106
- })
107
- })
108
-
109
- describe('cerApp plugin — configResolved hook', () => {
110
- it('does not throw when called', () => {
111
- const plugin = getCerPlugin()
112
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
113
- expect(() => plugin.configResolved(FAKE_RESOLVED)).not.toThrow()
114
- })
115
- })
116
-
117
- describe('cerApp plugin — resolveId hook', () => {
118
- beforeEach(() => {
119
- const plugin = getCerPlugin()
120
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
121
- plugin.configResolved(FAKE_RESOLVED)
122
- })
123
-
124
- it('resolves virtual:cer-routes to \\0virtual:cer-routes', () => {
125
- const plugin = getCerPlugin()
126
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
127
- expect(plugin.resolveId('virtual:cer-routes')).toBe('\0virtual:cer-routes')
128
- })
129
-
130
- it('resolves virtual:cer-layouts', () => {
131
- const plugin = getCerPlugin()
132
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
133
- expect(plugin.resolveId('virtual:cer-layouts')).toBe('\0virtual:cer-layouts')
134
- })
135
-
136
- it('resolves virtual:cer-plugins', () => {
137
- const plugin = getCerPlugin()
138
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
139
- expect(plugin.resolveId('virtual:cer-plugins')).toBe('\0virtual:cer-plugins')
140
- })
141
-
142
- it('resolves virtual:cer-server-api', () => {
143
- const plugin = getCerPlugin()
144
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
145
- expect(plugin.resolveId('virtual:cer-server-api')).toBe('\0virtual:cer-server-api')
146
- })
147
-
148
- it('resolves virtual:cer-loading', () => {
149
- const plugin = getCerPlugin()
150
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
151
- expect(plugin.resolveId('virtual:cer-loading')).toBe('\0virtual:cer-loading')
152
- })
153
-
154
- it('resolves virtual:cer-error', () => {
155
- const plugin = getCerPlugin()
156
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
157
- expect(plugin.resolveId('virtual:cer-error')).toBe('\0virtual:cer-error')
158
- })
159
-
160
- it('resolves /@cer/app.ts to \\0cer-app-entry (virtual module)', () => {
161
- const plugin = getCerPlugin()
162
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
163
- expect(plugin.resolveId('/@cer/app.ts')).toBe('\0cer-app-entry')
164
- })
165
-
166
- it('does not resolve /.cer/app.ts (old URL, rewritten by transformIndexHtml)', () => {
167
- const plugin = getCerPlugin()
168
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
169
- expect(plugin.resolveId('/.cer/app.ts')).toBeUndefined()
170
- })
171
-
172
- it('returns undefined for unknown ids', () => {
173
- const plugin = getCerPlugin()
174
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
175
- expect(plugin.resolveId('some-unknown-id')).toBeUndefined()
176
- })
177
- })
178
-
179
- describe('cerApp plugin — load hook', () => {
180
- it('loads \\0cer-app-entry with generated app entry content', async () => {
181
- const plugin = getCerPlugin()
182
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
183
- plugin.configResolved(FAKE_RESOLVED)
184
- const result = await plugin.load('\0cer-app-entry')
185
- expect(result).toBe(generateAppEntryTemplate())
186
- })
187
-
188
- it('returns null for unknown resolved ids', async () => {
189
- const plugin = getCerPlugin()
190
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
191
- plugin.configResolved(FAKE_RESOLVED)
192
- const result = await plugin.load('\0unknown-module')
193
- expect(result).toBeNull()
194
- })
195
-
196
- it('loads virtual:cer-routes module code', async () => {
197
- const plugin = getCerPlugin()
198
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
199
- plugin.configResolved(FAKE_RESOLVED)
200
- const result = await plugin.load('\0virtual:cer-routes')
201
- expect(result).toBe('// routes')
202
- })
203
-
204
- it('loads virtual:cer-layouts module code', async () => {
205
- const plugin = getCerPlugin()
206
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
207
- plugin.configResolved(FAKE_RESOLVED)
208
- const result = await plugin.load('\0virtual:cer-layouts')
209
- expect(result).toBe('// layouts')
210
- })
211
-
212
- it('loads virtual:cer-loading module code', async () => {
213
- const plugin = getCerPlugin()
214
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
215
- plugin.configResolved(FAKE_RESOLVED)
216
- const result = await plugin.load('\0virtual:cer-loading')
217
- expect(result).toBe('// loading')
218
- })
219
-
220
- it('loads virtual:cer-error module code', async () => {
221
- const plugin = getCerPlugin()
222
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
223
- plugin.configResolved(FAKE_RESOLVED)
224
- const result = await plugin.load('\0virtual:cer-error')
225
- expect(result).toBe('// error')
226
- })
227
-
228
- it('returns cached code on repeated load calls', async () => {
229
- const { generateRoutesCode } = await import('../../plugin/virtual/routes.js')
230
- vi.mocked(generateRoutesCode).mockClear()
231
-
232
- // Use a SINGLE plugin instance so the module cache persists across calls
233
- const plugin = getCerPlugin()
234
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
235
- plugin.configResolved(FAKE_RESOLVED)
236
-
237
- const first = await plugin.load('\0virtual:cer-routes')
238
- const second = await plugin.load('\0virtual:cer-routes')
239
-
240
- expect(first).toBe(second)
241
- // generateRoutesCode should only be called once (cache hit on second call)
242
- expect(generateRoutesCode).toHaveBeenCalledTimes(1)
243
- })
244
-
245
- it('loads virtual:cer-app-config and exports appConfig', async () => {
246
- const plugin = getCerPlugin({ mode: 'ssg' })
247
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
248
- plugin.configResolved(FAKE_RESOLVED)
249
- const result = await plugin.load('\0virtual:cer-app-config') as string
250
- expect(result).toContain('appConfig')
251
- expect(result).toContain('ssg')
252
- })
253
-
254
- it('excludes _runtimePrivateDefaults from the client bundle', async () => {
255
- const plugin = getCerPlugin({ runtimeConfig: { private: { dbUrl: '', secretKey: '' } } })
256
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
257
- plugin.configResolved(FAKE_RESOLVED)
258
- // Client load (ssr: false / omitted)
259
- const clientResult = await plugin.load('\0virtual:cer-app-config') as string
260
- expect(clientResult).not.toContain('_runtimePrivateDefaults')
261
- expect(clientResult).not.toContain('dbUrl')
262
- })
263
-
264
- it('includes _runtimePrivateDefaults in the SSR bundle', async () => {
265
- const plugin = getCerPlugin({ runtimeConfig: { private: { dbUrl: '', secretKey: '' } } })
266
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
267
- plugin.configResolved(FAKE_RESOLVED)
268
- // SSR load (ssr: true)
269
- const ssrResult = await plugin.load('\0virtual:cer-app-config', { ssr: true }) as string
270
- expect(ssrResult).toContain('_runtimePrivateDefaults')
271
- expect(ssrResult).toContain('dbUrl')
272
- })
273
-
274
- it('caches SSR and client virtual:cer-app-config separately', async () => {
275
- const plugin = getCerPlugin({ runtimeConfig: { private: { token: '' } } })
276
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
277
- plugin.configResolved(FAKE_RESOLVED)
278
- const client = await plugin.load('\0virtual:cer-app-config') as string
279
- const ssr = await plugin.load('\0virtual:cer-app-config', { ssr: true }) as string
280
- expect(client).not.toContain('_runtimePrivateDefaults')
281
- expect(ssr).toContain('_runtimePrivateDefaults')
282
- })
283
- })
284
-
285
- describe('cerApp plugin — transform hook', () => {
286
- it('returns null for virtual module ids', async () => {
287
- const plugin = getCerPlugin()
288
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
289
- plugin.configResolved(FAKE_RESOLVED)
290
- const result = plugin.transform('// code', '\0virtual:cer-routes')
291
- expect(result).toBeNull()
292
- })
293
-
294
- it('calls autoImportTransform for regular files', async () => {
295
- const { autoImportTransform } = await import('../../plugin/transforms/auto-import.js')
296
- const plugin = getCerPlugin()
297
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
298
- plugin.configResolved(FAKE_RESOLVED)
299
-
300
- plugin.transform('const x = 1', '/project/app/pages/index.ts')
301
- expect(autoImportTransform).toHaveBeenCalled()
302
- })
303
-
304
- it('returns null when autoImportTransform returns null', async () => {
305
- const plugin = getCerPlugin()
306
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
307
- plugin.configResolved(FAKE_RESOLVED)
308
- const result = plugin.transform('const x = 1', '/project/app/pages/index.ts')
309
- expect(result).toBeNull()
310
- })
311
-
312
- it('returns { code, map } when autoImportTransform returns a string', async () => {
313
- const { autoImportTransform } = await import('../../plugin/transforms/auto-import.js')
314
- vi.mocked(autoImportTransform).mockReturnValueOnce('transformed code')
315
- const plugin = getCerPlugin()
316
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
317
- plugin.configResolved(FAKE_RESOLVED)
318
- const result = plugin.transform('const x = 1', '/project/app/pages/index.ts') as { code: string; map: null }
319
- expect(result).toEqual({ code: 'transformed code', map: null })
320
- })
321
-
322
- it('returns null when autoImports.runtime is false', async () => {
323
- const plugin = getCerPlugin({ autoImports: { runtime: false } })
324
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
325
- plugin.configResolved(FAKE_RESOLVED)
326
- const result = plugin.transform('const x = 1', '/project/app/pages/index.ts')
327
- expect(result).toBeNull()
328
- })
329
- })
330
-
331
- describe('cerApp plugin — transformIndexHtml hook', () => {
332
- it('rewrites /.cer/app.ts src to /@cer/app.ts', () => {
333
- const plugin = getCerPlugin()
334
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
335
- const input = '<script type="module" src="/.cer/app.ts"></script>'
336
- const output = plugin.transformIndexHtml(input)
337
- expect(output).toContain('src="/@cer/app.ts"')
338
- expect(output).not.toContain('src="/.cer/app.ts"')
339
- })
340
-
341
- it('leaves html unchanged when /.cer/app.ts is not present', () => {
342
- const plugin = getCerPlugin()
343
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
344
- const input = '<script type="module" src="/@cer/app.ts"></script>'
345
- expect(plugin.transformIndexHtml(input)).toBe(input)
346
- })
347
- })
348
-
349
- describe('cerApp plugin — configResolved hook', () => {
350
- it('calls writeGeneratedDir during configResolved', async () => {
351
- const { writeGeneratedDir } = await import('../../plugin/generated-dir.js')
352
- vi.mocked(writeGeneratedDir).mockClear()
353
- const plugin = getCerPlugin()
354
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
355
- plugin.configResolved(FAKE_RESOLVED)
356
- expect(writeGeneratedDir).toHaveBeenCalledTimes(1)
357
- })
358
- })
359
-
360
- describe('cerApp plugin — buildStart hook', () => {
361
- it('calls writeGeneratedDir on build start', async () => {
362
- const { writeGeneratedDir } = await import('../../plugin/generated-dir.js')
363
- vi.mocked(writeGeneratedDir).mockClear()
364
- const plugin = getCerPlugin()
365
- plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
366
- plugin.configResolved(FAKE_RESOLVED)
367
- await plugin.buildStart()
368
- // writeGeneratedDir is called once in configResolved and once in buildStart
369
- expect(writeGeneratedDir).toHaveBeenCalledTimes(2)
370
- })
371
-
372
- it('calls scanComposableExports on build start', async () => {
373
- const { scanComposableExports } = await import('../../plugin/dts-generator.js')
374
- vi.mocked(scanComposableExports).mockClear()
375
- const plugin = getCerPlugin()
376
- plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
377
- plugin.configResolved(FAKE_RESOLVED)
378
- await plugin.buildStart()
379
- expect(scanComposableExports).toHaveBeenCalledTimes(1)
380
- })
381
-
382
- it('calls writeAutoImportDts on build start', async () => {
383
- const { writeAutoImportDts } = await import('../../plugin/dts-generator.js')
384
- vi.mocked(writeAutoImportDts).mockClear()
385
- const plugin = getCerPlugin()
386
- plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
387
- plugin.configResolved(FAKE_RESOLVED)
388
- await plugin.buildStart()
389
- expect(writeAutoImportDts).toHaveBeenCalledTimes(1)
390
- })
391
-
392
- it('calls writeTsconfigPaths on build start', async () => {
393
- const { writeTsconfigPaths } = await import('../../plugin/dts-generator.js')
394
- vi.mocked(writeTsconfigPaths).mockClear()
395
- const plugin = getCerPlugin()
396
- plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
397
- plugin.configResolved(FAKE_RESOLVED)
398
- await plugin.buildStart()
399
- expect(writeTsconfigPaths).toHaveBeenCalledTimes(1)
400
- })
401
-
402
- it('warms virtual:cer-app-config cache under :client key so load() hits it', async () => {
403
- // After buildStart(), a subsequent client load (ssr: false) should be served
404
- // from cache (generateAppConfigModule is not a public mock, so we verify by
405
- // ensuring the load hook returns a non-null result without triggering the
406
- // real generator — which is mocked at module level to a fixed string '// mock'
407
- // for other modules; appConfig is not mocked, so it generates real code).
408
- const plugin = getCerPlugin({ runtimeConfig: { private: { token: '' } } })
409
- plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
410
- plugin.configResolved(FAKE_RESOLVED)
411
- await plugin.buildStart()
412
-
413
- // Client load should return a result that does NOT include _runtimePrivateDefaults
414
- const result = await plugin.load('\0virtual:cer-app-config') as string
415
- expect(result).not.toContain('_runtimePrivateDefaults')
416
-
417
- // SSR load (different cache key) should include _runtimePrivateDefaults
418
- const ssrResult = await plugin.load('\0virtual:cer-app-config', { ssr: true }) as string
419
- expect(ssrResult).toContain('_runtimePrivateDefaults')
420
- })
421
- })
422
-
423
- describe('cerApp plugin — configureServer hook', () => {
424
- it('calls writeGeneratedDir on server configure', async () => {
425
- const { writeGeneratedDir } = await import('../../plugin/generated-dir.js')
426
- vi.mocked(writeGeneratedDir).mockClear()
427
- const plugin = getCerPlugin()
428
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
429
- plugin.configResolved(FAKE_RESOLVED)
430
- const mockServer = {
431
- watcher: { on: vi.fn() },
432
- moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
433
- ws: { send: vi.fn() },
434
- middlewares: { use: vi.fn() },
435
- }
436
- await plugin.configureServer(mockServer)
437
- // configResolved calls it once, configureServer calls it again
438
- expect(writeGeneratedDir).toHaveBeenCalledTimes(2)
439
- })
440
-
441
- it('calls scanComposableExports on server configure', async () => {
442
- const { scanComposableExports } = await import('../../plugin/dts-generator.js')
443
- vi.mocked(scanComposableExports).mockClear()
444
- const plugin = getCerPlugin()
445
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
446
- plugin.configResolved(FAKE_RESOLVED)
447
-
448
- const mockServer = {
449
- watcher: { on: vi.fn() },
450
- moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
451
- ws: { send: vi.fn() },
452
- }
453
- await plugin.configureServer(mockServer)
454
- expect(scanComposableExports).toHaveBeenCalled()
455
- })
456
-
457
- it('calls configureCerDevServer on server configure', async () => {
458
- const { configureCerDevServer } = await import('../../plugin/dev-server.js')
459
- vi.mocked(configureCerDevServer).mockClear()
460
- const plugin = getCerPlugin()
461
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
462
- plugin.configResolved(FAKE_RESOLVED)
463
-
464
- const mockServer = {
465
- watcher: { on: vi.fn() },
466
- moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
467
- ws: { send: vi.fn() },
468
- }
469
- await plugin.configureServer(mockServer)
470
- expect(configureCerDevServer).toHaveBeenCalled()
471
- })
472
-
473
- it('invokes the file-change watcher callback on add event', async () => {
474
- const { createWatcher } = await import('../../plugin/scanner.js')
475
- const { scanComposableExports } = await import('../../plugin/dts-generator.js')
476
- vi.mocked(scanComposableExports).mockClear()
477
-
478
- let capturedCallback: ((event: string, file: string) => void) | null = null
479
- vi.mocked(createWatcher).mockImplementationOnce((_watcher, _dirs, cb) => {
480
- capturedCallback = cb
481
- return { on: vi.fn(), close: vi.fn() } as unknown as ReturnType<typeof createWatcher>
482
- })
483
-
484
- const plugin = getCerPlugin()
485
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
486
- plugin.configResolved(FAKE_RESOLVED)
487
-
488
- const mockServer = {
489
- watcher: { on: vi.fn() },
490
- moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
491
- ws: { send: vi.fn() },
492
- }
493
- await plugin.configureServer(mockServer)
494
-
495
- // Simulate an 'add' event on a pages file — covers getDirtyVirtualIds and watcher callback
496
- await capturedCallback!('add', '/project/app/pages/new-page.ts')
497
- expect((mockServer.ws.send as ReturnType<typeof vi.fn>)).toHaveBeenCalledWith({ type: 'full-reload' })
498
- })
499
-
500
- it('re-scans composables when a composable file is added', async () => {
501
- const { createWatcher } = await import('../../plugin/scanner.js')
502
- const { scanComposableExports } = await import('../../plugin/dts-generator.js')
503
- vi.mocked(scanComposableExports).mockClear()
504
-
505
- let capturedCallback: ((event: string, file: string) => void) | null = null
506
- vi.mocked(createWatcher).mockImplementationOnce((_watcher, _dirs, cb) => {
507
- capturedCallback = cb
508
- return { on: vi.fn(), close: vi.fn() } as unknown as ReturnType<typeof createWatcher>
509
- })
510
-
511
- const plugin = getCerPlugin()
512
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
513
- plugin.configResolved(FAKE_RESOLVED)
514
-
515
- const mockServer = {
516
- watcher: { on: vi.fn() },
517
- moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
518
- ws: { send: vi.fn() },
519
- }
520
- await plugin.configureServer(mockServer)
521
-
522
- const callsBeforeEvent = vi.mocked(scanComposableExports).mock.calls.length
523
- await capturedCallback!('add', '/project/app/composables/use-new.ts')
524
- expect(vi.mocked(scanComposableExports).mock.calls.length).toBeGreaterThan(callsBeforeEvent)
525
- })
526
-
527
- it('does not trigger HMR on non-add/unlink events', async () => {
528
- const { createWatcher } = await import('../../plugin/scanner.js')
529
-
530
- let capturedCallback: ((event: string, file: string) => void) | null = null
531
- vi.mocked(createWatcher).mockImplementationOnce((_watcher, _dirs, cb) => {
532
- capturedCallback = cb
533
- return { on: vi.fn(), close: vi.fn() } as unknown as ReturnType<typeof createWatcher>
534
- })
535
-
536
- const plugin = getCerPlugin()
537
- plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
538
- plugin.configResolved(FAKE_RESOLVED)
539
-
540
- const wsSend = vi.fn()
541
- const mockServer = {
542
- watcher: { on: vi.fn() },
543
- moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
544
- ws: { send: wsSend },
545
- }
546
- await plugin.configureServer(mockServer)
547
- wsSend.mockClear()
548
-
549
- await capturedCallback!('change', '/project/app/pages/index.ts')
550
- expect(wsSend).not.toHaveBeenCalled()
551
- })
552
- })
@@ -1,117 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { contentPathToFile, emitContentFiles } from '../../../plugin/content/emitter.js'
3
- import { mkdtempSync, readFileSync, existsSync } from 'node:fs'
4
- import { tmpdir } from 'node:os'
5
- import { join } from 'pathe'
6
- import type { ContentItem } from '../../../types/content.js'
7
-
8
- // ─── contentPathToFile ────────────────────────────────────────────────────────
9
-
10
- describe('contentPathToFile', () => {
11
- it('maps / to index.json', () => {
12
- expect(contentPathToFile('/')).toBe('index.json')
13
- })
14
-
15
- it('maps /about to about.json', () => {
16
- expect(contentPathToFile('/about')).toBe('about.json')
17
- })
18
-
19
- it('maps /blog/hello to blog/hello.json', () => {
20
- expect(contentPathToFile('/blog/hello')).toBe('blog/hello.json')
21
- })
22
-
23
- it('maps /blog to blog.json', () => {
24
- expect(contentPathToFile('/blog')).toBe('blog.json')
25
- })
26
-
27
- it('maps /docs/getting-started to docs/getting-started.json', () => {
28
- expect(contentPathToFile('/docs/getting-started')).toBe('docs/getting-started.json')
29
- })
30
- })
31
-
32
- // ─── emitContentFiles ─────────────────────────────────────────────────────────
33
-
34
- describe('emitContentFiles', () => {
35
- const items: ContentItem[] = [
36
- {
37
- _path: '/',
38
- _file: 'index.md',
39
- _type: 'markdown',
40
- title: 'Home',
41
- description: 'Welcome',
42
- body: '<h1>Home</h1>',
43
- toc: [],
44
- },
45
- {
46
- _path: '/blog/hello',
47
- _file: 'blog/hello.md',
48
- _type: 'markdown',
49
- title: 'Hello',
50
- description: 'First post',
51
- date: '2026-04-03',
52
- draft: false,
53
- body: '<h1>Hello</h1>',
54
- toc: [{ depth: 1, id: 'hello', text: 'Hello' }],
55
- excerpt: '<p>Intro</p>',
56
- },
57
- ]
58
-
59
- it('writes manifest.json with lean ContentMeta (no body/toc/excerpt/_file)', () => {
60
- const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
61
- emitContentFiles(items, outDir, '{}')
62
- const manifest = JSON.parse(readFileSync(join(outDir, '_content/manifest.json'), 'utf-8'))
63
- expect(Array.isArray(manifest)).toBe(true)
64
- expect(manifest).toHaveLength(2)
65
- const root = manifest.find((m: { _path: string }) => m._path === '/')
66
- expect(root.title).toBe('Home')
67
- expect('body' in root).toBe(false)
68
- expect('toc' in root).toBe(false)
69
- expect('excerpt' in root).toBe(false)
70
- expect('_file' in root).toBe(false)
71
- })
72
-
73
- it('writes search-index.json with provided content', () => {
74
- const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
75
- emitContentFiles(items, outDir, '{"test":true}')
76
- const idx = JSON.parse(readFileSync(join(outDir, '_content/search-index.json'), 'utf-8'))
77
- expect(idx).toEqual({ test: true })
78
- })
79
-
80
- it('writes root document to _content/index.json', () => {
81
- const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
82
- emitContentFiles(items, outDir, '{}')
83
- expect(existsSync(join(outDir, '_content/index.json'))).toBe(true)
84
- const doc = JSON.parse(readFileSync(join(outDir, '_content/index.json'), 'utf-8'))
85
- expect(doc._path).toBe('/')
86
- expect(doc.body).toBe('<h1>Home</h1>')
87
- })
88
-
89
- it('writes nested document to correct subdirectory', () => {
90
- const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
91
- emitContentFiles(items, outDir, '{}')
92
- const docPath = join(outDir, '_content/blog/hello.json')
93
- expect(existsSync(docPath)).toBe(true)
94
- const doc = JSON.parse(readFileSync(docPath, 'utf-8'))
95
- expect(doc._path).toBe('/blog/hello')
96
- expect(doc.toc).toEqual([{ depth: 1, id: 'hello', text: 'Hello' }])
97
- expect(doc.excerpt).toBe('<p>Intro</p>')
98
- })
99
-
100
- it('coexisting blog.json and blog/ dir is allowed', () => {
101
- const items2: ContentItem[] = [
102
- ...items,
103
- {
104
- _path: '/blog',
105
- _file: 'blog/index.md',
106
- _type: 'markdown',
107
- title: 'Blog',
108
- body: '<p>Blog</p>',
109
- toc: [],
110
- },
111
- ]
112
- const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
113
- emitContentFiles(items2, outDir, '{}')
114
- expect(existsSync(join(outDir, '_content/blog.json'))).toBe(true)
115
- expect(existsSync(join(outDir, '_content/blog/hello.json'))).toBe(true)
116
- })
117
- })