@jasonshimmy/vite-plugin-cer-app 0.23.2 → 0.25.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 (404) hide show
  1. package/dist/cli/adapters/netlify.js +4 -2
  2. package/dist/cli/adapters/netlify.js.map +1 -1
  3. package/dist/cli/checks/lighthouse.d.ts +26 -0
  4. package/dist/cli/checks/lighthouse.d.ts.map +1 -0
  5. package/dist/cli/checks/lighthouse.js +121 -0
  6. package/dist/cli/checks/lighthouse.js.map +1 -0
  7. package/dist/cli/checks/links.d.ts +12 -0
  8. package/dist/cli/checks/links.d.ts.map +1 -0
  9. package/dist/cli/checks/links.js +89 -0
  10. package/dist/cli/checks/links.js.map +1 -0
  11. package/dist/cli/checks/performance.d.ts +17 -0
  12. package/dist/cli/checks/performance.d.ts.map +1 -0
  13. package/dist/cli/checks/performance.js +61 -0
  14. package/dist/cli/checks/performance.js.map +1 -0
  15. package/dist/cli/commands/check.d.ts +3 -0
  16. package/dist/cli/commands/check.d.ts.map +1 -0
  17. package/dist/cli/commands/check.js +85 -0
  18. package/dist/cli/commands/check.js.map +1 -0
  19. package/dist/cli/commands/preview.d.ts.map +1 -1
  20. package/dist/cli/commands/preview.js +4 -2
  21. package/dist/cli/commands/preview.js.map +1 -1
  22. package/dist/cli/create/index.d.ts +11 -1
  23. package/dist/cli/create/index.d.ts.map +1 -1
  24. package/dist/cli/create/index.js +135 -65
  25. package/dist/cli/create/index.js.map +1 -1
  26. package/dist/cli/create/templates/spa/package.json.tpl +5 -3
  27. package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
  28. package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
  29. package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
  30. package/dist/cli/index.js +2 -0
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/index.d.ts +4 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/plugin/build-ssg.d.ts +22 -6
  35. package/dist/plugin/build-ssg.d.ts.map +1 -1
  36. package/dist/plugin/build-ssg.js +226 -17
  37. package/dist/plugin/build-ssg.js.map +1 -1
  38. package/dist/plugin/content/index.d.ts +1 -1
  39. package/dist/plugin/content/index.d.ts.map +1 -1
  40. package/dist/plugin/content/index.js +8 -8
  41. package/dist/plugin/content/index.js.map +1 -1
  42. package/dist/plugin/content/parser.d.ts +3 -3
  43. package/dist/plugin/content/parser.d.ts.map +1 -1
  44. package/dist/plugin/content/parser.js +103 -24
  45. package/dist/plugin/content/parser.js.map +1 -1
  46. package/dist/plugin/dev-server.d.ts +4 -1
  47. package/dist/plugin/dev-server.d.ts.map +1 -1
  48. package/dist/plugin/dev-server.js.map +1 -1
  49. package/dist/plugin/dts-generator.d.ts.map +1 -1
  50. package/dist/plugin/dts-generator.js +50 -8
  51. package/dist/plugin/dts-generator.js.map +1 -1
  52. package/dist/plugin/generated-dir.d.ts +2 -0
  53. package/dist/plugin/generated-dir.d.ts.map +1 -1
  54. package/dist/plugin/generated-dir.js +17 -6
  55. package/dist/plugin/generated-dir.js.map +1 -1
  56. package/dist/plugin/html-post-process.d.ts +7 -0
  57. package/dist/plugin/html-post-process.d.ts.map +1 -1
  58. package/dist/plugin/html-post-process.js +26 -0
  59. package/dist/plugin/html-post-process.js.map +1 -1
  60. package/dist/plugin/index.d.ts.map +1 -1
  61. package/dist/plugin/index.js +60 -13
  62. package/dist/plugin/index.js.map +1 -1
  63. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  64. package/dist/plugin/transforms/auto-import.js +7 -0
  65. package/dist/plugin/transforms/auto-import.js.map +1 -1
  66. package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
  67. package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
  68. package/dist/plugin/transforms/prune-runtime-css.js +40 -0
  69. package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
  70. package/dist/runtime/app-template.d.ts +1 -1
  71. package/dist/runtime/app-template.d.ts.map +1 -1
  72. package/dist/runtime/app-template.js +206 -36
  73. package/dist/runtime/app-template.js.map +1 -1
  74. package/dist/runtime/composables/index.d.ts +4 -0
  75. package/dist/runtime/composables/index.d.ts.map +1 -1
  76. package/dist/runtime/composables/index.js +2 -0
  77. package/dist/runtime/composables/index.js.map +1 -1
  78. package/dist/runtime/composables/use-active-headings.d.ts +24 -0
  79. package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
  80. package/dist/runtime/composables/use-active-headings.js +112 -0
  81. package/dist/runtime/composables/use-active-headings.js.map +1 -0
  82. package/dist/runtime/composables/use-content-page.d.ts +45 -0
  83. package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
  84. package/dist/runtime/composables/use-content-page.js +181 -0
  85. package/dist/runtime/composables/use-content-page.js.map +1 -0
  86. package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
  87. package/dist/runtime/composables/use-content-search.js +1 -5
  88. package/dist/runtime/composables/use-content-search.js.map +1 -1
  89. package/dist/runtime/composables/use-fetch.d.ts +2 -1
  90. package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
  91. package/dist/runtime/composables/use-fetch.js +112 -43
  92. package/dist/runtime/composables/use-fetch.js.map +1 -1
  93. package/dist/runtime/composables/use-route.d.ts.map +1 -1
  94. package/dist/runtime/composables/use-route.js +39 -11
  95. package/dist/runtime/composables/use-route.js.map +1 -1
  96. package/dist/runtime/content/client.js +2 -2
  97. package/dist/runtime/content/client.js.map +1 -1
  98. package/dist/runtime/entry-server-template.d.ts +16 -1
  99. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  100. package/dist/runtime/entry-server-template.js +120 -13
  101. package/dist/runtime/entry-server-template.js.map +1 -1
  102. package/dist/types/config.d.ts +45 -4
  103. package/dist/types/config.d.ts.map +1 -1
  104. package/dist/types/config.js.map +1 -1
  105. package/dist/types/content.d.ts +18 -1
  106. package/dist/types/content.d.ts.map +1 -1
  107. package/dist/types/middleware.d.ts +2 -2
  108. package/dist/types/middleware.d.ts.map +1 -1
  109. package/package.json +22 -19
  110. package/.github/copilot-instructions.md +0 -169
  111. package/.github/workflows/publish.yml +0 -257
  112. package/.nvmrc +0 -1
  113. package/CHANGELOG.md +0 -236
  114. package/CLAUDE.md +0 -113
  115. package/commits.txt +0 -1
  116. package/cypress.config.ts +0 -16
  117. package/docs/authentication.md +0 -285
  118. package/docs/cli.md +0 -324
  119. package/docs/components.md +0 -237
  120. package/docs/composables.md +0 -907
  121. package/docs/configuration.md +0 -696
  122. package/docs/content.md +0 -570
  123. package/docs/data-loading.md +0 -336
  124. package/docs/getting-started.md +0 -237
  125. package/docs/head-management.md +0 -212
  126. package/docs/i18n.md +0 -159
  127. package/docs/layouts.md +0 -224
  128. package/docs/middleware.md +0 -234
  129. package/docs/plugins.md +0 -170
  130. package/docs/rendering-modes.md +0 -377
  131. package/docs/routing.md +0 -485
  132. package/docs/server-api.md +0 -253
  133. package/docs/testing.md +0 -455
  134. package/docs/use-fetch.md +0 -183
  135. package/e2e/cypress/e2e/api.cy.ts +0 -123
  136. package/e2e/cypress/e2e/async-component.cy.ts +0 -27
  137. package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
  138. package/e2e/cypress/e2e/content.cy.ts +0 -425
  139. package/e2e/cypress/e2e/cookie.cy.ts +0 -85
  140. package/e2e/cypress/e2e/data.cy.ts +0 -158
  141. package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
  142. package/e2e/cypress/e2e/fouc.cy.ts +0 -254
  143. package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
  144. package/e2e/cypress/e2e/head.cy.ts +0 -89
  145. package/e2e/cypress/e2e/i18n.cy.ts +0 -79
  146. package/e2e/cypress/e2e/interactive.cy.ts +0 -137
  147. package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
  148. package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
  149. package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
  150. package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
  151. package/e2e/cypress/e2e/middleware.cy.ts +0 -45
  152. package/e2e/cypress/e2e/navigate.cy.ts +0 -39
  153. package/e2e/cypress/e2e/observability.cy.ts +0 -77
  154. package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
  155. package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
  156. package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
  157. package/e2e/cypress/e2e/routes.cy.ts +0 -128
  158. package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
  159. package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
  160. package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
  161. package/e2e/cypress/e2e/session.cy.ts +0 -73
  162. package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
  163. package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
  164. package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
  165. package/e2e/cypress/e2e/use-state.cy.ts +0 -138
  166. package/e2e/cypress/support/commands.ts +0 -120
  167. package/e2e/cypress/support/e2e.ts +0 -10
  168. package/e2e/cypress/tsconfig.json +0 -14
  169. package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
  170. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
  171. package/e2e/kitchen-sink/app/error.ts +0 -18
  172. package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
  173. package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
  174. package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
  175. package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
  176. package/e2e/kitchen-sink/app/loading.ts +0 -9
  177. package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
  178. package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
  179. package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
  180. package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
  181. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
  182. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
  183. package/e2e/kitchen-sink/app/pages/404.ts +0 -9
  184. package/e2e/kitchen-sink/app/pages/about.ts +0 -17
  185. package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
  186. package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
  187. package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
  188. package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
  189. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
  190. package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
  191. package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
  192. package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
  193. package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
  194. package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
  195. package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
  196. package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
  197. package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
  198. package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
  199. package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
  200. package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
  201. package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
  202. package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
  203. package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
  204. package/e2e/kitchen-sink/app/pages/head.ts +0 -20
  205. package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
  206. package/e2e/kitchen-sink/app/pages/index.ts +0 -27
  207. package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
  208. package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
  209. package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
  210. package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
  211. package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
  212. package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
  213. package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
  214. package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
  215. package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
  216. package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
  217. package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
  218. package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
  219. package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
  220. package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
  221. package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
  222. package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
  223. package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
  224. package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
  225. package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
  226. package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
  227. package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
  228. package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
  229. package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
  230. package/e2e/kitchen-sink/cer-env.d.ts +0 -35
  231. package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
  232. package/e2e/kitchen-sink/cer.config.ts +0 -43
  233. package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
  234. package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
  235. package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
  236. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
  237. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
  238. package/e2e/kitchen-sink/content/blog/index.md +0 -8
  239. package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
  240. package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
  241. package/e2e/kitchen-sink/content/index.md +0 -16
  242. package/e2e/kitchen-sink/server/api/echo.ts +0 -12
  243. package/e2e/kitchen-sink/server/api/health.ts +0 -3
  244. package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
  245. package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
  246. package/e2e/kitchen-sink/server/api/session.ts +0 -23
  247. package/e2e/kitchen-sink/server/data/posts.ts +0 -21
  248. package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
  249. package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
  250. package/e2e/kitchen-sink/tsconfig.json +0 -3
  251. package/e2e/scripts/clean.mjs +0 -14
  252. package/eslint.config.ts +0 -22
  253. package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
  254. package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
  255. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
  256. package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
  257. package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
  258. package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
  259. package/src/__tests__/cli/preview-hardening.test.ts +0 -265
  260. package/src/__tests__/cli/preview-isr.test.ts +0 -320
  261. package/src/__tests__/index.test.ts +0 -21
  262. package/src/__tests__/plugin/app-template.test.ts +0 -166
  263. package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
  264. package/src/__tests__/plugin/build-ssg.test.ts +0 -598
  265. package/src/__tests__/plugin/build-ssr.test.ts +0 -192
  266. package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
  267. package/src/__tests__/plugin/content/emitter.test.ts +0 -117
  268. package/src/__tests__/plugin/content/loader.test.ts +0 -154
  269. package/src/__tests__/plugin/content/parser.test.ts +0 -381
  270. package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
  271. package/src/__tests__/plugin/content/search.test.ts +0 -119
  272. package/src/__tests__/plugin/dev-server.test.ts +0 -813
  273. package/src/__tests__/plugin/dts-generator.test.ts +0 -394
  274. package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
  275. package/src/__tests__/plugin/generated-dir.test.ts +0 -144
  276. package/src/__tests__/plugin/html-post-process.test.ts +0 -146
  277. package/src/__tests__/plugin/path-utils.test.ts +0 -411
  278. package/src/__tests__/plugin/resolve-config.test.ts +0 -233
  279. package/src/__tests__/plugin/scanner.test.ts +0 -186
  280. package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
  281. package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
  282. package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
  283. package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
  284. package/src/__tests__/plugin/virtual/error.test.ts +0 -71
  285. package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
  286. package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
  287. package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
  288. package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
  289. package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
  290. package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
  291. package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
  292. package/src/__tests__/runtime/app-template.test.ts +0 -208
  293. package/src/__tests__/runtime/define-middleware.test.ts +0 -64
  294. package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
  295. package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
  296. package/src/__tests__/runtime/isr-handler.test.ts +0 -338
  297. package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
  298. package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
  299. package/src/__tests__/runtime/oauth-index.test.ts +0 -43
  300. package/src/__tests__/runtime/use-auth.test.ts +0 -169
  301. package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
  302. package/src/__tests__/runtime/use-content-search.test.ts +0 -163
  303. package/src/__tests__/runtime/use-content.test.ts +0 -226
  304. package/src/__tests__/runtime/use-cookie.test.ts +0 -277
  305. package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
  306. package/src/__tests__/runtime/use-fetch.test.ts +0 -377
  307. package/src/__tests__/runtime/use-head.test.ts +0 -311
  308. package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
  309. package/src/__tests__/runtime/use-inject.test.ts +0 -66
  310. package/src/__tests__/runtime/use-locale.test.ts +0 -152
  311. package/src/__tests__/runtime/use-navigate.test.ts +0 -121
  312. package/src/__tests__/runtime/use-page-data.test.ts +0 -298
  313. package/src/__tests__/runtime/use-route.test.ts +0 -156
  314. package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
  315. package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
  316. package/src/__tests__/runtime/use-session.test.ts +0 -320
  317. package/src/__tests__/runtime/use-state.test.ts +0 -340
  318. package/src/__tests__/types/config.test.ts +0 -18
  319. package/src/cli/adapters/cloudflare.ts +0 -335
  320. package/src/cli/adapters/netlify.ts +0 -326
  321. package/src/cli/adapters/vercel.ts +0 -311
  322. package/src/cli/commands/adapt.ts +0 -84
  323. package/src/cli/commands/build.ts +0 -165
  324. package/src/cli/commands/dev.ts +0 -125
  325. package/src/cli/commands/generate.ts +0 -91
  326. package/src/cli/commands/preview-isr.ts +0 -172
  327. package/src/cli/commands/preview.ts +0 -523
  328. package/src/cli/create/index.ts +0 -275
  329. package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
  330. package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
  331. package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
  332. package/src/cli/create/templates/shared/index.html.tpl +0 -12
  333. package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
  334. package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
  335. package/src/cli/create/templates/spa/package.json.tpl +0 -18
  336. package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
  337. package/src/cli/create/templates/ssg/package.json.tpl +0 -19
  338. package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
  339. package/src/cli/create/templates/ssr/package.json.tpl +0 -18
  340. package/src/cli/index.ts +0 -22
  341. package/src/index.ts +0 -20
  342. package/src/plugin/build-ssg.ts +0 -403
  343. package/src/plugin/build-ssr.ts +0 -134
  344. package/src/plugin/content/emitter.ts +0 -50
  345. package/src/plugin/content/index.ts +0 -233
  346. package/src/plugin/content/parser.ts +0 -259
  347. package/src/plugin/content/path-utils.ts +0 -55
  348. package/src/plugin/content/scanner.ts +0 -26
  349. package/src/plugin/content/search.ts +0 -28
  350. package/src/plugin/dev-server.ts +0 -379
  351. package/src/plugin/dts-generator.ts +0 -273
  352. package/src/plugin/generated-dir.ts +0 -121
  353. package/src/plugin/html-post-process.ts +0 -96
  354. package/src/plugin/index.ts +0 -584
  355. package/src/plugin/path-utils.ts +0 -186
  356. package/src/plugin/scanner.ts +0 -65
  357. package/src/plugin/transforms/auto-import.ts +0 -206
  358. package/src/plugin/transforms/head-inject.ts +0 -161
  359. package/src/plugin/virtual/composables.ts +0 -28
  360. package/src/plugin/virtual/content-components.ts +0 -83
  361. package/src/plugin/virtual/error.ts +0 -34
  362. package/src/plugin/virtual/layouts.ts +0 -41
  363. package/src/plugin/virtual/loading.ts +0 -32
  364. package/src/plugin/virtual/middleware.ts +0 -45
  365. package/src/plugin/virtual/plugins.ts +0 -46
  366. package/src/plugin/virtual/routes.ts +0 -514
  367. package/src/plugin/virtual/server-api.ts +0 -85
  368. package/src/plugin/virtual/server-middleware.ts +0 -44
  369. package/src/runtime/app-template.ts +0 -377
  370. package/src/runtime/composables/define-middleware.ts +0 -17
  371. package/src/runtime/composables/define-server-middleware.ts +0 -18
  372. package/src/runtime/composables/index.ts +0 -27
  373. package/src/runtime/composables/use-auth.ts +0 -125
  374. package/src/runtime/composables/use-content-search.ts +0 -205
  375. package/src/runtime/composables/use-content.ts +0 -146
  376. package/src/runtime/composables/use-cookie.ts +0 -135
  377. package/src/runtime/composables/use-fetch.ts +0 -438
  378. package/src/runtime/composables/use-head.ts +0 -234
  379. package/src/runtime/composables/use-inject.ts +0 -49
  380. package/src/runtime/composables/use-locale.ts +0 -109
  381. package/src/runtime/composables/use-navigate.ts +0 -58
  382. package/src/runtime/composables/use-page-data.ts +0 -93
  383. package/src/runtime/composables/use-route.ts +0 -71
  384. package/src/runtime/composables/use-runtime-config.ts +0 -123
  385. package/src/runtime/composables/use-seo-meta.ts +0 -80
  386. package/src/runtime/composables/use-session.ts +0 -186
  387. package/src/runtime/composables/use-state.ts +0 -92
  388. package/src/runtime/content/client.ts +0 -168
  389. package/src/runtime/entry-client-template.ts +0 -39
  390. package/src/runtime/entry-server-template.ts +0 -493
  391. package/src/runtime/isr-handler.ts +0 -184
  392. package/src/runtime/oauth/handler.ts +0 -407
  393. package/src/runtime/oauth/index.ts +0 -49
  394. package/src/runtime/oauth/providers.ts +0 -38
  395. package/src/types/api.ts +0 -40
  396. package/src/types/config.ts +0 -379
  397. package/src/types/content.ts +0 -66
  398. package/src/types/index.ts +0 -7
  399. package/src/types/middleware.ts +0 -63
  400. package/src/types/page.ts +0 -117
  401. package/src/types/plugin.ts +0 -34
  402. package/tsconfig.build.json +0 -10
  403. package/tsconfig.json +0 -19
  404. 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
- })