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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/dist/cli/checks/lighthouse.d.ts +26 -0
  2. package/dist/cli/checks/lighthouse.d.ts.map +1 -0
  3. package/dist/cli/checks/lighthouse.js +121 -0
  4. package/dist/cli/checks/lighthouse.js.map +1 -0
  5. package/dist/cli/checks/links.d.ts +12 -0
  6. package/dist/cli/checks/links.d.ts.map +1 -0
  7. package/dist/cli/checks/links.js +89 -0
  8. package/dist/cli/checks/links.js.map +1 -0
  9. package/dist/cli/checks/performance.d.ts +17 -0
  10. package/dist/cli/checks/performance.d.ts.map +1 -0
  11. package/dist/cli/checks/performance.js +61 -0
  12. package/dist/cli/checks/performance.js.map +1 -0
  13. package/dist/cli/commands/check.d.ts +3 -0
  14. package/dist/cli/commands/check.d.ts.map +1 -0
  15. package/dist/cli/commands/check.js +85 -0
  16. package/dist/cli/commands/check.js.map +1 -0
  17. package/dist/cli/create/index.d.ts +11 -1
  18. package/dist/cli/create/index.d.ts.map +1 -1
  19. package/dist/cli/create/index.js +135 -65
  20. package/dist/cli/create/index.js.map +1 -1
  21. package/dist/cli/create/templates/spa/package.json.tpl +5 -3
  22. package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
  23. package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
  24. package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
  25. package/dist/cli/index.js +2 -0
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/index.d.ts +3 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/plugin/build-ssg.d.ts +22 -6
  30. package/dist/plugin/build-ssg.d.ts.map +1 -1
  31. package/dist/plugin/build-ssg.js +227 -17
  32. package/dist/plugin/build-ssg.js.map +1 -1
  33. package/dist/plugin/content/parser.d.ts.map +1 -1
  34. package/dist/plugin/content/parser.js +54 -10
  35. package/dist/plugin/content/parser.js.map +1 -1
  36. package/dist/plugin/dev-server.d.ts +4 -1
  37. package/dist/plugin/dev-server.d.ts.map +1 -1
  38. package/dist/plugin/dev-server.js.map +1 -1
  39. package/dist/plugin/dts-generator.d.ts.map +1 -1
  40. package/dist/plugin/dts-generator.js +50 -8
  41. package/dist/plugin/dts-generator.js.map +1 -1
  42. package/dist/plugin/generated-dir.d.ts +2 -0
  43. package/dist/plugin/generated-dir.d.ts.map +1 -1
  44. package/dist/plugin/generated-dir.js +17 -6
  45. package/dist/plugin/generated-dir.js.map +1 -1
  46. package/dist/plugin/html-post-process.d.ts +6 -0
  47. package/dist/plugin/html-post-process.d.ts.map +1 -1
  48. package/dist/plugin/html-post-process.js +24 -0
  49. package/dist/plugin/html-post-process.js.map +1 -1
  50. package/dist/plugin/index.d.ts.map +1 -1
  51. package/dist/plugin/index.js +60 -13
  52. package/dist/plugin/index.js.map +1 -1
  53. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  54. package/dist/plugin/transforms/auto-import.js +7 -0
  55. package/dist/plugin/transforms/auto-import.js.map +1 -1
  56. package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
  57. package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
  58. package/dist/plugin/transforms/prune-runtime-css.js +40 -0
  59. package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
  60. package/dist/runtime/app-template.d.ts +1 -1
  61. package/dist/runtime/app-template.d.ts.map +1 -1
  62. package/dist/runtime/app-template.js +206 -36
  63. package/dist/runtime/app-template.js.map +1 -1
  64. package/dist/runtime/composables/index.d.ts +4 -0
  65. package/dist/runtime/composables/index.d.ts.map +1 -1
  66. package/dist/runtime/composables/index.js +2 -0
  67. package/dist/runtime/composables/index.js.map +1 -1
  68. package/dist/runtime/composables/use-active-headings.d.ts +24 -0
  69. package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
  70. package/dist/runtime/composables/use-active-headings.js +112 -0
  71. package/dist/runtime/composables/use-active-headings.js.map +1 -0
  72. package/dist/runtime/composables/use-content-page.d.ts +45 -0
  73. package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
  74. package/dist/runtime/composables/use-content-page.js +179 -0
  75. package/dist/runtime/composables/use-content-page.js.map +1 -0
  76. package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
  77. package/dist/runtime/composables/use-content-search.js +1 -5
  78. package/dist/runtime/composables/use-content-search.js.map +1 -1
  79. package/dist/runtime/composables/use-fetch.d.ts +2 -1
  80. package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
  81. package/dist/runtime/composables/use-fetch.js +112 -43
  82. package/dist/runtime/composables/use-fetch.js.map +1 -1
  83. package/dist/runtime/composables/use-route.d.ts.map +1 -1
  84. package/dist/runtime/composables/use-route.js +39 -11
  85. package/dist/runtime/composables/use-route.js.map +1 -1
  86. package/dist/runtime/content/client.js +2 -2
  87. package/dist/runtime/content/client.js.map +1 -1
  88. package/dist/runtime/entry-server-template.d.ts +16 -1
  89. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  90. package/dist/runtime/entry-server-template.js +120 -13
  91. package/dist/runtime/entry-server-template.js.map +1 -1
  92. package/dist/types/config.d.ts +45 -4
  93. package/dist/types/config.d.ts.map +1 -1
  94. package/dist/types/config.js.map +1 -1
  95. package/dist/types/middleware.d.ts +2 -2
  96. package/dist/types/middleware.d.ts.map +1 -1
  97. package/package.json +22 -19
  98. package/.github/copilot-instructions.md +0 -169
  99. package/.github/workflows/publish.yml +0 -257
  100. package/.nvmrc +0 -1
  101. package/CHANGELOG.md +0 -236
  102. package/CLAUDE.md +0 -113
  103. package/commits.txt +0 -1
  104. package/cypress.config.ts +0 -16
  105. package/docs/authentication.md +0 -285
  106. package/docs/cli.md +0 -324
  107. package/docs/components.md +0 -237
  108. package/docs/composables.md +0 -907
  109. package/docs/configuration.md +0 -696
  110. package/docs/content.md +0 -570
  111. package/docs/data-loading.md +0 -336
  112. package/docs/getting-started.md +0 -237
  113. package/docs/head-management.md +0 -212
  114. package/docs/i18n.md +0 -159
  115. package/docs/layouts.md +0 -224
  116. package/docs/middleware.md +0 -234
  117. package/docs/plugins.md +0 -170
  118. package/docs/rendering-modes.md +0 -377
  119. package/docs/routing.md +0 -485
  120. package/docs/server-api.md +0 -253
  121. package/docs/testing.md +0 -455
  122. package/docs/use-fetch.md +0 -183
  123. package/e2e/cypress/e2e/api.cy.ts +0 -123
  124. package/e2e/cypress/e2e/async-component.cy.ts +0 -27
  125. package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
  126. package/e2e/cypress/e2e/content.cy.ts +0 -425
  127. package/e2e/cypress/e2e/cookie.cy.ts +0 -85
  128. package/e2e/cypress/e2e/data.cy.ts +0 -158
  129. package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
  130. package/e2e/cypress/e2e/fouc.cy.ts +0 -254
  131. package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
  132. package/e2e/cypress/e2e/head.cy.ts +0 -89
  133. package/e2e/cypress/e2e/i18n.cy.ts +0 -79
  134. package/e2e/cypress/e2e/interactive.cy.ts +0 -137
  135. package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
  136. package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
  137. package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
  138. package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
  139. package/e2e/cypress/e2e/middleware.cy.ts +0 -45
  140. package/e2e/cypress/e2e/navigate.cy.ts +0 -39
  141. package/e2e/cypress/e2e/observability.cy.ts +0 -77
  142. package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
  143. package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
  144. package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
  145. package/e2e/cypress/e2e/routes.cy.ts +0 -128
  146. package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
  147. package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
  148. package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
  149. package/e2e/cypress/e2e/session.cy.ts +0 -73
  150. package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
  151. package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
  152. package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
  153. package/e2e/cypress/e2e/use-state.cy.ts +0 -138
  154. package/e2e/cypress/support/commands.ts +0 -120
  155. package/e2e/cypress/support/e2e.ts +0 -10
  156. package/e2e/cypress/tsconfig.json +0 -14
  157. package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
  158. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
  159. package/e2e/kitchen-sink/app/error.ts +0 -18
  160. package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
  161. package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
  162. package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
  163. package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
  164. package/e2e/kitchen-sink/app/loading.ts +0 -9
  165. package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
  166. package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
  167. package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
  168. package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
  169. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
  170. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
  171. package/e2e/kitchen-sink/app/pages/404.ts +0 -9
  172. package/e2e/kitchen-sink/app/pages/about.ts +0 -17
  173. package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
  174. package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
  175. package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
  176. package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
  177. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
  178. package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
  179. package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
  180. package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
  181. package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
  182. package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
  183. package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
  184. package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
  185. package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
  186. package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
  187. package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
  188. package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
  189. package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
  190. package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
  191. package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
  192. package/e2e/kitchen-sink/app/pages/head.ts +0 -20
  193. package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
  194. package/e2e/kitchen-sink/app/pages/index.ts +0 -27
  195. package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
  196. package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
  197. package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
  198. package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
  199. package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
  200. package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
  201. package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
  202. package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
  203. package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
  204. package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
  205. package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
  206. package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
  207. package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
  208. package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
  209. package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
  210. package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
  211. package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
  212. package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
  213. package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
  214. package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
  215. package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
  216. package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
  217. package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
  218. package/e2e/kitchen-sink/cer-env.d.ts +0 -35
  219. package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
  220. package/e2e/kitchen-sink/cer.config.ts +0 -43
  221. package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
  222. package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
  223. package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
  224. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
  225. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
  226. package/e2e/kitchen-sink/content/blog/index.md +0 -8
  227. package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
  228. package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
  229. package/e2e/kitchen-sink/content/index.md +0 -16
  230. package/e2e/kitchen-sink/server/api/echo.ts +0 -12
  231. package/e2e/kitchen-sink/server/api/health.ts +0 -3
  232. package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
  233. package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
  234. package/e2e/kitchen-sink/server/api/session.ts +0 -23
  235. package/e2e/kitchen-sink/server/data/posts.ts +0 -21
  236. package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
  237. package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
  238. package/e2e/kitchen-sink/tsconfig.json +0 -3
  239. package/e2e/scripts/clean.mjs +0 -14
  240. package/eslint.config.ts +0 -22
  241. package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
  242. package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
  243. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
  244. package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
  245. package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
  246. package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
  247. package/src/__tests__/cli/preview-hardening.test.ts +0 -265
  248. package/src/__tests__/cli/preview-isr.test.ts +0 -320
  249. package/src/__tests__/index.test.ts +0 -21
  250. package/src/__tests__/plugin/app-template.test.ts +0 -166
  251. package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
  252. package/src/__tests__/plugin/build-ssg.test.ts +0 -598
  253. package/src/__tests__/plugin/build-ssr.test.ts +0 -192
  254. package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
  255. package/src/__tests__/plugin/content/emitter.test.ts +0 -117
  256. package/src/__tests__/plugin/content/loader.test.ts +0 -154
  257. package/src/__tests__/plugin/content/parser.test.ts +0 -381
  258. package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
  259. package/src/__tests__/plugin/content/search.test.ts +0 -119
  260. package/src/__tests__/plugin/dev-server.test.ts +0 -813
  261. package/src/__tests__/plugin/dts-generator.test.ts +0 -394
  262. package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
  263. package/src/__tests__/plugin/generated-dir.test.ts +0 -144
  264. package/src/__tests__/plugin/html-post-process.test.ts +0 -146
  265. package/src/__tests__/plugin/path-utils.test.ts +0 -411
  266. package/src/__tests__/plugin/resolve-config.test.ts +0 -233
  267. package/src/__tests__/plugin/scanner.test.ts +0 -186
  268. package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
  269. package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
  270. package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
  271. package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
  272. package/src/__tests__/plugin/virtual/error.test.ts +0 -71
  273. package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
  274. package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
  275. package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
  276. package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
  277. package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
  278. package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
  279. package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
  280. package/src/__tests__/runtime/app-template.test.ts +0 -208
  281. package/src/__tests__/runtime/define-middleware.test.ts +0 -64
  282. package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
  283. package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
  284. package/src/__tests__/runtime/isr-handler.test.ts +0 -338
  285. package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
  286. package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
  287. package/src/__tests__/runtime/oauth-index.test.ts +0 -43
  288. package/src/__tests__/runtime/use-auth.test.ts +0 -169
  289. package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
  290. package/src/__tests__/runtime/use-content-search.test.ts +0 -163
  291. package/src/__tests__/runtime/use-content.test.ts +0 -226
  292. package/src/__tests__/runtime/use-cookie.test.ts +0 -277
  293. package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
  294. package/src/__tests__/runtime/use-fetch.test.ts +0 -377
  295. package/src/__tests__/runtime/use-head.test.ts +0 -311
  296. package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
  297. package/src/__tests__/runtime/use-inject.test.ts +0 -66
  298. package/src/__tests__/runtime/use-locale.test.ts +0 -152
  299. package/src/__tests__/runtime/use-navigate.test.ts +0 -121
  300. package/src/__tests__/runtime/use-page-data.test.ts +0 -298
  301. package/src/__tests__/runtime/use-route.test.ts +0 -156
  302. package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
  303. package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
  304. package/src/__tests__/runtime/use-session.test.ts +0 -320
  305. package/src/__tests__/runtime/use-state.test.ts +0 -340
  306. package/src/__tests__/types/config.test.ts +0 -18
  307. package/src/cli/adapters/cloudflare.ts +0 -335
  308. package/src/cli/adapters/netlify.ts +0 -326
  309. package/src/cli/adapters/vercel.ts +0 -311
  310. package/src/cli/commands/adapt.ts +0 -84
  311. package/src/cli/commands/build.ts +0 -165
  312. package/src/cli/commands/dev.ts +0 -125
  313. package/src/cli/commands/generate.ts +0 -91
  314. package/src/cli/commands/preview-isr.ts +0 -172
  315. package/src/cli/commands/preview.ts +0 -523
  316. package/src/cli/create/index.ts +0 -275
  317. package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
  318. package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
  319. package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
  320. package/src/cli/create/templates/shared/index.html.tpl +0 -12
  321. package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
  322. package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
  323. package/src/cli/create/templates/spa/package.json.tpl +0 -18
  324. package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
  325. package/src/cli/create/templates/ssg/package.json.tpl +0 -19
  326. package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
  327. package/src/cli/create/templates/ssr/package.json.tpl +0 -18
  328. package/src/cli/index.ts +0 -22
  329. package/src/index.ts +0 -20
  330. package/src/plugin/build-ssg.ts +0 -403
  331. package/src/plugin/build-ssr.ts +0 -134
  332. package/src/plugin/content/emitter.ts +0 -50
  333. package/src/plugin/content/index.ts +0 -233
  334. package/src/plugin/content/parser.ts +0 -259
  335. package/src/plugin/content/path-utils.ts +0 -55
  336. package/src/plugin/content/scanner.ts +0 -26
  337. package/src/plugin/content/search.ts +0 -28
  338. package/src/plugin/dev-server.ts +0 -379
  339. package/src/plugin/dts-generator.ts +0 -273
  340. package/src/plugin/generated-dir.ts +0 -121
  341. package/src/plugin/html-post-process.ts +0 -96
  342. package/src/plugin/index.ts +0 -584
  343. package/src/plugin/path-utils.ts +0 -186
  344. package/src/plugin/scanner.ts +0 -65
  345. package/src/plugin/transforms/auto-import.ts +0 -206
  346. package/src/plugin/transforms/head-inject.ts +0 -161
  347. package/src/plugin/virtual/composables.ts +0 -28
  348. package/src/plugin/virtual/content-components.ts +0 -83
  349. package/src/plugin/virtual/error.ts +0 -34
  350. package/src/plugin/virtual/layouts.ts +0 -41
  351. package/src/plugin/virtual/loading.ts +0 -32
  352. package/src/plugin/virtual/middleware.ts +0 -45
  353. package/src/plugin/virtual/plugins.ts +0 -46
  354. package/src/plugin/virtual/routes.ts +0 -514
  355. package/src/plugin/virtual/server-api.ts +0 -85
  356. package/src/plugin/virtual/server-middleware.ts +0 -44
  357. package/src/runtime/app-template.ts +0 -377
  358. package/src/runtime/composables/define-middleware.ts +0 -17
  359. package/src/runtime/composables/define-server-middleware.ts +0 -18
  360. package/src/runtime/composables/index.ts +0 -27
  361. package/src/runtime/composables/use-auth.ts +0 -125
  362. package/src/runtime/composables/use-content-search.ts +0 -205
  363. package/src/runtime/composables/use-content.ts +0 -146
  364. package/src/runtime/composables/use-cookie.ts +0 -135
  365. package/src/runtime/composables/use-fetch.ts +0 -438
  366. package/src/runtime/composables/use-head.ts +0 -234
  367. package/src/runtime/composables/use-inject.ts +0 -49
  368. package/src/runtime/composables/use-locale.ts +0 -109
  369. package/src/runtime/composables/use-navigate.ts +0 -58
  370. package/src/runtime/composables/use-page-data.ts +0 -93
  371. package/src/runtime/composables/use-route.ts +0 -71
  372. package/src/runtime/composables/use-runtime-config.ts +0 -123
  373. package/src/runtime/composables/use-seo-meta.ts +0 -80
  374. package/src/runtime/composables/use-session.ts +0 -186
  375. package/src/runtime/composables/use-state.ts +0 -92
  376. package/src/runtime/content/client.ts +0 -168
  377. package/src/runtime/entry-client-template.ts +0 -39
  378. package/src/runtime/entry-server-template.ts +0 -493
  379. package/src/runtime/isr-handler.ts +0 -184
  380. package/src/runtime/oauth/handler.ts +0 -407
  381. package/src/runtime/oauth/index.ts +0 -49
  382. package/src/runtime/oauth/providers.ts +0 -38
  383. package/src/types/api.ts +0 -40
  384. package/src/types/config.ts +0 -379
  385. package/src/types/content.ts +0 -66
  386. package/src/types/index.ts +0 -7
  387. package/src/types/middleware.ts +0 -63
  388. package/src/types/page.ts +0 -117
  389. package/src/types/plugin.ts +0 -34
  390. package/tsconfig.build.json +0 -10
  391. package/tsconfig.json +0 -19
  392. package/vitest.config.ts +0 -33
