@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,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
- })