create-jen-app 1.2.3 → 1.2.4

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 (355) hide show
  1. package/dist/colors.js +0 -17
  2. package/dist/create.js +5 -17
  3. package/dist/generator.js +14 -31
  4. package/dist/index.js +6 -1
  5. package/package.json +1 -1
  6. package/templates/ssr-isr/README.md +77 -0
  7. package/templates/ssr-isr/build.js +118 -0
  8. package/templates/ssr-isr/jen.config.ts +109 -0
  9. package/templates/ssr-isr/jenjs.d.ts +22 -0
  10. package/templates/ssr-isr/lib/api/(hello).js +9 -0
  11. package/templates/ssr-isr/lib/auth/cookie-utils.js +79 -0
  12. package/templates/ssr-isr/lib/auth/index.js +2 -0
  13. package/templates/ssr-isr/lib/auth/jwt.js +57 -0
  14. package/templates/ssr-isr/lib/auth/session.js +92 -0
  15. package/templates/ssr-isr/lib/build/asset-hashing.d.ts +10 -0
  16. package/templates/ssr-isr/lib/build/asset-hashing.js +25 -0
  17. package/templates/ssr-isr/lib/build/asset-manifest.d.ts +11 -0
  18. package/templates/ssr-isr/lib/build/asset-manifest.js +21 -0
  19. package/templates/{static → ssr-isr}/lib/build/build.d.ts +1 -1
  20. package/templates/ssr-isr/lib/build/build.js +141 -0
  21. package/templates/{static → ssr-isr}/lib/build/island-hydration.d.ts +8 -5
  22. package/templates/ssr-isr/lib/build/island-hydration.js +44 -0
  23. package/templates/ssr-isr/lib/build/minifier.d.ts +20 -0
  24. package/templates/ssr-isr/lib/build/minifier.js +46 -0
  25. package/templates/ssr-isr/lib/build/page-renderer.d.ts +17 -0
  26. package/templates/ssr-isr/lib/build/page-renderer.js +28 -0
  27. package/templates/ssr-isr/lib/build/production-build.d.ts +10 -0
  28. package/templates/ssr-isr/lib/build/production-build.js +13 -0
  29. package/templates/ssr-isr/lib/build/ssg-pipeline.d.ts +15 -0
  30. package/templates/ssr-isr/lib/build/ssg-pipeline.js +113 -0
  31. package/templates/ssr-isr/lib/build-tools/build-site.js +36 -0
  32. package/templates/ssr-isr/lib/cache/index.js +10 -0
  33. package/templates/ssr-isr/lib/cache/memory.js +40 -0
  34. package/templates/ssr-isr/lib/cache/redis.js +61 -0
  35. package/templates/ssr-isr/lib/cli/banner.js +28 -0
  36. package/templates/ssr-isr/lib/cli/templates/ssg/jen.config.js +32 -0
  37. package/templates/ssr-isr/lib/cli/templates/ssg/site/index.js +9 -0
  38. package/templates/ssr-isr/lib/cli/templates/ssr/jen.config.js +32 -0
  39. package/templates/ssr-isr/lib/cli/templates/ssr/site/index.js +9 -0
  40. package/templates/ssr-isr/lib/compilers/esbuild-plugins.js +111 -0
  41. package/templates/ssr-isr/lib/compilers/svelte.js +44 -0
  42. package/templates/ssr-isr/lib/compilers/vue.js +90 -0
  43. package/templates/ssr-isr/lib/core/http.js +71 -0
  44. package/templates/ssr-isr/lib/core/middleware-hooks.js +97 -0
  45. package/templates/ssr-isr/lib/core/paths.js +39 -0
  46. package/templates/ssr-isr/lib/core/routes/match.js +47 -0
  47. package/templates/ssr-isr/lib/core/routes/scan.js +190 -0
  48. package/templates/ssr-isr/lib/core/types.js +1 -0
  49. package/templates/ssr-isr/lib/css/compiler.js +74 -0
  50. package/templates/ssr-isr/lib/db/connector.js +42 -0
  51. package/templates/ssr-isr/lib/db/drivers/jdb.js +44 -0
  52. package/templates/ssr-isr/lib/db/drivers/sql.js +182 -0
  53. package/templates/ssr-isr/lib/db/index.js +48 -0
  54. package/templates/ssr-isr/lib/db/types.js +1 -0
  55. package/templates/ssr-isr/lib/graphql/index.js +52 -0
  56. package/templates/ssr-isr/lib/graphql/resolvers.js +25 -0
  57. package/templates/ssr-isr/lib/graphql/schema.js +35 -0
  58. package/templates/ssr-isr/lib/i18n/en.json +4 -0
  59. package/templates/ssr-isr/lib/i18n/es.json +4 -0
  60. package/templates/ssr-isr/lib/i18n/index.js +15 -0
  61. package/templates/ssr-isr/lib/import/jen-import.js +161 -0
  62. package/templates/ssr-isr/lib/index.js +116 -0
  63. package/templates/ssr-isr/lib/jdb/engine.js +275 -0
  64. package/templates/ssr-isr/lib/jdb/index.js +34 -0
  65. package/templates/ssr-isr/lib/jdb/types.js +1 -0
  66. package/templates/ssr-isr/lib/jdb/utils.js +176 -0
  67. package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.js +0 -17
  68. package/templates/ssr-isr/lib/middleware/builtins/cors.js +54 -0
  69. package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.js +0 -17
  70. package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.js +0 -17
  71. package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.js +0 -17
  72. package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.js +0 -17
  73. package/templates/ssr-isr/lib/middleware/context.js +124 -0
  74. package/templates/{static → ssr-isr}/lib/middleware/decorators.js +0 -17
  75. package/templates/{static → ssr-isr}/lib/middleware/errors/handler.js +0 -17
  76. package/templates/ssr-isr/lib/middleware/errors/http-error.js +10 -0
  77. package/templates/ssr-isr/lib/middleware/kernel.js +85 -0
  78. package/templates/ssr-isr/lib/middleware/pipeline.js +148 -0
  79. package/templates/ssr-isr/lib/middleware/registry.js +85 -0
  80. package/templates/ssr-isr/lib/middleware/response.js +107 -0
  81. package/templates/ssr-isr/lib/middleware/types.d.ts +1 -0
  82. package/templates/ssr-isr/lib/middleware/types.js +1 -0
  83. package/templates/ssr-isr/lib/middleware/utils/matcher.js +13 -0
  84. package/templates/{static → ssr-isr}/lib/native/bundle.js +0 -17
  85. package/templates/{static → ssr-isr}/lib/native/dev-server.js +0 -17
  86. package/templates/{static → ssr-isr}/lib/native/index.js +0 -17
  87. package/templates/{static → ssr-isr}/lib/native/optimizer.js +0 -17
  88. package/templates/ssr-isr/lib/native/style-compiler.js +19 -0
  89. package/templates/ssr-isr/lib/plugin/loader.js +36 -0
  90. package/templates/ssr-isr/lib/runtime/client-runtime.js +25 -0
  91. package/templates/ssr-isr/lib/runtime/hmr.js +59 -0
  92. package/templates/ssr-isr/lib/runtime/hydrate.js +55 -0
  93. package/templates/ssr-isr/lib/runtime/island-hydration-client.js +146 -0
  94. package/templates/ssr-isr/lib/runtime/islands.js +110 -0
  95. package/templates/ssr-isr/lib/runtime/render.js +244 -0
  96. package/templates/ssr-isr/lib/server/api-routes.js +237 -0
  97. package/templates/ssr-isr/lib/server/api.js +108 -0
  98. package/templates/ssr-isr/lib/server/app.js +438 -0
  99. package/templates/ssr-isr/lib/server/runtimeServe.js +169 -0
  100. package/templates/ssr-isr/lib/server/ssr.js +202 -0
  101. package/templates/ssr-isr/lib/shared/log.js +64 -0
  102. package/templates/ssr-isr/package.json +23 -0
  103. package/templates/ssr-isr/server.js +128 -0
  104. package/templates/ssr-isr/site/pages/(index).tsx +11 -0
  105. package/templates/ssr-isr/site/styles/global.scss +37 -0
  106. package/templates/ssr-isr/tsconfig.json +39 -0
  107. package/templates/static/build.js +30 -18
  108. package/templates/static/jen.config.ts +0 -18
  109. package/templates/static/jenjs.d.ts +0 -18
  110. package/templates/static/lib/api/(hello).js +0 -17
  111. package/templates/static/lib/api/examples/files/[...slug].js +22 -0
  112. package/templates/static/lib/api/examples/hello.js +11 -0
  113. package/templates/static/lib/api/examples/posts/[id].js +37 -0
  114. package/templates/static/lib/api/examples/posts.js +37 -0
  115. package/templates/static/lib/api/examples/search.js +23 -0
  116. package/templates/static/lib/api/index.js +41 -0
  117. package/templates/static/lib/api/loader.js +234 -0
  118. package/templates/static/lib/api/router.js +259 -0
  119. package/templates/static/lib/assets/types.js +1 -0
  120. package/templates/static/lib/auth/cookie-utils.js +3 -16
  121. package/templates/static/lib/auth/index.js +0 -17
  122. package/templates/static/lib/auth/jwt.js +0 -17
  123. package/templates/static/lib/auth/session.js +0 -17
  124. package/templates/static/lib/build/asset-hashing.js +44 -36
  125. package/templates/static/lib/build/asset-manifest.js +16 -33
  126. package/templates/static/lib/build/build.js +270 -125
  127. package/templates/static/lib/build/bundle-analyzer-ui.js +417 -0
  128. package/templates/static/lib/build/bundle-analyzer.js +945 -0
  129. package/templates/static/lib/build/code-splitter.js +194 -0
  130. package/templates/static/lib/build/feature-analyzer.js +190 -0
  131. package/templates/static/lib/build/feature-gate.js +257 -0
  132. package/templates/static/lib/build/island-hydration.js +17 -35
  133. package/templates/static/lib/build/lazy-loader.js +322 -0
  134. package/templates/static/lib/build/minifier.js +40 -59
  135. package/templates/static/lib/build/page-renderer.js +23 -40
  136. package/templates/static/lib/build/production-build.js +9 -26
  137. package/templates/static/lib/build/rust-hashing.js +71 -0
  138. package/templates/static/lib/build/script-optimizer.js +285 -0
  139. package/templates/static/lib/build/ssg-pipeline.js +100 -106
  140. package/templates/static/lib/build/vercel-output.js +298 -0
  141. package/templates/static/lib/build-tools/build-site.js +0 -17
  142. package/templates/static/lib/cache/index.js +0 -17
  143. package/templates/static/lib/cache/memory.js +0 -17
  144. package/templates/static/lib/cache/redis.js +0 -17
  145. package/templates/static/lib/cli/banner.js +0 -17
  146. package/templates/static/lib/cli/templates/ssg/jen.config.js +0 -17
  147. package/templates/static/lib/cli/templates/ssr/jen.config.js +0 -17
  148. package/templates/static/lib/client/Image.js +42 -0
  149. package/templates/static/lib/client/Link.js +190 -0
  150. package/templates/static/lib/client/PWA.js +46 -0
  151. package/templates/static/lib/client/Seo.js +97 -0
  152. package/templates/static/lib/client/index.js +9 -0
  153. package/templates/static/lib/client/useNavigation.js +25 -0
  154. package/templates/static/lib/client/useRouter.js +64 -0
  155. package/templates/static/lib/client-routing/Link.js +17 -0
  156. package/templates/static/lib/client-routing/index.js +19 -0
  157. package/templates/static/lib/client-routing/router.js +151 -0
  158. package/templates/static/lib/client-routing/signal.js +147 -0
  159. package/templates/static/lib/compilers/esbuild-plugins.js +0 -17
  160. package/templates/static/lib/compilers/svelte.js +0 -17
  161. package/templates/static/lib/compilers/vue.js +0 -17
  162. package/templates/static/lib/core/config.js +0 -17
  163. package/templates/static/lib/core/feature-guard.js +136 -0
  164. package/templates/static/lib/core/features.js +99 -0
  165. package/templates/static/lib/core/http.js +0 -17
  166. package/templates/static/lib/core/layouts/index.js +10 -0
  167. package/templates/static/lib/core/layouts/render.js +158 -0
  168. package/templates/static/lib/core/layouts/scan.js +112 -0
  169. package/templates/static/lib/core/layouts/types.js +1 -0
  170. package/templates/static/lib/core/lifecycle.js +129 -0
  171. package/templates/static/lib/core/loader-schema.js +81 -0
  172. package/templates/static/lib/core/middleware-hooks.js +0 -17
  173. package/templates/static/lib/core/paths.js +0 -17
  174. package/templates/static/lib/core/routes/advanced.js +114 -0
  175. package/templates/static/lib/core/routes/handlers.js +181 -0
  176. package/templates/static/lib/core/routes/match.js +89 -17
  177. package/templates/static/lib/core/routes/orchestrator.js +171 -0
  178. package/templates/static/lib/core/routes/rendering-config.js +131 -0
  179. package/templates/static/lib/core/routes/scan.js +0 -17
  180. package/templates/static/lib/core/types.js +0 -17
  181. package/templates/static/lib/css/compiler.js +1 -18
  182. package/templates/static/lib/data-fetching/cache.js +223 -0
  183. package/templates/static/lib/data-fetching/client.js +202 -0
  184. package/templates/static/lib/data-fetching/feature-guard.js +29 -0
  185. package/templates/static/lib/data-fetching/graphql.js +265 -0
  186. package/templates/static/lib/data-fetching/index.js +57 -0
  187. package/templates/static/lib/data-fetching/rest.js +256 -0
  188. package/templates/static/lib/data-fetching/server.js +182 -0
  189. package/templates/static/lib/data-fetching/types.js +5 -0
  190. package/templates/static/lib/db/connector.js +0 -17
  191. package/templates/static/lib/db/drivers/jdb.js +0 -17
  192. package/templates/static/lib/db/drivers/sql.js +0 -17
  193. package/templates/static/lib/db/index.js +0 -17
  194. package/templates/static/lib/db/types.js +0 -17
  195. package/templates/static/lib/devtools/component-tree.js +106 -0
  196. package/templates/static/lib/devtools/devtools.js +638 -0
  197. package/templates/static/lib/devtools/event-bus.js +29 -0
  198. package/templates/static/lib/devtools/event-logger.js +67 -0
  199. package/templates/static/lib/devtools/index.js +9 -0
  200. package/templates/static/lib/devtools/integration.js +149 -0
  201. package/templates/static/lib/devtools/performance.js +84 -0
  202. package/templates/static/lib/devtools/persistence.js +57 -0
  203. package/templates/static/lib/devtools/plugins.js +97 -0
  204. package/templates/static/lib/devtools/search.js +89 -0
  205. package/templates/static/lib/devtools/ui.js +769 -0
  206. package/templates/static/lib/features/api/handler.js +10 -0
  207. package/templates/static/lib/features/api/index.js +5 -0
  208. package/templates/static/lib/features/api/types.js +4 -0
  209. package/templates/static/lib/features/middleware/compiled.js +7 -0
  210. package/templates/static/lib/features/middleware/index.js +5 -0
  211. package/templates/static/lib/features/middleware/types.js +4 -0
  212. package/templates/static/lib/fonts/index.js +46 -0
  213. package/templates/static/lib/fonts/inject.js +125 -0
  214. package/templates/static/lib/fonts/loader.js +196 -0
  215. package/templates/static/lib/fonts/types.js +1 -0
  216. package/templates/static/lib/graphql/index.js +1 -18
  217. package/templates/static/lib/graphql/resolvers.js +20 -13
  218. package/templates/static/lib/graphql/schema.js +0 -17
  219. package/templates/static/lib/i18n/index.js +7 -19
  220. package/templates/static/lib/import/jen-import.js +1 -18
  221. package/templates/static/lib/index.js +79 -125
  222. package/templates/static/lib/jdb/engine.js +0 -17
  223. package/templates/static/lib/jdb/index.js +1 -18
  224. package/templates/static/lib/jdb/types.js +0 -17
  225. package/templates/static/lib/jdb/utils.js +0 -17
  226. package/templates/static/lib/middleware/builtins/cors.js +3 -16
  227. package/templates/static/lib/middleware/context.js +0 -17
  228. package/templates/static/lib/middleware/kernel.js +117 -25
  229. package/templates/static/lib/middleware/pipeline.js +0 -17
  230. package/templates/static/lib/middleware/registry.js +0 -17
  231. package/templates/static/lib/middleware/response.js +0 -17
  232. package/templates/static/lib/plugin/examples/analytics-plugin.js +183 -0
  233. package/templates/static/lib/plugin/examples/cdn-upload-plugin.js +94 -0
  234. package/templates/static/lib/plugin/loader.js +0 -17
  235. package/templates/static/lib/plugin/plugin-manager.js +177 -0
  236. package/templates/static/lib/plugin/types.js +28 -0
  237. package/templates/static/lib/runtime/client-runtime.js +0 -17
  238. package/templates/static/lib/runtime/hmr.js +0 -17
  239. package/templates/static/lib/runtime/hydrate.js +0 -17
  240. package/templates/static/lib/runtime/island-hydration-client.js +0 -17
  241. package/templates/static/lib/runtime/islands.js +0 -17
  242. package/templates/static/lib/runtime/render.js +208 -50
  243. package/templates/static/lib/security/security-config.js +60 -0
  244. package/templates/static/lib/security/security-middleware.js +229 -0
  245. package/templates/static/lib/server/api-routes.js +153 -43
  246. package/templates/static/lib/server/api.js +0 -17
  247. package/templates/static/lib/server/app.js +539 -223
  248. package/templates/static/lib/server/isr.js +365 -0
  249. package/templates/static/lib/server/runtimeServe.js +31 -24
  250. package/templates/static/lib/server/ssr.js +98 -22
  251. package/templates/static/lib/server-actions/handler.js +180 -0
  252. package/templates/static/lib/server-actions/index.js +19 -0
  253. package/templates/static/lib/server-actions/middleware.js +146 -0
  254. package/templates/static/lib/server-actions/scan.js +152 -0
  255. package/templates/static/lib/server-actions/types.js +1 -0
  256. package/templates/static/lib/server-actions/validators.js +156 -0
  257. package/templates/static/lib/shared/log.js +19 -20
  258. package/templates/static/lib/telemetry/api/rate-limiter.js +32 -0
  259. package/templates/static/lib/telemetry/api/validator.js +67 -0
  260. package/templates/static/lib/telemetry/client.js +121 -0
  261. package/templates/static/lib/telemetry/tests/rate-limiter.test.js +46 -0
  262. package/templates/static/lib/telemetry/tests/validator.test.js +62 -0
  263. package/templates/static/lib/vendor/glob/glob.js +4766 -0
  264. package/templates/static/lib/vendor/preact/LICENSE +21 -0
  265. package/templates/static/lib/vendor/preact/preact.module.js +797 -0
  266. package/templates/static/lib/vendor/sass/sass.node.mjs +212 -0
  267. package/templates/static/package.json +4 -0
  268. package/templates/static/server.js +22 -22
  269. package/templates/static/site/(home).tsx +0 -18
  270. package/templates/static/tsconfig.json +5 -1
  271. package/templates/static/.esbuild/jen.config.js +0 -19
  272. package/templates/static/lib/build/asset-hashing.d.ts +0 -10
  273. package/templates/static/lib/build/asset-manifest.d.ts +0 -11
  274. package/templates/static/lib/build/minifier.d.ts +0 -20
  275. package/templates/static/lib/build/page-renderer.d.ts +0 -17
  276. package/templates/static/lib/build/production-build.d.ts +0 -10
  277. package/templates/static/lib/build/ssg-pipeline.d.ts +0 -15
  278. package/templates/static/lib/middleware/errors/http-error.js +0 -27
  279. package/templates/static/lib/middleware/types.js +0 -18
  280. package/templates/static/lib/middleware/utils/matcher.js +0 -30
  281. package/templates/static/lib/native/style-compiler.js +0 -36
  282. /package/templates/{static → ssr-isr}/lib/api/(hello).d.ts +0 -0
  283. /package/templates/{static → ssr-isr}/lib/auth/cookie-utils.d.ts +0 -0
  284. /package/templates/{static → ssr-isr}/lib/auth/index.d.ts +0 -0
  285. /package/templates/{static → ssr-isr}/lib/auth/jwt.d.ts +0 -0
  286. /package/templates/{static → ssr-isr}/lib/auth/session.d.ts +0 -0
  287. /package/templates/{static → ssr-isr}/lib/build-tools/build-site.d.ts +0 -0
  288. /package/templates/{static → ssr-isr}/lib/cache/index.d.ts +0 -0
  289. /package/templates/{static → ssr-isr}/lib/cache/memory.d.ts +0 -0
  290. /package/templates/{static → ssr-isr}/lib/cache/redis.d.ts +0 -0
  291. /package/templates/{static → ssr-isr}/lib/cli/banner.d.ts +0 -0
  292. /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/jen.config.d.ts +0 -0
  293. /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/site/index.d.ts +0 -0
  294. /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/jen.config.d.ts +0 -0
  295. /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/site/index.d.ts +0 -0
  296. /package/templates/{static → ssr-isr}/lib/compilers/esbuild-plugins.d.ts +0 -0
  297. /package/templates/{static → ssr-isr}/lib/compilers/svelte.d.ts +0 -0
  298. /package/templates/{static → ssr-isr}/lib/compilers/vue.d.ts +0 -0
  299. /package/templates/{static → ssr-isr}/lib/core/config.d.ts +0 -0
  300. /package/templates/{static/lib/middleware/types.d.ts → ssr-isr/lib/core/config.js} +0 -0
  301. /package/templates/{static → ssr-isr}/lib/core/http.d.ts +0 -0
  302. /package/templates/{static → ssr-isr}/lib/core/middleware-hooks.d.ts +0 -0
  303. /package/templates/{static → ssr-isr}/lib/core/paths.d.ts +0 -0
  304. /package/templates/{static → ssr-isr}/lib/core/routes/match.d.ts +0 -0
  305. /package/templates/{static → ssr-isr}/lib/core/routes/scan.d.ts +0 -0
  306. /package/templates/{static → ssr-isr}/lib/core/types.d.ts +0 -0
  307. /package/templates/{static → ssr-isr}/lib/css/compiler.d.ts +0 -0
  308. /package/templates/{static → ssr-isr}/lib/db/connector.d.ts +0 -0
  309. /package/templates/{static → ssr-isr}/lib/db/drivers/jdb.d.ts +0 -0
  310. /package/templates/{static → ssr-isr}/lib/db/drivers/sql.d.ts +0 -0
  311. /package/templates/{static → ssr-isr}/lib/db/index.d.ts +0 -0
  312. /package/templates/{static → ssr-isr}/lib/db/types.d.ts +0 -0
  313. /package/templates/{static → ssr-isr}/lib/graphql/index.d.ts +0 -0
  314. /package/templates/{static → ssr-isr}/lib/graphql/resolvers.d.ts +0 -0
  315. /package/templates/{static → ssr-isr}/lib/graphql/schema.d.ts +0 -0
  316. /package/templates/{static → ssr-isr}/lib/i18n/index.d.ts +0 -0
  317. /package/templates/{static → ssr-isr}/lib/import/jen-import.d.ts +0 -0
  318. /package/templates/{static → ssr-isr}/lib/index.d.ts +0 -0
  319. /package/templates/{static → ssr-isr}/lib/jdb/engine.d.ts +0 -0
  320. /package/templates/{static → ssr-isr}/lib/jdb/index.d.ts +0 -0
  321. /package/templates/{static → ssr-isr}/lib/jdb/types.d.ts +0 -0
  322. /package/templates/{static → ssr-isr}/lib/jdb/utils.d.ts +0 -0
  323. /package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.d.ts +0 -0
  324. /package/templates/{static → ssr-isr}/lib/middleware/builtins/cors.d.ts +0 -0
  325. /package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.d.ts +0 -0
  326. /package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.d.ts +0 -0
  327. /package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.d.ts +0 -0
  328. /package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.d.ts +0 -0
  329. /package/templates/{static → ssr-isr}/lib/middleware/context.d.ts +0 -0
  330. /package/templates/{static → ssr-isr}/lib/middleware/decorators.d.ts +0 -0
  331. /package/templates/{static → ssr-isr}/lib/middleware/errors/handler.d.ts +0 -0
  332. /package/templates/{static → ssr-isr}/lib/middleware/errors/http-error.d.ts +0 -0
  333. /package/templates/{static → ssr-isr}/lib/middleware/kernel.d.ts +0 -0
  334. /package/templates/{static → ssr-isr}/lib/middleware/pipeline.d.ts +0 -0
  335. /package/templates/{static → ssr-isr}/lib/middleware/registry.d.ts +0 -0
  336. /package/templates/{static → ssr-isr}/lib/middleware/response.d.ts +0 -0
  337. /package/templates/{static → ssr-isr}/lib/middleware/utils/matcher.d.ts +0 -0
  338. /package/templates/{static → ssr-isr}/lib/native/bundle.d.ts +0 -0
  339. /package/templates/{static → ssr-isr}/lib/native/dev-server.d.ts +0 -0
  340. /package/templates/{static → ssr-isr}/lib/native/index.d.ts +0 -0
  341. /package/templates/{static → ssr-isr}/lib/native/optimizer.d.ts +0 -0
  342. /package/templates/{static → ssr-isr}/lib/native/style-compiler.d.ts +0 -0
  343. /package/templates/{static → ssr-isr}/lib/plugin/loader.d.ts +0 -0
  344. /package/templates/{static → ssr-isr}/lib/runtime/client-runtime.d.ts +0 -0
  345. /package/templates/{static → ssr-isr}/lib/runtime/hmr.d.ts +0 -0
  346. /package/templates/{static → ssr-isr}/lib/runtime/hydrate.d.ts +0 -0
  347. /package/templates/{static → ssr-isr}/lib/runtime/island-hydration-client.d.ts +0 -0
  348. /package/templates/{static → ssr-isr}/lib/runtime/islands.d.ts +0 -0
  349. /package/templates/{static → ssr-isr}/lib/runtime/render.d.ts +0 -0
  350. /package/templates/{static → ssr-isr}/lib/server/api-routes.d.ts +0 -0
  351. /package/templates/{static → ssr-isr}/lib/server/api.d.ts +0 -0
  352. /package/templates/{static → ssr-isr}/lib/server/app.d.ts +0 -0
  353. /package/templates/{static → ssr-isr}/lib/server/runtimeServe.d.ts +0 -0
  354. /package/templates/{static → ssr-isr}/lib/server/ssr.d.ts +0 -0
  355. /package/templates/{static → ssr-isr}/lib/shared/log.d.ts +0 -0
