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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/dist/cli/checks/lighthouse.d.ts +26 -0
  2. package/dist/cli/checks/lighthouse.d.ts.map +1 -0
  3. package/dist/cli/checks/lighthouse.js +121 -0
  4. package/dist/cli/checks/lighthouse.js.map +1 -0
  5. package/dist/cli/checks/links.d.ts +12 -0
  6. package/dist/cli/checks/links.d.ts.map +1 -0
  7. package/dist/cli/checks/links.js +89 -0
  8. package/dist/cli/checks/links.js.map +1 -0
  9. package/dist/cli/checks/performance.d.ts +17 -0
  10. package/dist/cli/checks/performance.d.ts.map +1 -0
  11. package/dist/cli/checks/performance.js +61 -0
  12. package/dist/cli/checks/performance.js.map +1 -0
  13. package/dist/cli/commands/check.d.ts +3 -0
  14. package/dist/cli/commands/check.d.ts.map +1 -0
  15. package/dist/cli/commands/check.js +85 -0
  16. package/dist/cli/commands/check.js.map +1 -0
  17. package/dist/cli/commands/preview.d.ts.map +1 -1
  18. package/dist/cli/commands/preview.js +37 -4
  19. package/dist/cli/commands/preview.js.map +1 -1
  20. package/dist/cli/create/index.d.ts +11 -1
  21. package/dist/cli/create/index.d.ts.map +1 -1
  22. package/dist/cli/create/index.js +135 -65
  23. package/dist/cli/create/index.js.map +1 -1
  24. package/dist/cli/create/templates/spa/package.json.tpl +5 -3
  25. package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
  26. package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
  27. package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
  28. package/dist/cli/index.js +2 -0
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/index.d.ts +3 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/plugin/build-ssg.d.ts +22 -4
  33. package/dist/plugin/build-ssg.d.ts.map +1 -1
  34. package/dist/plugin/build-ssg.js +273 -13
  35. package/dist/plugin/build-ssg.js.map +1 -1
  36. package/dist/plugin/content/parser.d.ts.map +1 -1
  37. package/dist/plugin/content/parser.js +54 -10
  38. package/dist/plugin/content/parser.js.map +1 -1
  39. package/dist/plugin/dev-server.d.ts +6 -1
  40. package/dist/plugin/dev-server.d.ts.map +1 -1
  41. package/dist/plugin/dev-server.js.map +1 -1
  42. package/dist/plugin/dts-generator.d.ts.map +1 -1
  43. package/dist/plugin/dts-generator.js +50 -8
  44. package/dist/plugin/dts-generator.js.map +1 -1
  45. package/dist/plugin/generated-dir.d.ts +2 -0
  46. package/dist/plugin/generated-dir.d.ts.map +1 -1
  47. package/dist/plugin/generated-dir.js +17 -6
  48. package/dist/plugin/generated-dir.js.map +1 -1
  49. package/dist/plugin/html-post-process.d.ts +35 -0
  50. package/dist/plugin/html-post-process.d.ts.map +1 -0
  51. package/dist/plugin/html-post-process.js +112 -0
  52. package/dist/plugin/html-post-process.js.map +1 -0
  53. package/dist/plugin/index.d.ts +9 -0
  54. package/dist/plugin/index.d.ts.map +1 -1
  55. package/dist/plugin/index.js +89 -14
  56. package/dist/plugin/index.js.map +1 -1
  57. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  58. package/dist/plugin/transforms/auto-import.js +7 -0
  59. package/dist/plugin/transforms/auto-import.js.map +1 -1
  60. package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
  61. package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
  62. package/dist/plugin/transforms/prune-runtime-css.js +40 -0
  63. package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
  64. package/dist/runtime/app-template.d.ts +1 -4
  65. package/dist/runtime/app-template.d.ts.map +1 -1
  66. package/dist/runtime/app-template.js +211 -40
  67. package/dist/runtime/app-template.js.map +1 -1
  68. package/dist/runtime/composables/index.d.ts +4 -0
  69. package/dist/runtime/composables/index.d.ts.map +1 -1
  70. package/dist/runtime/composables/index.js +2 -0
  71. package/dist/runtime/composables/index.js.map +1 -1
  72. package/dist/runtime/composables/use-active-headings.d.ts +24 -0
  73. package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
  74. package/dist/runtime/composables/use-active-headings.js +112 -0
  75. package/dist/runtime/composables/use-active-headings.js.map +1 -0
  76. package/dist/runtime/composables/use-content-page.d.ts +45 -0
  77. package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
  78. package/dist/runtime/composables/use-content-page.js +179 -0
  79. package/dist/runtime/composables/use-content-page.js.map +1 -0
  80. package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
  81. package/dist/runtime/composables/use-content-search.js +1 -5
  82. package/dist/runtime/composables/use-content-search.js.map +1 -1
  83. package/dist/runtime/composables/use-fetch.d.ts +2 -1
  84. package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
  85. package/dist/runtime/composables/use-fetch.js +112 -43
  86. package/dist/runtime/composables/use-fetch.js.map +1 -1
  87. package/dist/runtime/composables/use-head.d.ts.map +1 -1
  88. package/dist/runtime/composables/use-head.js +30 -6
  89. package/dist/runtime/composables/use-head.js.map +1 -1
  90. package/dist/runtime/composables/use-route.d.ts.map +1 -1
  91. package/dist/runtime/composables/use-route.js +39 -11
  92. package/dist/runtime/composables/use-route.js.map +1 -1
  93. package/dist/runtime/content/client.js +2 -2
  94. package/dist/runtime/content/client.js.map +1 -1
  95. package/dist/runtime/entry-server-template.d.ts +16 -1
  96. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  97. package/dist/runtime/entry-server-template.js +120 -13
  98. package/dist/runtime/entry-server-template.js.map +1 -1
  99. package/dist/types/config.d.ts +53 -4
  100. package/dist/types/config.d.ts.map +1 -1
  101. package/dist/types/config.js.map +1 -1
  102. package/dist/types/middleware.d.ts +2 -2
  103. package/dist/types/middleware.d.ts.map +1 -1
  104. package/package.json +22 -19
  105. package/.github/copilot-instructions.md +0 -169
  106. package/.github/workflows/publish.yml +0 -257
  107. package/.nvmrc +0 -1
  108. package/CHANGELOG.md +0 -232
  109. package/CLAUDE.md +0 -113
  110. package/commits.txt +0 -1
  111. package/cypress.config.ts +0 -16
  112. package/docs/authentication.md +0 -285
  113. package/docs/cli.md +0 -324
  114. package/docs/components.md +0 -237
  115. package/docs/composables.md +0 -907
  116. package/docs/configuration.md +0 -667
  117. package/docs/content.md +0 -570
  118. package/docs/data-loading.md +0 -336
  119. package/docs/getting-started.md +0 -237
  120. package/docs/head-management.md +0 -212
  121. package/docs/i18n.md +0 -159
  122. package/docs/layouts.md +0 -224
  123. package/docs/middleware.md +0 -234
  124. package/docs/plugins.md +0 -170
  125. package/docs/rendering-modes.md +0 -377
  126. package/docs/routing.md +0 -485
  127. package/docs/server-api.md +0 -253
  128. package/docs/testing.md +0 -455
  129. package/docs/use-fetch.md +0 -183
  130. package/e2e/cypress/e2e/api.cy.ts +0 -123
  131. package/e2e/cypress/e2e/async-component.cy.ts +0 -27
  132. package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
  133. package/e2e/cypress/e2e/content.cy.ts +0 -425
  134. package/e2e/cypress/e2e/cookie.cy.ts +0 -85
  135. package/e2e/cypress/e2e/data.cy.ts +0 -158
  136. package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
  137. package/e2e/cypress/e2e/fouc.cy.ts +0 -254
  138. package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
  139. package/e2e/cypress/e2e/head.cy.ts +0 -89
  140. package/e2e/cypress/e2e/i18n.cy.ts +0 -79
  141. package/e2e/cypress/e2e/interactive.cy.ts +0 -137
  142. package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
  143. package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
  144. package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
  145. package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
  146. package/e2e/cypress/e2e/middleware.cy.ts +0 -45
  147. package/e2e/cypress/e2e/navigate.cy.ts +0 -39
  148. package/e2e/cypress/e2e/observability.cy.ts +0 -77
  149. package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
  150. package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
  151. package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
  152. package/e2e/cypress/e2e/routes.cy.ts +0 -128
  153. package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
  154. package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
  155. package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
  156. package/e2e/cypress/e2e/session.cy.ts +0 -73
  157. package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
  158. package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
  159. package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
  160. package/e2e/cypress/e2e/use-state.cy.ts +0 -138
  161. package/e2e/cypress/support/commands.ts +0 -120
  162. package/e2e/cypress/support/e2e.ts +0 -10
  163. package/e2e/cypress/tsconfig.json +0 -14
  164. package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
  165. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
  166. package/e2e/kitchen-sink/app/error.ts +0 -18
  167. package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
  168. package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
  169. package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
  170. package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
  171. package/e2e/kitchen-sink/app/loading.ts +0 -9
  172. package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
  173. package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
  174. package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
  175. package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
  176. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
  177. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
  178. package/e2e/kitchen-sink/app/pages/404.ts +0 -9
  179. package/e2e/kitchen-sink/app/pages/about.ts +0 -17
  180. package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
  181. package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
  182. package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
  183. package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
  184. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
  185. package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
  186. package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
  187. package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
  188. package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
  189. package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
  190. package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
  191. package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
  192. package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
  193. package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
  194. package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
  195. package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
  196. package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
  197. package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
  198. package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
  199. package/e2e/kitchen-sink/app/pages/head.ts +0 -20
  200. package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
  201. package/e2e/kitchen-sink/app/pages/index.ts +0 -27
  202. package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
  203. package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
  204. package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
  205. package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
  206. package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
  207. package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
  208. package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
  209. package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
  210. package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
  211. package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
  212. package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
  213. package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
  214. package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
  215. package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
  216. package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
  217. package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
  218. package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
  219. package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
  220. package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
  221. package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
  222. package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
  223. package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
  224. package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
  225. package/e2e/kitchen-sink/cer-env.d.ts +0 -35
  226. package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
  227. package/e2e/kitchen-sink/cer.config.ts +0 -43
  228. package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
  229. package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
  230. package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
  231. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
  232. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
  233. package/e2e/kitchen-sink/content/blog/index.md +0 -8
  234. package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
  235. package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
  236. package/e2e/kitchen-sink/content/index.md +0 -16
  237. package/e2e/kitchen-sink/server/api/echo.ts +0 -12
  238. package/e2e/kitchen-sink/server/api/health.ts +0 -3
  239. package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
  240. package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
  241. package/e2e/kitchen-sink/server/api/session.ts +0 -23
  242. package/e2e/kitchen-sink/server/data/posts.ts +0 -21
  243. package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
  244. package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
  245. package/e2e/kitchen-sink/tsconfig.json +0 -3
  246. package/e2e/scripts/clean.mjs +0 -14
  247. package/eslint.config.ts +0 -22
  248. package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
  249. package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
  250. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
  251. package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
  252. package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
  253. package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
  254. package/src/__tests__/cli/preview-hardening.test.ts +0 -265
  255. package/src/__tests__/cli/preview-isr.test.ts +0 -320
  256. package/src/__tests__/index.test.ts +0 -21
  257. package/src/__tests__/plugin/app-template.test.ts +0 -112
  258. package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
  259. package/src/__tests__/plugin/build-ssg.test.ts +0 -598
  260. package/src/__tests__/plugin/build-ssr.test.ts +0 -192
  261. package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
  262. package/src/__tests__/plugin/content/emitter.test.ts +0 -117
  263. package/src/__tests__/plugin/content/loader.test.ts +0 -154
  264. package/src/__tests__/plugin/content/parser.test.ts +0 -381
  265. package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
  266. package/src/__tests__/plugin/content/search.test.ts +0 -119
  267. package/src/__tests__/plugin/dev-server.test.ts +0 -813
  268. package/src/__tests__/plugin/dts-generator.test.ts +0 -394
  269. package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
  270. package/src/__tests__/plugin/generated-dir.test.ts +0 -144
  271. package/src/__tests__/plugin/path-utils.test.ts +0 -411
  272. package/src/__tests__/plugin/resolve-config.test.ts +0 -200
  273. package/src/__tests__/plugin/scanner.test.ts +0 -186
  274. package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
  275. package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
  276. package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
  277. package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
  278. package/src/__tests__/plugin/virtual/error.test.ts +0 -71
  279. package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
  280. package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
  281. package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
  282. package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
  283. package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
  284. package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
  285. package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
  286. package/src/__tests__/runtime/app-template.test.ts +0 -198
  287. package/src/__tests__/runtime/define-middleware.test.ts +0 -64
  288. package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
  289. package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
  290. package/src/__tests__/runtime/isr-handler.test.ts +0 -338
  291. package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
  292. package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
  293. package/src/__tests__/runtime/oauth-index.test.ts +0 -43
  294. package/src/__tests__/runtime/use-auth.test.ts +0 -169
  295. package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
  296. package/src/__tests__/runtime/use-content-search.test.ts +0 -163
  297. package/src/__tests__/runtime/use-content.test.ts +0 -226
  298. package/src/__tests__/runtime/use-cookie.test.ts +0 -277
  299. package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
  300. package/src/__tests__/runtime/use-fetch.test.ts +0 -377
  301. package/src/__tests__/runtime/use-head.test.ts +0 -266
  302. package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
  303. package/src/__tests__/runtime/use-inject.test.ts +0 -66
  304. package/src/__tests__/runtime/use-locale.test.ts +0 -152
  305. package/src/__tests__/runtime/use-navigate.test.ts +0 -121
  306. package/src/__tests__/runtime/use-page-data.test.ts +0 -298
  307. package/src/__tests__/runtime/use-route.test.ts +0 -156
  308. package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
  309. package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
  310. package/src/__tests__/runtime/use-session.test.ts +0 -320
  311. package/src/__tests__/runtime/use-state.test.ts +0 -340
  312. package/src/__tests__/types/config.test.ts +0 -18
  313. package/src/cli/adapters/cloudflare.ts +0 -335
  314. package/src/cli/adapters/netlify.ts +0 -326
  315. package/src/cli/adapters/vercel.ts +0 -311
  316. package/src/cli/commands/adapt.ts +0 -84
  317. package/src/cli/commands/build.ts +0 -165
  318. package/src/cli/commands/dev.ts +0 -125
  319. package/src/cli/commands/generate.ts +0 -91
  320. package/src/cli/commands/preview-isr.ts +0 -172
  321. package/src/cli/commands/preview.ts +0 -489
  322. package/src/cli/create/index.ts +0 -275
  323. package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
  324. package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
  325. package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
  326. package/src/cli/create/templates/shared/index.html.tpl +0 -12
  327. package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
  328. package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
  329. package/src/cli/create/templates/spa/package.json.tpl +0 -18
  330. package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
  331. package/src/cli/create/templates/ssg/package.json.tpl +0 -19
  332. package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
  333. package/src/cli/create/templates/ssr/package.json.tpl +0 -18
  334. package/src/cli/index.ts +0 -22
  335. package/src/index.ts +0 -20
  336. package/src/plugin/build-ssg.ts +0 -336
  337. package/src/plugin/build-ssr.ts +0 -134
  338. package/src/plugin/content/emitter.ts +0 -50
  339. package/src/plugin/content/index.ts +0 -233
  340. package/src/plugin/content/parser.ts +0 -259
  341. package/src/plugin/content/path-utils.ts +0 -55
  342. package/src/plugin/content/scanner.ts +0 -26
  343. package/src/plugin/content/search.ts +0 -28
  344. package/src/plugin/dev-server.ts +0 -377
  345. package/src/plugin/dts-generator.ts +0 -273
  346. package/src/plugin/generated-dir.ts +0 -121
  347. package/src/plugin/index.ts +0 -553
  348. package/src/plugin/path-utils.ts +0 -186
  349. package/src/plugin/scanner.ts +0 -65
  350. package/src/plugin/transforms/auto-import.ts +0 -206
  351. package/src/plugin/transforms/head-inject.ts +0 -161
  352. package/src/plugin/virtual/composables.ts +0 -28
  353. package/src/plugin/virtual/content-components.ts +0 -83
  354. package/src/plugin/virtual/error.ts +0 -34
  355. package/src/plugin/virtual/layouts.ts +0 -41
  356. package/src/plugin/virtual/loading.ts +0 -32
  357. package/src/plugin/virtual/middleware.ts +0 -45
  358. package/src/plugin/virtual/plugins.ts +0 -46
  359. package/src/plugin/virtual/routes.ts +0 -514
  360. package/src/plugin/virtual/server-api.ts +0 -85
  361. package/src/plugin/virtual/server-middleware.ts +0 -44
  362. package/src/runtime/app-template.ts +0 -380
  363. package/src/runtime/composables/define-middleware.ts +0 -17
  364. package/src/runtime/composables/define-server-middleware.ts +0 -18
  365. package/src/runtime/composables/index.ts +0 -27
  366. package/src/runtime/composables/use-auth.ts +0 -125
  367. package/src/runtime/composables/use-content-search.ts +0 -205
  368. package/src/runtime/composables/use-content.ts +0 -146
  369. package/src/runtime/composables/use-cookie.ts +0 -135
  370. package/src/runtime/composables/use-fetch.ts +0 -438
  371. package/src/runtime/composables/use-head.ts +0 -212
  372. package/src/runtime/composables/use-inject.ts +0 -49
  373. package/src/runtime/composables/use-locale.ts +0 -109
  374. package/src/runtime/composables/use-navigate.ts +0 -58
  375. package/src/runtime/composables/use-page-data.ts +0 -93
  376. package/src/runtime/composables/use-route.ts +0 -71
  377. package/src/runtime/composables/use-runtime-config.ts +0 -123
  378. package/src/runtime/composables/use-seo-meta.ts +0 -80
  379. package/src/runtime/composables/use-session.ts +0 -186
  380. package/src/runtime/composables/use-state.ts +0 -92
  381. package/src/runtime/content/client.ts +0 -168
  382. package/src/runtime/entry-client-template.ts +0 -39
  383. package/src/runtime/entry-server-template.ts +0 -493
  384. package/src/runtime/isr-handler.ts +0 -184
  385. package/src/runtime/oauth/handler.ts +0 -407
  386. package/src/runtime/oauth/index.ts +0 -49
  387. package/src/runtime/oauth/providers.ts +0 -38
  388. package/src/types/api.ts +0 -40
  389. package/src/types/config.ts +0 -371
  390. package/src/types/content.ts +0 -66
  391. package/src/types/index.ts +0 -7
  392. package/src/types/middleware.ts +0 -63
  393. package/src/types/page.ts +0 -117
  394. package/src/types/plugin.ts +0 -34
  395. package/tsconfig.build.json +0 -10
  396. package/tsconfig.json +0 -19
  397. package/vitest.config.ts +0 -33