@@ -1,407 +0,0 @@
1
- /**
2
- * OAuth 2.0 request handlers — initiate, callback, and logout.
3
- *
4
- * All three functions run inside a `runWithRequestContext` scope so
5
- * `useSession()` and `useCookie()` work correctly (they read/write HTTP
6
- * headers via AsyncLocalStorage).
7
- *
8
- * Security:
9
- * - PKCE (S256) is used for all providers that support it (Google, Discord).
10
- * GitHub does not support PKCE so it is omitted for that provider.
11
- * - The `state` parameter is a 16-byte random value stored in a short-lived
12
- * (`_oauth_pkce`) session cookie. The callback verifies it before
13
- * exchanging the code, preventing CSRF.
14
- * - `clientSecret` never appears in any client bundle — this file is only
15
- * imported by the server-side virtual:cer-server-api module.
16
- */
17
-
18
- import type { IncomingMessage, ServerResponse } from 'node:http'
19
- import { useSession } from '../composables/use-session.js'
20
- import { OAUTH_PROVIDERS } from './providers.js'
21
-
22
- // ─── Types ────────────────────────────────────────────────────────────────────
23
-
24
- /**
25
- * Normalised OAuth user written to the auth session cookie after a
26
- * successful callback. Also exported from `composables/use-auth.ts` under
27
- * the same name — both definitions are structurally identical and
28
- * TypeScript treats them as compatible.
29
- */
30
- export interface AuthUser {
31
- /** OAuth provider name, e.g. `'google'`, `'github'`, `'discord'`. */
32
- provider: string
33
- /** Provider-issued user id, always coerced to a string. */
34
- id: string
35
- name?: string
36
- email?: string
37
- /** URL of the user's profile picture / avatar. */
38
- avatar?: string
39
- [key: string]: unknown
40
- }
41
-
42
- /**
43
- * Subset of `OAuthProviderConfig` that is serialised into the virtual
44
- * `server-api` module at build time. Only the fields needed at request
45
- * time are included — the full plugin config is NOT exposed to the server
46
- * bundle.
47
- */
48
- interface ResolvedProviderConfig {
49
- clientId: string
50
- clientSecret: string
51
- scope?: string[]
52
- authorizationUrl?: string
53
- tokenUrl?: string
54
- userInfoUrl?: string
55
- }
56
-
57
- /**
58
- * Shape of the `_authCfg` constant injected into the virtual server-api
59
- * module by the plugin.
60
- *
61
- * - `providers` — map of provider name → credentials + optional overrides.
62
- * Built-in providers (`google`, `github`, `discord`) only need
63
- * `clientId` / `clientSecret`; custom providers must supply all three
64
- * endpoint URLs.
65
- * - `redirectAfterLogin` — relative or absolute URL to redirect to after a
66
- * successful OAuth callback (e.g. `'/dashboard'`).
67
- * - `redirectAfterLogout` — URL to redirect to after the logout endpoint
68
- * clears the session cookie (e.g. `'/'`).
69
- * - `sessionKey` — name of the auth session cookie; must match
70
- * `auth.sessionKey` in `cer.config.ts` (defaults to `'auth'`).
71
- */
72
- export interface ResolvedAuthConfig {
73
- providers?: Record<string, ResolvedProviderConfig | undefined>
74
- redirectAfterLogin: string
75
- redirectAfterLogout: string
76
- sessionKey: string
77
- }
78
-
79
- interface PkceSessionData {
80
- state: string
81
- verifier: string
82
- provider: string
83
- [key: string]: unknown
84
- }
85
-
86
- // ─── Web Crypto helpers ───────────────────────────────────────────────────────
87
-
88
- const ENC = new TextEncoder()
89
-
90
- /** Encode an ArrayBuffer as a URL-safe base64 string (no padding). */
91
- function _b64u(buf: ArrayBuffer): string {
92
- return btoa(String.fromCharCode(...new Uint8Array(buf)))
93
- .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
94
- }
95
-
96
- /**
97
- * Generate a 32-byte cryptographically random PKCE code verifier.
98
- * Encoded as base64url per RFC 7636 §4.1.
99
- */
100
- async function generateCodeVerifier(): Promise<string> {
101
- const bytes = new Uint8Array(32)
102
- crypto.getRandomValues(bytes)
103
- return _b64u(bytes.buffer as ArrayBuffer)
104
- }
105
-
106
- /**
107
- * Derive the PKCE S256 code challenge from the verifier.
108
- * `code_challenge = BASE64URL(SHA-256(ASCII(code_verifier)))` — RFC 7636 §4.2.
109
- */
110
- async function generateCodeChallenge(verifier: string): Promise<string> {
111
- const hash = await crypto.subtle.digest('SHA-256', ENC.encode(verifier))
112
- return _b64u(hash)
113
- }
114
-
115
- /**
116
- * Generate a 16-byte cryptographically random state parameter.
117
- * Used to bind the initiate and callback requests (CSRF protection).
118
- */
119
- function generateState(): string {
120
- const bytes = new Uint8Array(16)
121
- crypto.getRandomValues(bytes)
122
- return _b64u(bytes.buffer as ArrayBuffer)
123
- }
124
-
125
- // ─── URL helpers ──────────────────────────────────────────────────────────────
126
-
127
- function getCallbackUrl(req: IncomingMessage, provider: string): string {
128
- const proto = (req.headers['x-forwarded-proto'] as string | undefined) ?? 'http'
129
- const host = (req.headers.host as string | undefined) ?? 'localhost'
130
- return `${proto}://${host}/api/auth/callback/${provider}`
131
- }
132
-
133
- function getQueryParam(req: IncomingMessage, name: string): string | null {
134
- try {
135
- const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`)
136
- return url.searchParams.get(name)
137
- } catch {
138
- return null
139
- }
140
- }
141
-
142
- // ─── Profile normalisation ────────────────────────────────────────────────────
143
-
144
- /**
145
- * Map a raw provider userinfo response to the canonical {@link AuthUser}
146
- * shape. Each provider uses slightly different field names:
147
- *
148
- * | Provider | id field | name field | avatar field |
149
- * |----------|----------------|-------------------------|----------------|
150
- * | google | `id` or `sub` | `name` | `picture` |
151
- * | github | `id` | `name` or `login` | `avatar_url` |
152
- * | discord | `id` | `global_name`/`username`| CDN avatar URL |
153
- *
154
- * Unknown providers fall back to a best-effort mapping using common field
155
- * names (`id`, `sub`, `name`, `username`, `email`, `avatar`, `picture`,
156
- * `avatar_url`). All values are coerced to strings; missing fields become
157
- * empty strings.
158
- */
159
- function normaliseProfile(provider: string, profile: Record<string, unknown>): AuthUser {
160
- switch (provider) {
161
- case 'google':
162
- return {
163
- provider,
164
- id: String(profile.id ?? profile.sub ?? ''),
165
- name: String(profile.name ?? ''),
166
- email: String(profile.email ?? ''),
167
- avatar: String(profile.picture ?? ''),
168
- }
169
- case 'github':
170
- return {
171
- provider,
172
- id: String(profile.id ?? ''),
173
- name: String(profile.name ?? profile.login ?? ''),
174
- email: String(profile.email ?? ''),
175
- avatar: String(profile.avatar_url ?? ''),
176
- }
177
- case 'discord':
178
- return {
179
- provider,
180
- id: String(profile.id ?? ''),
181
- name: String(profile.global_name ?? profile.username ?? ''),
182
- email: String(profile.email ?? ''),
183
- avatar: profile.avatar && profile.id
184
- ? `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.png`
185
- : '',
186
- }
187
- default:
188
- return {
189
- provider,
190
- id: String(profile.id ?? profile.sub ?? ''),
191
- name: String(profile.name ?? (profile.username as string | undefined) ?? ''),
192
- email: String(profile.email ?? ''),
193
- avatar: String(
194
- profile.avatar ?? profile.picture ?? profile.avatar_url ?? '',
195
- ),
196
- }
197
- }
198
- }
199
-
200
- // ─── Public handlers ──────────────────────────────────────────────────────────
201
-
202
- /**
203
- * GET /api/auth/:provider
204
- *
205
- * Generates a PKCE code verifier + state, stores them in a short-lived session
206
- * cookie, and redirects the browser to the provider's authorization URL.
207
- */
208
- export async function handleOAuthInitiate(
209
- req: IncomingMessage,
210
- res: ServerResponse,
211
- provider: string,
212
- config: ResolvedAuthConfig,
213
- ): Promise<void> {
214
- const providerConfig = config.providers?.[provider]
215
- if (!providerConfig) {
216
- res.statusCode = 404
217
- res.end(`[cer-app] Unknown OAuth provider: ${provider}`)
218
- return
219
- }
220
-
221
- const endpoints = OAUTH_PROVIDERS[provider]
222
- const authUrl = providerConfig.authorizationUrl ?? endpoints?.authorizationUrl
223
- if (!authUrl) {
224
- res.statusCode = 500
225
- res.end(`[cer-app] OAuth provider "${provider}" is missing authorizationUrl`)
226
- return
227
- }
228
-
229
- const state = generateState()
230
- const verifier = await generateCodeVerifier()
231
-
232
- // Store state + verifier in a short-lived PKCE session (10 minutes).
233
- const pkceSession = useSession<PkceSessionData>({ name: '_oauth_pkce', maxAge: 600 })
234
- await pkceSession.set({ state, verifier, provider })
235
-
236
- const usePkce = providerConfig.authorizationUrl ? true : (endpoints?.pkce ?? true)
237
- const scopes = providerConfig.scope ?? endpoints?.defaultScopes ?? []
238
-
239
- const params = new URLSearchParams({
240
- client_id: providerConfig.clientId,
241
- redirect_uri: getCallbackUrl(req, provider),
242
- response_type: 'code',
243
- scope: scopes.join(' '),
244
- state,
245
- })
246
-
247
- if (usePkce) {
248
- params.set('code_challenge', await generateCodeChallenge(verifier))
249
- params.set('code_challenge_method', 'S256')
250
- }
251
-
252
- res.statusCode = 302
253
- res.setHeader('Location', `${authUrl}?${params.toString()}`)
254
- res.end()
255
- }
256
-
257
- /**
258
- * GET /api/auth/callback/:provider
259
- *
260
- * Validates the state param, exchanges the authorisation code for tokens,
261
- * fetches the user profile, normalises it, and stores the result in the
262
- * auth session cookie before redirecting to `redirectAfterLogin`.
263
- */
264
- export async function handleOAuthCallback(
265
- req: IncomingMessage,
266
- res: ServerResponse,
267
- provider: string,
268
- config: ResolvedAuthConfig,
269
- ): Promise<void> {
270
- const code = getQueryParam(req, 'code')
271
- const state = getQueryParam(req, 'state')
272
-
273
- if (!code || !state) {
274
- res.statusCode = 400
275
- res.end('[cer-app] OAuth callback missing code or state parameter')
276
- return
277
- }
278
-
279
- // Validate state to prevent CSRF.
280
- const pkceSession = useSession<PkceSessionData>({ name: '_oauth_pkce', maxAge: 600 })
281
- const pkceData = await pkceSession.get()
282
-
283
- if (!pkceData || pkceData.state !== state || pkceData.provider !== provider) {
284
- res.statusCode = 400
285
- res.end('[cer-app] OAuth state mismatch — possible CSRF attempt')
286
- return
287
- }
288
- await pkceSession.clear()
289
-
290
- const providerConfig = config.providers?.[provider]
291
- if (!providerConfig) {
292
- res.statusCode = 404
293
- res.end(`[cer-app] Unknown OAuth provider: ${provider}`)
294
- return
295
- }
296
-
297
- const endpoints = OAUTH_PROVIDERS[provider]
298
- const tokenUrl = providerConfig.tokenUrl ?? endpoints?.tokenUrl
299
- const userInfoUrl = providerConfig.userInfoUrl ?? endpoints?.userInfoUrl
300
-
301
- if (!tokenUrl || !userInfoUrl) {
302
- res.statusCode = 500
303
- res.end(`[cer-app] OAuth provider "${provider}" is missing tokenUrl or userInfoUrl`)
304
- return
305
- }
306
-
307
- // Exchange authorisation code for tokens.
308
- const usePkce = providerConfig.authorizationUrl ? true : (endpoints?.pkce ?? true)
309
- const tokenBody: Record<string, string> = {
310
- grant_type: 'authorization_code',
311
- client_id: providerConfig.clientId,
312
- client_secret: providerConfig.clientSecret,
313
- code,
314
- redirect_uri: getCallbackUrl(req, provider),
315
- }
316
- if (usePkce) {
317
- tokenBody.code_verifier = pkceData.verifier
318
- }
319
-
320
- let tokenRes: Response
321
- try {
322
- tokenRes = await fetch(tokenUrl, {
323
- method: 'POST',
324
- headers: {
325
- 'Content-Type': 'application/x-www-form-urlencoded',
326
- 'Accept': 'application/json',
327
- },
328
- body: new URLSearchParams(tokenBody).toString(),
329
- })
330
- } catch {
331
- res.statusCode = 502
332
- res.end('[cer-app] OAuth token exchange request failed')
333
- return
334
- }
335
-
336
- if (!tokenRes.ok) {
337
- res.statusCode = 502
338
- res.end('[cer-app] OAuth token exchange returned non-OK status')
339
- return
340
- }
341
-
342
- let tokens: { access_token: string; refresh_token?: string; expires_in?: number; token_type?: string }
343
- try {
344
- tokens = await tokenRes.json() as typeof tokens
345
- } catch {
346
- res.statusCode = 502
347
- res.end('[cer-app] OAuth token exchange returned invalid JSON')
348
- return
349
- }
350
-
351
- // Fetch the user's profile from the provider.
352
- let userRes: Response
353
- try {
354
- userRes = await fetch(userInfoUrl, {
355
- headers: {
356
- 'Authorization': `${tokens.token_type ?? 'Bearer'} ${tokens.access_token}`,
357
- 'Accept': 'application/json',
358
- },
359
- })
360
- } catch {
361
- res.statusCode = 502
362
- res.end('[cer-app] OAuth user-info request failed')
363
- return
364
- }
365
-
366
- if (!userRes.ok) {
367
- res.statusCode = 502
368
- res.end('[cer-app] OAuth user-info returned non-OK status')
369
- return
370
- }
371
-
372
- let profile: Record<string, unknown>
373
- try {
374
- profile = await userRes.json() as Record<string, unknown>
375
- } catch {
376
- res.statusCode = 502
377
- res.end('[cer-app] OAuth user-info returned invalid JSON')
378
- return
379
- }
380
- const user: AuthUser = normaliseProfile(provider, profile)
381
-
382
- // Store the normalised user in the auth session cookie.
383
- const authSession = useSession<AuthUser>({ name: config.sessionKey })
384
- await authSession.set(user)
385
-
386
- res.statusCode = 302
387
- res.setHeader('Location', config.redirectAfterLogin)
388
- res.end()
389
- }
390
-
391
- /**
392
- * GET /api/auth/logout
393
- *
394
- * Clears the auth session cookie and redirects to `redirectAfterLogout`.
395
- */
396
- export async function handleOAuthLogout(
397
- _req: IncomingMessage,
398
- res: ServerResponse,
399
- config: ResolvedAuthConfig,
400
- ): Promise<void> {
401
- const authSession = useSession({ name: config.sessionKey })
402
- await authSession.clear()
403
-
404
- res.statusCode = 302
405
- res.setHeader('Location', config.redirectAfterLogout)
406
- res.end()
407
- }
@@ -1,49 +0,0 @@
1
- export { handleOAuthInitiate, handleOAuthCallback, handleOAuthLogout } from './handler.js'
2
- export type { AuthUser, ResolvedAuthConfig } from './handler.js'
3
- export { OAUTH_PROVIDERS } from './providers.js'
4
- export type { OAuthEndpoints } from './providers.js'
5
-
6
- /**
7
- * Type-safe helper for declaring an OAuth provider in `cer.config.ts`.
8
- * Returns the config unchanged — exists purely for TypeScript inference.
9
- *
10
- * Built-in providers (`google`, `github`, `discord`) only require `clientId`
11
- * and `clientSecret`. You can override any endpoint URL or supply a custom
12
- * `scope` array. For a provider not listed in `OAUTH_PROVIDERS` you must
13
- * supply all three endpoint URLs (`authorizationUrl`, `tokenUrl`,
14
- * `userInfoUrl`).
15
- *
16
- * @example
17
- * ```ts
18
- * // cer.config.ts
19
- * import { defineConfig } from '@jasonshimmy/vite-plugin-cer-app'
20
- *
21
- * export default defineConfig({
22
- * auth: {
23
- * providers: {
24
- * google: defineOAuthProvider({
25
- * clientId: process.env.GOOGLE_CLIENT_ID!,
26
- * clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
27
- * }),
28
- * github: defineOAuthProvider({
29
- * clientId: process.env.GITHUB_CLIENT_ID!,
30
- * clientSecret: process.env.GITHUB_CLIENT_SECRET!,
31
- * scope: ['read:user', 'user:email', 'read:org'],
32
- * }),
33
- * },
34
- * redirectAfterLogin: '/dashboard',
35
- * redirectAfterLogout: '/',
36
- * },
37
- * })
38
- * ```
39
- */
40
- export function defineOAuthProvider<T extends {
41
- clientId: string
42
- clientSecret: string
43
- scope?: string[]
44
- authorizationUrl?: string
45
- tokenUrl?: string
46
- userInfoUrl?: string
47
- }>(config: T): T {
48
- return config
49
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * Built-in OAuth provider endpoint definitions.
3
- * Users may override any of these by setting `authorizationUrl`, `tokenUrl`,
4
- * or `userInfoUrl` directly on the `OAuthProviderConfig`.
5
- */
6
-
7
- export interface OAuthEndpoints {
8
- authorizationUrl: string
9
- tokenUrl: string
10
- userInfoUrl: string
11
- defaultScopes: string[]
12
- /** Some providers (e.g. GitHub) do not support PKCE. */
13
- pkce: boolean
14
- }
15
-
16
- export const OAUTH_PROVIDERS: Record<string, OAuthEndpoints> = {
17
- google: {
18
- authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth',
19
- tokenUrl: 'https://oauth2.googleapis.com/token',
20
- userInfoUrl: 'https://www.googleapis.com/oauth2/v2/userinfo',
21
- defaultScopes: ['openid', 'email', 'profile'],
22
- pkce: true,
23
- },
24
- github: {
25
- authorizationUrl: 'https://github.com/login/oauth/authorize',
26
- tokenUrl: 'https://github.com/login/oauth/access_token',
27
- userInfoUrl: 'https://api.github.com/user',
28
- defaultScopes: ['read:user', 'user:email'],
29
- pkce: false, // GitHub does not support PKCE
30
- },
31
- discord: {
32
- authorizationUrl: 'https://discord.com/api/oauth2/authorize',
33
- tokenUrl: 'https://discord.com/api/oauth2/token',
34
- userInfoUrl: 'https://discord.com/api/users/@me',
35
- defaultScopes: ['identify', 'email'],
36
- pkce: true,
37
- },
38
- }
package/src/types/api.ts DELETED
@@ -1,40 +0,0 @@
1
- import type { IncomingMessage, ServerResponse } from 'node:http'
2
-
3
- /**
4
- * Augmented Node.js `IncomingMessage` passed to API route handlers.
5
- * Route params and query string are pre-parsed; `body` is parsed from JSON automatically.
6
- */
7
- export interface ApiRequest extends IncomingMessage {
8
- params: Record<string, string>
9
- query: Record<string, string>
10
- body: unknown
11
- }
12
-
13
- /**
14
- * Augmented Node.js `ServerResponse` passed to API route handlers.
15
- * Adds convenience methods for JSON responses and fluent status setting.
16
- */
17
- export interface ApiResponse extends ServerResponse {
18
- json(data: unknown): void
19
- status(code: number): ApiResponse
20
- }
21
-
22
- /**
23
- * Handler function for a file-based API route (`app/api/**\/*.ts`).
24
- *
25
- * @example
26
- * ```ts
27
- * // app/api/posts/[id].ts
28
- * export const GET: ApiHandler = async (req, res) => {
29
- * const post = await fetchPost(req.params.id)
30
- * res.json(post)
31
- * }
32
- * ```
33
- */
34
- export type ApiHandler = (req: ApiRequest, res: ApiResponse) => Promise<void> | void
35
-
36
- /** Combined request/response context passed to API utility functions and composables inside API handlers. */
37
- export interface ApiContext {
38
- req: ApiRequest
39
- res: ApiResponse
40
- }