@@ -0,0 +1,36 @@
1
+ // Site build utilities
2
+ // Migrated from Python src/python/build.py
3
+ import { copyFileSync, rmSync, mkdirSync, readdirSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { log } from "../shared/log.js";
6
+ function copyDir(src, dst) {
7
+ if (!readdirSync(src, { withFileTypes: true }).length) return;
8
+ mkdirSync(dst, { recursive: true });
9
+ for (const file of readdirSync(src, { withFileTypes: true })) {
10
+ const srcPath = join(src, file.name);
11
+ const dstPath = join(dst, file.name);
12
+ if (file.isDirectory()) {
13
+ copyDir(srcPath, dstPath);
14
+ } else {
15
+ copyFileSync(srcPath, dstPath);
16
+ }
17
+ }
18
+ }
19
+ export async function buildSite(opts = {}) {
20
+ log.info("Building site...");
21
+ const srcDir = "site";
22
+ const distDir = "dist";
23
+ // Clean dist
24
+ try {
25
+ rmSync(distDir, { recursive: true, force: true });
26
+ } catch {}
27
+ // Copy assets
28
+ copyDir(srcDir, distDir);
29
+ log.info(`Copied ${srcDir} → ${distDir}`);
30
+ // Minify if requested
31
+ if (opts.minify) {
32
+ log.info("Minifying assets...");
33
+ // Placeholder: integrate image/font minifiers
34
+ }
35
+ log.info("Build complete.");
36
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Cache layer module providing two implementations:
3
+ * - MemoryCache: In-memory Map-based cache for single-process deployments.
4
+ * - RedisCache: API contract for distributed caching (requires external redis library).
5
+ *
6
+ * Choose MemoryCache for development/testing or single-instance production.
7
+ * Choose RedisCache for multi-process or distributed environments (must install redis separately).
8
+ */
9
+ export * from "./memory";
10
+ export * from "./redis";
@@ -0,0 +1,40 @@
1
+ /**
2
+ * In-memory cache implementation using a JavaScript Map.
3
+ * Stores key-value pairs with optional time-to-live (TTL) expiration.
4
+ * Useful for development, testing, or single-process deployments.
5
+ * Not suitable for multi-process environments (values isolated per process).
6
+ * Note: Expired entries are deleted asynchronously via setTimeout; memory is not
7
+ * compacted if clear() or delete() are never called on expired keys.
8
+ */
9
+ export class MemoryCache {
10
+ /** Internal store mapping cache keys to arbitrary values. */
11
+ store = new Map();
12
+ /**
13
+ * Store a value in cache with optional time-to-live.
14
+ * If TTL is specified, the entry is automatically deleted after ttlMs milliseconds.
15
+ * @param key - Cache key identifier.
16
+ * @param value - Value to store (can be any type; recommend serializable for consistency).
17
+ * @param ttlMs - Time-to-live in milliseconds. If omitted, entry persists until delete() or process restart.
18
+ */
19
+ set(key, value, ttlMs) {
20
+ this.store.set(key, value);
21
+ if (ttlMs) setTimeout(() => this.store.delete(key), ttlMs);
22
+ }
23
+ /**
24
+ * Retrieve a value from cache.
25
+ * Returns undefined if key does not exist or has expired.
26
+ * @param key - Cache key identifier.
27
+ * @returns Stored value or undefined if not found.
28
+ */
29
+ get(key) {
30
+ return this.store.get(key);
31
+ }
32
+ /**
33
+ * Remove a value from cache.
34
+ * Safe to call on non-existent keys (no-op).
35
+ * @param key - Cache key identifier.
36
+ */
37
+ delete(key) {
38
+ this.store.delete(key);
39
+ }
40
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Placeholder Redis cache implementation.
3
+ * The framework does not include the Redis library; users must install it separately.
4
+ * This class provides the API contract; actual implementation requires external redis library.
5
+ * Install with: npm install redis
6
+ *
7
+ * Usage example:
8
+ * import { RedisCache } from "jenjs";
9
+ * const cache = new RedisCache();
10
+ * await cache.connect();
11
+ * await cache.set("key", { data: "value" }, 3600);
12
+ * const val = await cache.get("key");
13
+ *
14
+ * Suitable for distributed/multi-process deployments where shared cache is needed.
15
+ */
16
+ export class RedisCache {
17
+ /**
18
+ * Connect to Redis server.
19
+ * Requires external redis library to be installed.
20
+ * @throws Always throws if called without external library.
21
+ */
22
+ async connect() {
23
+ throw new Error(
24
+ "Redis implementation requires external library. Install: npm install redis",
25
+ );
26
+ }
27
+ /**
28
+ * Store a value in Redis with optional time-to-live.
29
+ * @param key - Cache key identifier.
30
+ * @param value - Value to store (should be serializable to JSON).
31
+ * @param ttlSec - Time-to-live in seconds. If omitted, key persists indefinitely.
32
+ * @throws Always throws if called without external library.
33
+ */
34
+ async set(key, value, ttlSec) {
35
+ throw new Error(
36
+ "Redis implementation requires external library. Install: npm install redis",
37
+ );
38
+ }
39
+ /**
40
+ * Retrieve a value from Redis.
41
+ * @param key - Cache key identifier.
42
+ * @returns Stored value or undefined if key does not exist.
43
+ * @throws Always throws if called without external library.
44
+ */
45
+ async get(key) {
46
+ throw new Error(
47
+ "Redis implementation requires external library. Install: npm install redis",
48
+ );
49
+ }
50
+ /**
51
+ * Delete a value from Redis.
52
+ * Safe to call on non-existent keys (no-op in Redis).
53
+ * @param key - Cache key identifier.
54
+ * @throws Always throws if called without external library.
55
+ */
56
+ async delete(key) {
57
+ throw new Error(
58
+ "Redis implementation requires external library. Install: npm install redis",
59
+ );
60
+ }
61
+ }
@@ -0,0 +1,28 @@
1
+ // Stylized CLI Banner for Jen.js
2
+ // Matches the visual style requested (Purple/Cyan gradient feel)
3
+ const RES = "\x1b[0m";
4
+ const PURPLE = "\x1b[38;2;200;128;255m"; // #C880FF
5
+ const CYAN = "\x1b[38;2;86;194;201m"; // #56C2C9
6
+ const GRAY = "\x1b[90m";
7
+ const BOLD = "\x1b[1m";
8
+ const DIM = "\x1b[2m";
9
+ export function printBanner(port, env, version = "1.0.0") {
10
+ // Clear screen mostly
11
+ // console.log("\x1b[2J\x1b[3J\x1b[H");
12
+ console.log();
13
+ console.log(` ${PURPLE} __ ${CYAN} _ ${RES}`);
14
+ console.log(` ${PURPLE} / /__ ____ ${CYAN} (_)____${RES}`);
15
+ console.log(` ${PURPLE} __ / / _ \/ __ \ ${CYAN} / / ___/${RES}`);
16
+ console.log(
17
+ ` ${PURPLE}/ /_/ / __/ / / /${GRAY}_____${CYAN}/ / (__ )${RES}`,
18
+ );
19
+ console.log(` ${PURPLE}\____/\___/_/ /_/${GRAY}_____/${CYAN}_/____/ ${RES}`);
20
+ console.log();
21
+ console.log(` ${GRAY}Jen.js Framework ${DIM}v${version}${RES}`);
22
+ console.log();
23
+ console.log(
24
+ ` ${GRAY}➜${RES} ${BOLD}Local:${RES} ${CYAN}http://localhost:${port}/${RES}`,
25
+ );
26
+ console.log(` ${GRAY}➜${RES} ${BOLD}Mode:${RES} ${PURPLE}${env}${RES}`);
27
+ console.log();
28
+ }
@@ -0,0 +1,32 @@
1
+ const config = {
2
+ siteDir: "site",
3
+ distDir: "dist",
4
+ routes: {
5
+ fileExtensions: [".tsx", ".jsx", ".ts", ".js"],
6
+ routeFilePattern: /^\((.+)\)\.(t|j)sx?$/,
7
+ enableIndexFallback: true,
8
+ },
9
+ rendering: {
10
+ defaultMode: "ssg",
11
+ defaultRevalidateSeconds: 60,
12
+ },
13
+ assets: {
14
+ publicDir: "site/assets",
15
+ cacheControl: "public, max-age=31536000, immutable",
16
+ },
17
+ inject: {
18
+ head: [
19
+ `<meta charset="utf-8">`,
20
+ `<meta name="viewport" content="width=device-width, initial-scale=1">`,
21
+ ],
22
+ bodyEnd: [],
23
+ },
24
+ css: {
25
+ globalScss: "site/styles/global.scss",
26
+ },
27
+ server: {
28
+ port: 3000,
29
+ hostname: "0.0.0.0",
30
+ },
31
+ };
32
+ export default config;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ export default function Home() {
3
+ return _jsxs("div", {
4
+ children: [
5
+ _jsx("h1", { children: "Welcome to My SSG App" }),
6
+ _jsx("p", { children: "This page was generated from the SSG template." }),
7
+ ],
8
+ });
9
+ }
@@ -0,0 +1,32 @@
1
+ const config = {
2
+ siteDir: "site",
3
+ distDir: "dist",
4
+ routes: {
5
+ fileExtensions: [".tsx", ".jsx", ".ts", ".js"],
6
+ routeFilePattern: /^\((.+)\)\.(t|j)sx?$/,
7
+ enableIndexFallback: true,
8
+ },
9
+ rendering: {
10
+ defaultMode: "ssr",
11
+ defaultRevalidateSeconds: 60,
12
+ },
13
+ assets: {
14
+ publicDir: "site/assets",
15
+ cacheControl: "public, max-age=31536000, immutable",
16
+ },
17
+ inject: {
18
+ head: [
19
+ `<meta charset="utf-8">`,
20
+ `<meta name="viewport" content="width=device-width, initial-scale=1">`,
21
+ ],
22
+ bodyEnd: [],
23
+ },
24
+ css: {
25
+ globalScss: "site/styles/global.scss",
26
+ },
27
+ server: {
28
+ port: 3000,
29
+ hostname: "0.0.0.0",
30
+ },
31
+ };
32
+ export default config;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ export default function Home() {
3
+ return _jsxs("div", {
4
+ children: [
5
+ _jsx("h1", { children: "Welcome to My SSR App" }),
6
+ _jsx("p", { children: "This page is rendered on the server." }),
7
+ ],
8
+ });
9
+ }
@@ -0,0 +1,111 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { createVueCompiler } from "./vue.js";
3
+ import { createSvelteCompiler } from "./svelte.js";
4
+ const vueCache = new Map();
5
+ const svelteCache = new Map();
6
+ export function vueEsbuildPlugin() {
7
+ const compiler = createVueCompiler();
8
+ return {
9
+ name: "vue",
10
+ setup(build) {
11
+ build.onLoad({ filter: /\.vue$/ }, async (args) => {
12
+ try {
13
+ // Check cache
14
+ if (vueCache.has(args.path)) {
15
+ return {
16
+ contents: vueCache.get(args.path),
17
+ loader: "js",
18
+ };
19
+ }
20
+ const source = readFileSync(args.path, "utf-8");
21
+ const result = compiler.compile(source, {
22
+ filename: args.path,
23
+ id: args.path.replace(/[^a-z0-9]/gi, "_"),
24
+ });
25
+ if (result.error) {
26
+ return {
27
+ errors: [
28
+ {
29
+ text: `Vue compilation failed: ${result.error}`,
30
+ location: { file: args.path, line: 1, column: 0 },
31
+ },
32
+ ],
33
+ };
34
+ }
35
+ vueCache.set(args.path, result.code);
36
+ return {
37
+ contents: result.code,
38
+ loader: "js",
39
+ };
40
+ } catch (err) {
41
+ return {
42
+ errors: [
43
+ {
44
+ text: `Vue plugin error: ${String(err)}`,
45
+ location: { file: args.path, line: 1, column: 0 },
46
+ },
47
+ ],
48
+ };
49
+ }
50
+ });
51
+ },
52
+ };
53
+ }
54
+ export function svelteEsbuildPlugin() {
55
+ const compiler = createSvelteCompiler();
56
+ return {
57
+ name: "svelte",
58
+ setup(build) {
59
+ build.onLoad({ filter: /\.svelte$/ }, async (args) => {
60
+ try {
61
+ // Check cache
62
+ if (svelteCache.has(args.path)) {
63
+ return {
64
+ contents: svelteCache.get(args.path),
65
+ loader: "js",
66
+ };
67
+ }
68
+ const source = readFileSync(args.path, "utf-8");
69
+ const result = compiler.compile(source, {
70
+ filename: args.path,
71
+ dev: process.env.NODE_ENV !== "production",
72
+ });
73
+ if (result.error) {
74
+ return {
75
+ errors: [
76
+ {
77
+ text: `Svelte compilation failed: ${result.error}`,
78
+ location: { file: args.path, line: 1, column: 0 },
79
+ },
80
+ ],
81
+ };
82
+ }
83
+ svelteCache.set(args.path, result.code);
84
+ return {
85
+ contents: result.code,
86
+ loader: "js",
87
+ };
88
+ } catch (err) {
89
+ return {
90
+ errors: [
91
+ {
92
+ text: `Svelte plugin error: ${String(err)}`,
93
+ location: { file: args.path, line: 1, column: 0 },
94
+ },
95
+ ],
96
+ };
97
+ }
98
+ });
99
+ },
100
+ };
101
+ }
102
+ export function invalidateVueCache(filePath) {
103
+ vueCache.delete(filePath);
104
+ }
105
+ export function invalidateSvelteCache(filePath) {
106
+ svelteCache.delete(filePath);
107
+ }
108
+ export function clearAllCompilerCaches() {
109
+ vueCache.clear();
110
+ svelteCache.clear();
111
+ }
@@ -0,0 +1,44 @@
1
+ import { compile as svelteCompile } from "svelte/compiler";
2
+ import { log } from "../shared/log.js";
3
+ export class SvelteCompiler {
4
+ compile(source, options) {
5
+ try {
6
+ const filename = options.filename || "component.svelte";
7
+ const result = svelteCompile(source, {
8
+ filename,
9
+ dev: options.dev ?? false,
10
+ css: "injected", // Inject CSS at runtime instead of extracting
11
+ preserveComments: !options.minified,
12
+ preserveWhitespace: !options.minified,
13
+ });
14
+ if (result.warnings && result.warnings.length > 0) {
15
+ result.warnings.forEach((w) => {
16
+ log.warn(`[Svelte] ${filename}: ${w.message}`);
17
+ });
18
+ }
19
+ // Build module code
20
+ let code = result.js.code;
21
+ // If CSS is generated, inject it
22
+ if (result.css && result.css.code.trim()) {
23
+ const escapedCss = result.css.code
24
+ .replace(/"/g, '\\"')
25
+ .replace(/\n/g, "\\n");
26
+ code += `
27
+ if (typeof window !== 'undefined') {
28
+ const style = document.createElement('style');
29
+ style.textContent = "${escapedCss}";
30
+ document.head.appendChild(style);
31
+ }
32
+ `;
33
+ }
34
+ return { code };
35
+ } catch (err) {
36
+ const message = err.message || String(err);
37
+ log.error(`[Svelte] Compilation error: ${message}`);
38
+ return { code: "", error: message };
39
+ }
40
+ }
41
+ }
42
+ export function createSvelteCompiler() {
43
+ return new SvelteCompiler();
44
+ }
@@ -0,0 +1,90 @@
1
+ import {
2
+ parse,
3
+ compileScript,
4
+ compileTemplate,
5
+ compileStyle,
6
+ } from "@vue/compiler-sfc";
7
+ import { log } from "../shared/log.js";
8
+ export class VueCompiler {
9
+ compile(source, options) {
10
+ try {
11
+ const filename = options.filename || "component.vue";
12
+ const id = options.id || filename.replace(/[^a-z0-9]/gi, "_");
13
+ // Parse SFC
14
+ const parseResult = parse(source, { filename });
15
+ const descriptor = parseResult.descriptor;
16
+ let scriptCode = "";
17
+ let templateCode = "";
18
+ let styleCode = "";
19
+ // Compile script
20
+ if (descriptor.script || descriptor.scriptSetup) {
21
+ const scriptCompiled = compileScript(descriptor, {
22
+ id,
23
+ isProd: options.minified ?? false,
24
+ });
25
+ scriptCode = scriptCompiled.content;
26
+ }
27
+ // Compile template
28
+ if (descriptor.template) {
29
+ const templateCompiled = compileTemplate({
30
+ source: descriptor.template.content,
31
+ filename,
32
+ id,
33
+ compilerOptions: {
34
+ isCustomElement: (tag) => tag.startsWith("custom-"),
35
+ },
36
+ });
37
+ if (templateCompiled.errors.length > 0) {
38
+ return {
39
+ code: "",
40
+ error: `Template compilation error: ${templateCompiled.errors.join(", ")}`,
41
+ };
42
+ }
43
+ templateCode = templateCompiled.code;
44
+ }
45
+ // Compile styles (scoped)
46
+ if (descriptor.styles.length > 0) {
47
+ descriptor.styles.forEach((style, idx) => {
48
+ const styleCompiled = compileStyle({
49
+ source: style.content,
50
+ filename,
51
+ id,
52
+ scoped: style.scoped ?? false,
53
+ });
54
+ if (styleCompiled.errors.length > 0) {
55
+ log.warn(
56
+ `Style compilation warning at style[${idx}]: ${styleCompiled.errors.join(", ")}`,
57
+ );
58
+ }
59
+ styleCode += styleCompiled.code + "\n";
60
+ });
61
+ }
62
+ // Inject styles at runtime
63
+ let injectStyle = "";
64
+ if (styleCode.trim()) {
65
+ const escapedStyle = styleCode
66
+ .replace(/"/g, '\\"')
67
+ .replace(/\n/g, "\\n");
68
+ injectStyle = `
69
+ const style = document.createElement('style');
70
+ style.textContent = "${escapedStyle}";
71
+ document.head.appendChild(style);
72
+ `;
73
+ }
74
+ // Build final module
75
+ const finalCode = `
76
+ ${scriptCode || "export default {}"}
77
+ ${templateCode}
78
+ ${injectStyle}
79
+ `;
80
+ return { code: finalCode };
81
+ } catch (err) {
82
+ const message = err.message || String(err);
83
+ log.error(`[Vue] Compilation error: ${message}`);
84
+ return { code: "", error: message };
85
+ }
86
+ }
87
+ }
88
+ export function createVueCompiler() {
89
+ return new VueCompiler();
90
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Parses the HTTP Cookie header into an object of name-value pairs.
3
+ *
4
+ * Cookie format (RFC 6265):
5
+ * - Multiple cookies separated by semicolons
6
+ * - Each cookie is name=value with optional whitespace
7
+ * - Cookie values are URL-encoded and must be decoded
8
+ *
9
+ * Edge cases handled:
10
+ * - Missing or empty Cookie header returns empty object
11
+ * - Whitespace is trimmed from names and values
12
+ * - Values may contain equals signs (split only on first =)
13
+ * - Empty names or values are filtered out
14
+ * - Values are URL-decoded to handle special characters
15
+ *
16
+ * @param req Node.js IncomingMessage with headers property
17
+ *
18
+ * @returns Object with cookie names as keys and decoded values
19
+ *
20
+ * @example
21
+ * // Header: "sessionId=abc123; theme=dark; path=/admin"
22
+ * // Returns: { sessionId: "abc123", theme: "dark", path: "/admin" }
23
+ *
24
+ * // Header missing or empty
25
+ * // Returns: {}
26
+ */
27
+ export function parseCookies(req) {
28
+ const cookie = req.headers.cookie;
29
+ if (!cookie) return {};
30
+ const out = {};
31
+ for (const part of cookie.split(";")) {
32
+ const [k, ...rest] = part.trim().split("=");
33
+ const trimmedName = k.trim();
34
+ const trimmedValue = rest.join("=").trim();
35
+ if (trimmedName && trimmedValue) {
36
+ out[trimmedName] = decodeURIComponent(trimmedValue);
37
+ }
38
+ }
39
+ return out;
40
+ }
41
+ /**
42
+ * Converts Node.js headers object to a flat string-valued object.
43
+ *
44
+ * Header normalization:
45
+ * - Node.js headers may have array values (for multiple headers with same name)
46
+ * - Arrays are joined with comma-space to follow HTTP spec (RFC 2822)
47
+ * - Non-array string values are kept as-is
48
+ * - Header names are already lowercased by Node.js
49
+ *
50
+ * Motivation:
51
+ * Application code typically expects headers as a flat object with string values,
52
+ * not Node.js's mixed types. This normalizes the data structure for consistency.
53
+ *
54
+ * @param headers The headers object from IncomingMessage.headers
55
+ *
56
+ * @returns Flat object with header names (lowercase) as keys and string values
57
+ *
58
+ * @example
59
+ * // Input (from Node.js):
60
+ * { accept: "text/html", "accept-encoding": ["gzip", "deflate"], "content-type": "application/json" }
61
+ * // Output:
62
+ * { accept: "text/html", "accept-encoding": "gzip, deflate", "content-type": "application/json" }
63
+ */
64
+ export function headersToObject(headers) {
65
+ const out = {};
66
+ for (const [k, v] of Object.entries(headers)) {
67
+ if (Array.isArray(v)) out[k] = v.join(", ");
68
+ else if (typeof v === "string") out[k] = v;
69
+ }
70
+ return out;
71
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Type definitions note:
3
+ * Route module types (middleware field, hydrate field) are defined in core/types.ts.
4
+ * This module provides the middleware execution engine and context object.
5
+ */
6
+ /**
7
+ * Creates a middleware context object from request data.
8
+ * Called by the renderer before executing route middleware.
9
+ *
10
+ * Initializes:
11
+ * - All request data (req, res, url, params, query, headers, cookies)
12
+ * - Empty data object for middleware to populate
13
+ * - Helper methods (status, setHeader, redirect, json) as chainable methods
14
+ *
15
+ * @param opts Configuration with raw request data
16
+ * @param opts.req Node.js IncomingMessage
17
+ * @param opts.res Node.js ServerResponse
18
+ * @param opts.url Parsed URL from request
19
+ * @param opts.params Route parameters from URL path
20
+ * @param opts.query Query string parameters
21
+ * @param opts.headers Normalized headers object
22
+ * @param opts.cookies Parsed cookies from Cookie header
23
+ *
24
+ * @returns Initialized RouteMiddlewareContext ready for middleware execution
25
+ */
26
+ export function createRouteMiddlewareContext(opts) {
27
+ const ctx = {
28
+ ...opts,
29
+ data: {},
30
+ status: function (code) {
31
+ this.res.statusCode = code;
32
+ return this;
33
+ },
34
+ setHeader: function (key, value) {
35
+ this.res.setHeader(key, value);
36
+ return this;
37
+ },
38
+ redirect: function (url, statusCode = 302) {
39
+ this.res.statusCode = statusCode;
40
+ this.res.setHeader("location", url);
41
+ this.res.end();
42
+ throw new Error("__REDIRECT__");
43
+ },
44
+ json: function (data, statusCode = 200) {
45
+ this.res.statusCode = statusCode;
46
+ this.res.setHeader("content-type", "application/json; charset=utf-8");
47
+ this.res.end(JSON.stringify(data));
48
+ throw new Error("__JSON__");
49
+ },
50
+ };
51
+ return ctx;
52
+ }
53
+ /**
54
+ * Executes an array of route middleware sequentially for a route.
55
+ *
56
+ * Execution model:
57
+ * 1. Iterates through middlewares in order
58
+ * 2. Each middleware is awaited (even if synchronous)
59
+ * 3. Middleware can populate ctx.data for use by loader and page
60
+ * 4. If middleware calls ctx.redirect() or ctx.json(), error is caught and re-thrown
61
+ * 5. Other errors are propagated immediately
62
+ *
63
+ * Control flow:
64
+ * - Normal completion: all middlewares finish and function returns
65
+ * - Early exit: middleware calls ctx.redirect() or ctx.json()
66
+ * - Error: middleware throws or ctx.redirect()/json() throws sentinel error
67
+ *
68
+ * Side effects:
69
+ * - Response headers, status, and body may be sent by middleware
70
+ * - ctx.data may be modified by middleware
71
+ * - Should only be called in server context (SSR); not during SSG build
72
+ *
73
+ * @param middlewares Array of middleware functions to execute
74
+ * @param ctx RouteMiddlewareContext created by createRouteMiddlewareContext()
75
+ *
76
+ * @returns Promise that resolves if all middlewares complete normally
77
+ * @throws Error with message "__REDIRECT__" if middleware calls ctx.redirect()
78
+ * @throws Error with message "__JSON__" if middleware calls ctx.json()
79
+ * @throws Error from middleware if it throws
80
+ */
81
+ export async function executeRouteMiddleware(middlewares, ctx) {
82
+ for (const mw of middlewares) {
83
+ try {
84
+ await mw(ctx);
85
+ } catch (err) {
86
+ /**
87
+ * Sentinel errors from ctx.redirect() and ctx.json() are re-thrown
88
+ * to signal that the response was already sent.
89
+ * Other errors propagate normally for error handling middleware.
90
+ */
91
+ if (err.message === "__REDIRECT__" || err.message === "__JSON__") {
92
+ throw err;
93
+ }
94
+ throw err;
95
+ }
96
+ }
97
+ }