@@ -0,0 +1,26 @@
1
+ export declare const LIGHTHOUSE_CATEGORIES: readonly ["performance", "accessibility", "best-practices", "seo"];
2
+ export declare function median(values: readonly number[]): number;
3
+ export interface LighthouseAuditOptions {
4
+ root?: string;
5
+ urls: string[];
6
+ runs?: number;
7
+ attempts?: number;
8
+ preset?: 'desktop';
9
+ categories?: string[];
10
+ /** Chromium-family executable. Defaults to CHROME_PATH or a known platform installation. */
11
+ chromePath?: string;
12
+ }
13
+ export interface LighthouseUrlReport {
14
+ url: string;
15
+ medians: Record<string, number>;
16
+ }
17
+ export interface ChromiumDiscoveryOptions {
18
+ environment?: Record<string, string | undefined>;
19
+ platform?: NodeJS.Platform;
20
+ exists?: (path: string) => boolean;
21
+ }
22
+ /** Resolve Chrome, Chromium, Edge, or Brave without requiring a global Chrome install. */
23
+ export declare function findChromiumExecutable(options?: ChromiumDiscoveryOptions): string | undefined;
24
+ /** Run repeatable Lighthouse audits using the application's optional local dependency. */
25
+ export declare function runLighthouseAudit(options: LighthouseAuditOptions): Promise<LighthouseUrlReport[]>;
26
+ //# sourceMappingURL=lighthouse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lighthouse.d.ts","sourceRoot":"","sources":["../../../src/cli/checks/lighthouse.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,qBAAqB,oEAKxB,CAAA;AAEV,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAIxD;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,4FAA4F;IAC5F,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAA;IAC1B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;CACnC;AAED,0FAA0F;AAC1F,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,GAAG,SAAS,CA8BjG;AAaD,0FAA0F;AAC1F,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA4DhC"}
@@ -0,0 +1,121 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { mkdtemp, readFile, rm } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
5
+ import { join, resolve } from 'node:path';
6
+ export const LIGHTHOUSE_CATEGORIES = [
7
+ 'performance',
8
+ 'accessibility',
9
+ 'best-practices',
10
+ 'seo',
11
+ ];
12
+ export function median(values) {
13
+ if (values.length === 0)
14
+ return 0;
15
+ const sorted = [...values].sort((a, b) => a - b);
16
+ return sorted[Math.floor(sorted.length / 2)];
17
+ }
18
+ /** Resolve Chrome, Chromium, Edge, or Brave without requiring a global Chrome install. */
19
+ export function findChromiumExecutable(options = {}) {
20
+ const environment = options.environment ?? process.env;
21
+ const platform = options.platform ?? process.platform;
22
+ const exists = options.exists ?? existsSync;
23
+ const explicit = environment.CHROME_PATH?.trim();
24
+ if (explicit)
25
+ return explicit;
26
+ const candidates = platform === 'darwin'
27
+ ? [
28
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
29
+ '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
30
+ '/Applications/Chromium.app/Contents/MacOS/Chromium',
31
+ '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
32
+ '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser',
33
+ ]
34
+ : platform === 'win32'
35
+ ? [
36
+ `${environment.PROGRAMFILES ?? 'C:\\Program Files'}\\Google\\Chrome\\Application\\chrome.exe`,
37
+ `${environment.PROGRAMFILES ?? 'C:\\Program Files'}\\Microsoft\\Edge\\Application\\msedge.exe`,
38
+ `${environment.LOCALAPPDATA ?? ''}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
39
+ ]
40
+ : [
41
+ '/usr/bin/google-chrome',
42
+ '/usr/bin/google-chrome-stable',
43
+ '/usr/bin/chromium',
44
+ '/usr/bin/chromium-browser',
45
+ '/usr/bin/microsoft-edge',
46
+ '/usr/bin/brave-browser',
47
+ ];
48
+ return candidates.find((candidate) => exists(candidate));
49
+ }
50
+ function run(command, args, environment) {
51
+ return new Promise((resolveRun, reject) => {
52
+ const child = spawn(command, args, { stdio: 'inherit', env: environment });
53
+ child.once('error', reject);
54
+ child.once('exit', (code, signal) => {
55
+ if (code === 0)
56
+ resolveRun();
57
+ else
58
+ reject(new Error(`${command} exited with ${code ?? signal}`));
59
+ });
60
+ });
61
+ }
62
+ /** Run repeatable Lighthouse audits using the application's optional local dependency. */
63
+ export async function runLighthouseAudit(options) {
64
+ const root = resolve(options.root ?? process.cwd());
65
+ const cli = join(root, 'node_modules/lighthouse/cli/index.js');
66
+ const categories = options.categories ?? [...LIGHTHOUSE_CATEGORIES];
67
+ const runs = Math.max(1, options.runs ?? 3);
68
+ const attempts = Math.max(1, options.attempts ?? 3);
69
+ const chromePath = options.chromePath?.trim() || findChromiumExecutable();
70
+ const environment = chromePath ? { ...process.env, CHROME_PATH: chromePath } : process.env;
71
+ const reportsDir = await mkdtemp(join(tmpdir(), 'cer-lighthouse-'));
72
+ const result = [];
73
+ try {
74
+ for (const [urlIndex, url] of options.urls.entries()) {
75
+ const scores = Object.fromEntries(categories.map((category) => [category, []]));
76
+ for (let runIndex = 0; runIndex < runs; runIndex += 1) {
77
+ const outputPath = join(reportsDir, `${urlIndex}-${runIndex}.json`);
78
+ const args = [
79
+ cli,
80
+ url,
81
+ '--quiet',
82
+ '--chrome-flags=--headless --no-sandbox',
83
+ `--only-categories=${categories.join(',')}`,
84
+ '--output=json',
85
+ `--output-path=${outputPath}`,
86
+ ];
87
+ if (options.preset)
88
+ args.push(`--preset=${options.preset}`);
89
+ let lastError;
90
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
91
+ try {
92
+ await run(process.execPath, args, environment);
93
+ lastError = undefined;
94
+ break;
95
+ }
96
+ catch (error) {
97
+ lastError = error;
98
+ if (attempt < attempts) {
99
+ await new Promise((resolveWait) => setTimeout(resolveWait, attempt * 250));
100
+ }
101
+ }
102
+ }
103
+ if (lastError)
104
+ throw lastError;
105
+ const report = JSON.parse(await readFile(outputPath, 'utf8'));
106
+ for (const category of categories) {
107
+ scores[category].push(report.categories[category]?.score ?? 0);
108
+ }
109
+ }
110
+ result.push({
111
+ url,
112
+ medians: Object.fromEntries(categories.map((category) => [category, median(scores[category])])),
113
+ });
114
+ }
115
+ return result;
116
+ }
117
+ finally {
118
+ await rm(reportsDir, { recursive: true, force: true });
119
+ }
120
+ }
121
+ //# sourceMappingURL=lighthouse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lighthouse.js","sourceRoot":"","sources":["../../../src/cli/checks/lighthouse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface BuiltLinksOptions {
2
+ outputDir?: string;
3
+ skipTopLevel?: readonly string[];
4
+ }
5
+ export interface BuiltLinksReport {
6
+ pages: number;
7
+ links: number;
8
+ failures: string[];
9
+ }
10
+ /** Validate every internal href and fragment emitted by an SSG build. */
11
+ export declare function checkBuiltLinks(options?: BuiltLinksOptions): Promise<BuiltLinksReport>;
12
+ //# sourceMappingURL=links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../../src/cli/checks/links.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AA8BD,yEAAyE;AACzE,wBAAsB,eAAe,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+ChG"}
@@ -0,0 +1,89 @@
1
+ import { access, readFile, readdir, stat } from 'node:fs/promises';
2
+ import { dirname, join, relative, resolve, sep } from 'node:path';
3
+ async function collectHtml(directory, skipped, depth = 0) {
4
+ const entries = await readdir(directory, { withFileTypes: true });
5
+ const files = [];
6
+ for (const entry of entries) {
7
+ if (depth === 0 && entry.isDirectory() && skipped.has(entry.name))
8
+ continue;
9
+ const path = join(directory, entry.name);
10
+ if (entry.isDirectory())
11
+ files.push(...await collectHtml(path, skipped, depth + 1));
12
+ else if (entry.name === 'index.html')
13
+ files.push(path);
14
+ }
15
+ return files;
16
+ }
17
+ async function exists(path) {
18
+ try {
19
+ await access(path);
20
+ return true;
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ async function isFile(path) {
27
+ try {
28
+ return (await stat(path)).isFile();
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ function escapeRegExp(value) {
35
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
36
+ }
37
+ /** Validate every internal href and fragment emitted by an SSG build. */
38
+ export async function checkBuiltLinks(options = {}) {
39
+ const outputDir = resolve(options.outputDir ?? 'dist');
40
+ const skipped = new Set(options.skipTopLevel ?? ['client', 'server', '_content', 'assets']);
41
+ const pages = await collectHtml(outputDir, skipped);
42
+ const failures = [];
43
+ let links = 0;
44
+ for (const page of pages) {
45
+ const html = await readFile(page, 'utf8');
46
+ const relativeDirectory = relative(outputDir, dirname(page)).split(sep).filter(Boolean).join('/');
47
+ const pageRoute = relativeDirectory ? `/${relativeDirectory}` : '/';
48
+ const base = new URL(pageRoute.endsWith('/') ? pageRoute : `${pageRoute}/`, 'https://local.test');
49
+ const hrefs = [...html.matchAll(/\bhref=(?:"([^"]*)"|'([^']*)')/gi)]
50
+ .map((match) => match[1] ?? match[2]);
51
+ for (const href of hrefs) {
52
+ if (!href || /^(?:https?:|mailto:|tel:|data:|javascript:|\/\/)/i.test(href))
53
+ continue;
54
+ const url = new URL(href, base);
55
+ if (url.origin !== base.origin)
56
+ continue;
57
+ links += 1;
58
+ let pathname = url.pathname;
59
+ try {
60
+ pathname = decodeURIComponent(pathname);
61
+ }
62
+ catch { /* retain encoded path */ }
63
+ const relativeTarget = pathname.replace(/^\/+/, '');
64
+ const directTarget = join(outputDir, relativeTarget);
65
+ const routeTarget = pathname === '/'
66
+ ? join(outputDir, 'index.html')
67
+ : join(outputDir, relativeTarget, 'index.html');
68
+ const target = await isFile(directTarget) ? directTarget : routeTarget;
69
+ if (!(await exists(target))) {
70
+ failures.push(`${relative(outputDir, page)} -> ${href} (missing ${relative(outputDir, target)})`);
71
+ continue;
72
+ }
73
+ if (url.hash && target.endsWith('.html')) {
74
+ let id = url.hash.slice(1);
75
+ try {
76
+ id = decodeURIComponent(id);
77
+ }
78
+ catch { /* retain encoded id */ }
79
+ const targetHtml = target === page ? html : await readFile(target, 'utf8');
80
+ const quotedId = escapeRegExp(id);
81
+ const hasId = new RegExp(`\\bid=(?:"${quotedId}"|'${quotedId}')`, 'i').test(targetHtml);
82
+ if (!hasId)
83
+ failures.push(`${relative(outputDir, page)} -> ${href} (missing #${id})`);
84
+ }
85
+ }
86
+ }
87
+ return { pages: pages.length, links, failures };
88
+ }
89
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../../src/cli/checks/links.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface PerformanceBudgetOptions {
2
+ outputDir?: string;
3
+ page?: string;
4
+ maxHtmlBytes?: number;
5
+ maxInitialJsGzipBytes?: number;
6
+ maxEntryJsGzipBytes?: number;
7
+ expectedPages?: number;
8
+ }
9
+ export interface PerformanceBudgetReport {
10
+ htmlBytes: number;
11
+ initialJsGzipBytes: number;
12
+ entryJsGzipBytes: number;
13
+ failures: string[];
14
+ }
15
+ /** Measure framework-neutral SSG output budgets and build-integrity signals. */
16
+ export declare function checkPerformanceBudgets(options?: PerformanceBudgetOptions): Promise<PerformanceBudgetReport>;
17
+ //# sourceMappingURL=performance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../../../src/cli/checks/performance.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,gFAAgF;AAChF,wBAAsB,uBAAuB,CAC3C,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,CAkElC"}
@@ -0,0 +1,61 @@
1
+ import { gzipSync } from 'node:zlib';
2
+ import { readFile, readdir, stat } from 'node:fs/promises';
3
+ import { basename, join, resolve } from 'node:path';
4
+ /** Measure framework-neutral SSG output budgets and build-integrity signals. */
5
+ export async function checkPerformanceBudgets(options = {}) {
6
+ const outputDir = resolve(options.outputDir ?? 'dist');
7
+ const page = (options.page ?? '/').replace(/^\/+|\/+$/g, '');
8
+ const htmlPath = page ? join(outputDir, page, 'index.html') : join(outputDir, 'index.html');
9
+ const assetsDir = join(outputDir, 'assets');
10
+ const html = await readFile(htmlPath, 'utf8');
11
+ const htmlBytes = (await stat(htmlPath)).size;
12
+ const failures = [];
13
+ const assetNames = new Set([...html.matchAll(/(?:src|href)=(?:"([^"]+\.js)"|'([^']+\.js)')/g)]
14
+ .map((match) => match[1] ?? match[2])
15
+ .map((url) => url.slice(url.lastIndexOf('/') + 1)));
16
+ let initialJsGzipBytes = 0;
17
+ let entryJsGzipBytes = 0;
18
+ for (const name of assetNames) {
19
+ try {
20
+ const bytes = gzipSync(await readFile(join(assetsDir, name))).byteLength;
21
+ initialJsGzipBytes += bytes;
22
+ if (name.startsWith('index-'))
23
+ entryJsGzipBytes += bytes;
24
+ }
25
+ catch {
26
+ failures.push(`homepage references missing JavaScript asset ${name}`);
27
+ }
28
+ }
29
+ if (options.maxHtmlBytes !== undefined && htmlBytes > options.maxHtmlBytes) {
30
+ failures.push(`homepage is ${htmlBytes.toLocaleString()} bytes (budget: ${options.maxHtmlBytes.toLocaleString()})`);
31
+ }
32
+ if (options.maxInitialJsGzipBytes !== undefined &&
33
+ initialJsGzipBytes > options.maxInitialJsGzipBytes) {
34
+ failures.push(`initial JavaScript is ${initialJsGzipBytes.toLocaleString()} gzip bytes (budget: ${options.maxInitialJsGzipBytes.toLocaleString()})`);
35
+ }
36
+ if (options.maxEntryJsGzipBytes !== undefined &&
37
+ entryJsGzipBytes > options.maxEntryJsGzipBytes) {
38
+ failures.push(`entry JavaScript is ${entryJsGzipBytes.toLocaleString()} gzip bytes (budget: ${options.maxEntryJsGzipBytes.toLocaleString()})`);
39
+ }
40
+ const assets = await readdir(assetsDir);
41
+ const browserExternals = assets.filter((name) => name.startsWith('__vite-browser-external'));
42
+ if (browserExternals.length > 0) {
43
+ failures.push(`client build contains browser-external shims: ${browserExternals.join(', ')}`);
44
+ }
45
+ try {
46
+ const manifest = JSON.parse(await readFile(join(outputDir, 'ssg-manifest.json'), 'utf8'));
47
+ if ((manifest.errors?.length ?? 0) > 0) {
48
+ failures.push(`SSG manifest contains ${manifest.errors.length} render error(s)`);
49
+ }
50
+ if (options.expectedPages !== undefined && manifest.paths?.length !== options.expectedPages) {
51
+ failures.push(`SSG manifest contains ${manifest.paths?.length ?? 0} pages (expected: ${options.expectedPages})`);
52
+ }
53
+ }
54
+ catch {
55
+ if (options.expectedPages !== undefined) {
56
+ failures.push(`missing ${basename(join(outputDir, 'ssg-manifest.json'))}`);
57
+ }
58
+ }
59
+ return { htmlBytes, initialJsGzipBytes, entryJsGzipBytes, failures };
60
+ }
61
+ //# sourceMappingURL=performance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.js","sourceRoot":"","sources":["../../../src/cli/checks/performance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function checkCommand(): Command;
3
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkBnC,wBAAgB,YAAY,IAAI,OAAO,CA0FtC"}
@@ -0,0 +1,85 @@
1
+ import { Command } from 'commander';
2
+ import { resolve } from 'node:path';
3
+ import { checkBuiltLinks } from '../checks/links.js';
4
+ import { checkPerformanceBudgets } from '../checks/performance.js';
5
+ import { LIGHTHOUSE_CATEGORIES, runLighthouseAudit } from '../checks/lighthouse.js';
6
+ function numberOption(value) {
7
+ const parsed = Number(value);
8
+ if (!Number.isFinite(parsed) || parsed < 0)
9
+ throw new Error(`Invalid non-negative number: ${value}`);
10
+ return parsed;
11
+ }
12
+ function printFailures(label, failures) {
13
+ if (failures.length === 0)
14
+ return;
15
+ console.error(`${label} failed:\n- ${failures.join('\n- ')}`);
16
+ process.exitCode = 1;
17
+ }
18
+ export function checkCommand() {
19
+ const command = new Command('check').description('Validate production build quality');
20
+ command.addCommand(new Command('links')
21
+ .description('Validate all internal SSG links and fragments')
22
+ .option('--root <root>', 'Project root directory', process.cwd())
23
+ .option('--output <directory>', 'Build output directory', 'dist')
24
+ .action(async (options) => {
25
+ const report = await checkBuiltLinks({ outputDir: resolve(options.root, options.output) });
26
+ printFailures('Built-link validation', report.failures);
27
+ if (report.failures.length === 0) {
28
+ console.log(`Built-link validation passed: ${report.links} links across ${report.pages} pages.`);
29
+ }
30
+ }));
31
+ command.addCommand(new Command('performance')
32
+ .description('Validate HTML and JavaScript production budgets')
33
+ .option('--root <root>', 'Project root directory', process.cwd())
34
+ .option('--output <directory>', 'Build output directory', 'dist')
35
+ .option('--page <path>', 'Route to budget', '/')
36
+ .option('--max-html <bytes>', 'Maximum HTML bytes', numberOption, 250_000)
37
+ .option('--max-initial-js <bytes>', 'Maximum initial JavaScript gzip bytes', numberOption, 85_000)
38
+ .option('--max-entry-js <bytes>', 'Maximum entry JavaScript gzip bytes', numberOption, 50_000)
39
+ .option('--expected-pages <count>', 'Expected SSG manifest page count', numberOption)
40
+ .action(async (options) => {
41
+ const report = await checkPerformanceBudgets({
42
+ outputDir: resolve(options.root, options.output),
43
+ page: options.page,
44
+ maxHtmlBytes: options.maxHtml,
45
+ maxInitialJsGzipBytes: options.maxInitialJs,
46
+ maxEntryJsGzipBytes: options.maxEntryJs,
47
+ expectedPages: options.expectedPages,
48
+ });
49
+ printFailures('Performance budget', report.failures);
50
+ if (report.failures.length === 0) {
51
+ console.log(`Performance budgets passed: HTML ${report.htmlBytes.toLocaleString()} bytes; initial JS ${report.initialJsGzipBytes.toLocaleString()} gzip bytes.`);
52
+ }
53
+ }));
54
+ command.addCommand(new Command('lighthouse')
55
+ .description('Require perfect median Lighthouse scores using a local lighthouse dependency')
56
+ .requiredOption('--url <urls...>', 'One or more preview URLs to audit')
57
+ .option('--root <root>', 'Project root directory', process.cwd())
58
+ .option('--runs <count>', 'Runs per URL', numberOption, 3)
59
+ .option('--attempts <count>', 'Launch attempts per run', numberOption, 3)
60
+ .option('--desktop', 'Use the Lighthouse desktop preset')
61
+ .option('--chrome-path <path>', 'Chrome, Chromium, Edge, or Brave executable')
62
+ .action(async (options) => {
63
+ const reports = await runLighthouseAudit({
64
+ root: options.root,
65
+ urls: options.url,
66
+ runs: options.runs,
67
+ attempts: options.attempts,
68
+ preset: options.desktop ? 'desktop' : undefined,
69
+ chromePath: options.chromePath,
70
+ });
71
+ const failures = [];
72
+ for (const report of reports) {
73
+ const summary = LIGHTHOUSE_CATEGORIES.map((category) => {
74
+ const score = report.medians[category] ?? 0;
75
+ if (score !== 1)
76
+ failures.push(`${report.url}: ${category}=${Math.round(score * 100)}`);
77
+ return `${category}=${Math.round(score * 100)}`;
78
+ });
79
+ console.log(`[lighthouse] ${report.url}: ${summary.join(' ')}`);
80
+ }
81
+ printFailures('Lighthouse audit', failures);
82
+ }));
83
+ return command;
84
+ }
85
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/cli/commands/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAClE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEnF,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAA;IACpG,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,QAAkB;IACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IACjC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,eAAe,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC7D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACtB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAA;IAErF,OAAO,CAAC,UAAU,CAChB,IAAI,OAAO,CAAC,OAAO,CAAC;SACjB,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,eAAe,EAAE,wBAAwB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAChE,MAAM,CAAC,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,CAAC;SAChE,MAAM,CAAC,KAAK,EAAE,OAAyC,EAAE,EAAE;QAC1D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC1F,aAAa,CAAC,uBAAuB,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;QACvD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,iCAAiC,MAAM,CAAC,KAAK,iBAAiB,MAAM,CAAC,KAAK,SAAS,CAAC,CAAA;QAClG,CAAC;IACH,CAAC,CAAC,CACL,CAAA;IAED,OAAO,CAAC,UAAU,CAChB,IAAI,OAAO,CAAC,aAAa,CAAC;SACvB,WAAW,CAAC,iDAAiD,CAAC;SAC9D,MAAM,CAAC,eAAe,EAAE,wBAAwB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAChE,MAAM,CAAC,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,CAAC;SAChE,MAAM,CAAC,eAAe,EAAE,iBAAiB,EAAE,GAAG,CAAC;SAC/C,MAAM,CAAC,oBAAoB,EAAE,oBAAoB,EAAE,YAAY,EAAE,OAAO,CAAC;SACzE,MAAM,CAAC,0BAA0B,EAAE,uCAAuC,EAAE,YAAY,EAAE,MAAM,CAAC;SACjG,MAAM,CAAC,wBAAwB,EAAE,qCAAqC,EAAE,YAAY,EAAE,MAAM,CAAC;SAC7F,MAAM,CAAC,0BAA0B,EAAE,kCAAkC,EAAE,YAAY,CAAC;SACpF,MAAM,CAAC,KAAK,EAAE,OAQd,EAAE,EAAE;QACH,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC;YAC3C,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC;YAChD,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,YAAY,EAAE,OAAO,CAAC,OAAO;YAC7B,qBAAqB,EAAE,OAAO,CAAC,YAAY;YAC3C,mBAAmB,EAAE,OAAO,CAAC,UAAU;YACvC,aAAa,EAAE,OAAO,CAAC,aAAa;SACrC,CAAC,CAAA;QACF,aAAa,CAAC,oBAAoB,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;QACpD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,oCAAoC,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,sBAAsB,MAAM,CAAC,kBAAkB,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA;QAClK,CAAC;IACH,CAAC,CAAC,CACL,CAAA;IAED,OAAO,CAAC,UAAU,CAChB,IAAI,OAAO,CAAC,YAAY,CAAC;SACtB,WAAW,CAAC,8EAA8E,CAAC;SAC3F,cAAc,CAAC,iBAAiB,EAAE,mCAAmC,CAAC;SACtE,MAAM,CAAC,eAAe,EAAE,wBAAwB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAChE,MAAM,CAAC,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;SACzD,MAAM,CAAC,oBAAoB,EAAE,yBAAyB,EAAE,YAAY,EAAE,CAAC,CAAC;SACxE,MAAM,CAAC,WAAW,EAAE,mCAAmC,CAAC;SACxD,MAAM,CAAC,sBAAsB,EAAE,6CAA6C,CAAC;SAC7E,MAAM,CAAC,KAAK,EAAE,OAOd,EAAE,EAAE;QACH,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC;YACvC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,GAAG;YACjB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YAC/C,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAA;QACF,MAAM,QAAQ,GAAa,EAAE,CAAA;QAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;gBAC3C,IAAI,KAAK,KAAK,CAAC;oBAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,CAAA;gBACvF,OAAO,GAAG,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAA;YACjD,CAAC,CAAC,CAAA;YACF,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACjE,CAAC;QACD,aAAa,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAA;IAC7C,CAAC,CAAC,CACL,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkMnC,wBAAgB,cAAc,IAAI,OAAO,CAsSxC"}
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA6NnC,wBAAgB,cAAc,IAAI,OAAO,CA6SxC"}
@@ -1,6 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import { createServer as createHttpServer } from 'node:http';
3
3
  import { createReadStream, existsSync, statSync } from 'node:fs';
4
+ import { createGzip } from 'node:zlib';
4
5
  import { resolve, join, extname } from 'pathe';
5
6
  import { pathToFileURL } from 'node:url';
6
7
  import { isPathBounded, findRevalidate, findRenderMode, renderForIsr, serveFromIsrCache, } from './preview-isr.js';
@@ -103,6 +104,20 @@ function getMimeType(filePath) {
103
104
  const ext = extname(filePath).toLowerCase();
104
105
  return MIME_TYPES[ext] ?? 'application/octet-stream';
105
106
  }
107
+ // MIME types that benefit from gzip compression. Binary formats (woff2, images)
108
+ // are already compressed and should not be re-compressed.
109
+ const GZIP_TYPES = new Set([
110
+ 'text/html; charset=utf-8',
111
+ 'application/javascript; charset=utf-8',
112
+ 'text/css; charset=utf-8',
113
+ 'application/json; charset=utf-8',
114
+ 'image/svg+xml',
115
+ 'application/json',
116
+ ]);
117
+ function acceptsGzip(req) {
118
+ const ae = req.headers['accept-encoding'] ?? '';
119
+ return ae.includes('gzip');
120
+ }
106
121
  /**
107
122
  * Returns the appropriate Cache-Control header value for a file.
108
123
  * Vite content-hashes assets placed in the /assets/ directory, so they
@@ -123,6 +138,8 @@ function setSecurityHeaders(res) {
123
138
  }
124
139
  /**
125
140
  * Serves a static file from the dist directory.
141
+ * Applies gzip compression for compressible text types when the client
142
+ * signals support via the Accept-Encoding request header.
126
143
  * Returns true if the file was served, false otherwise.
127
144
  */
128
145
  function serveStaticFile(req, res, distDir) {
@@ -149,10 +166,18 @@ function serveStaticFile(req, res, distDir) {
149
166
  return false;
150
167
  }
151
168
  }
152
- res.setHeader('Content-Type', getMimeType(filePath));
169
+ const mimeType = getMimeType(filePath);
170
+ res.setHeader('Content-Type', mimeType);
153
171
  res.setHeader('Cache-Control', getCacheControl(filePath));
154
172
  setSecurityHeaders(res);
155
- createReadStream(filePath).pipe(res);
173
+ const stream = createReadStream(filePath);
174
+ if (GZIP_TYPES.has(mimeType) && acceptsGzip(req)) {
175
+ res.setHeader('Content-Encoding', 'gzip');
176
+ stream.pipe(createGzip()).pipe(res);
177
+ }
178
+ else {
179
+ stream.pipe(res);
180
+ }
156
181
  return true;
157
182
  }
158
183
  /**
@@ -418,9 +443,17 @@ export function previewCommand() {
418
443
  const assetPath = join(clientDist, urlPath);
419
444
  if (isPathBounded(clientDist, urlPath) &&
420
445
  existsSync(assetPath) && !statSync(assetPath).isDirectory()) {
421
- res.setHeader('Content-Type', getMimeType(assetPath));
446
+ const mimeType = getMimeType(assetPath);
447
+ res.setHeader('Content-Type', mimeType);
422
448
  res.setHeader('Cache-Control', getCacheControl(assetPath));
423
- createReadStream(assetPath).pipe(res);
449
+ const stream = createReadStream(assetPath);
450
+ if (GZIP_TYPES.has(mimeType) && acceptsGzip(req)) {
451
+ res.setHeader('Content-Encoding', 'gzip');
452
+ stream.pipe(createGzip()).pipe(res);
453
+ }
454
+ else {
455
+ stream.pipe(res);
456
+ }
424
457
  return;
425
458
  }
426
459
  }