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,37 @@
1
+ /**
2
+ * Example Dynamic API Route: GET|PUT|DELETE /api/posts/[id]
3
+ *
4
+ * Example showing dynamic route parameters
5
+ */
6
+ const posts = [
7
+ { id: 1, title: "First Post", content: "Hello World" },
8
+ { id: 2, title: "Second Post", content: "Jen.js is awesome" },
9
+ ];
10
+ export default async function handler(req, res) {
11
+ const { id } = req.params;
12
+ const postId = parseInt(String(id), 10);
13
+ if (isNaN(postId)) {
14
+ return res.status(400).json({ error: "Invalid post ID" });
15
+ }
16
+ const post = posts.find((p) => p.id === postId);
17
+ if (!post) {
18
+ return res.status(404).json({ error: "Post not found" });
19
+ }
20
+ if (req.method === "GET") {
21
+ // Get single post
22
+ res.status(200).json({ data: post });
23
+ } else if (req.method === "PUT") {
24
+ // Update post
25
+ const { title, content } = req.body;
26
+ if (title) post.title = title;
27
+ if (content) post.content = content;
28
+ res.status(200).json({ data: post });
29
+ } else if (req.method === "DELETE") {
30
+ // Delete post
31
+ const index = posts.findIndex((p) => p.id === postId);
32
+ posts.splice(index, 1);
33
+ res.status(200).json({ message: "Post deleted" });
34
+ } else {
35
+ res.status(405).json({ error: "Method not allowed" });
36
+ }
37
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Example API Route: GET|POST /api/posts
3
+ *
4
+ * Example showing HTTP method handling and request body parsing
5
+ */
6
+ const posts = [
7
+ { id: 1, title: "First Post", content: "Hello World" },
8
+ { id: 2, title: "Second Post", content: "Jen.js is awesome" },
9
+ ];
10
+ export default async function handler(req, res) {
11
+ if (req.method === "GET") {
12
+ // Get all posts
13
+ res.status(200).json({ data: posts });
14
+ } else if (req.method === "POST") {
15
+ // Create new post
16
+ const { title, content } = req.body;
17
+ if (!title || !content) {
18
+ return res.status(400).json({ error: "Missing title or content" });
19
+ }
20
+ const newPost = {
21
+ id: posts.length + 1,
22
+ title,
23
+ content,
24
+ };
25
+ posts.push(newPost);
26
+ res.status(201).json({ data: newPost });
27
+ } else {
28
+ res.status(405).json({ error: "Method not allowed" });
29
+ }
30
+ }
31
+ // Optional configuration
32
+ export const config = {
33
+ maxDuration: 30,
34
+ bodyParser: {
35
+ sizeLimit: "1mb",
36
+ },
37
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Example API Route: GET /api/search
3
+ *
4
+ * Example showing query parameter handling
5
+ */
6
+ export default async function handler(req, res) {
7
+ const { q, limit = "10" } = req.query;
8
+ if (!q) {
9
+ return res.status(400).json({ error: "Missing search query parameter" });
10
+ }
11
+ const limitNum = Math.min(parseInt(String(limit), 10) || 10, 100);
12
+ // Simulate search results
13
+ const results = [
14
+ { id: 1, title: `Result for "${q}"`, relevance: 0.95 },
15
+ { id: 2, title: `Another match for "${q}"`, relevance: 0.85 },
16
+ { id: 3, title: `Third result`, relevance: 0.72 },
17
+ ].slice(0, limitNum);
18
+ res.status(200).json({
19
+ query: q,
20
+ count: results.length,
21
+ results,
22
+ });
23
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Jen.js API Routes System
3
+ *
4
+ * File-based API routing system inspired by Next.js API Routes.
5
+ * All files in the `api/` directory are automatically mapped to `/api/*` routes.
6
+ *
7
+ * @example
8
+ * ```
9
+ * Directory structure:
10
+ * src/api/
11
+ * hello.ts -> GET /api/hello
12
+ * posts.ts -> GET|POST /api/posts
13
+ * posts/[id].ts -> GET /api/posts/123
14
+ * files/[...slug].ts -> GET /api/files/a/b/c
15
+ * admin/[[...path]].ts -> GET /api/admin or /api/admin/a/b
16
+ * ```
17
+ *
18
+ * @example Usage in handler
19
+ * ```ts
20
+ * // src/api/hello.ts
21
+ * import type { ApiRequest, ApiResponse } from '../api';
22
+ *
23
+ * export default function handler(req: ApiRequest, res: ApiResponse) {
24
+ * res.status(200).json({ message: 'Hello from Jen.js!' });
25
+ * }
26
+ *
27
+ * // Optional config
28
+ * export const config = {
29
+ * maxDuration: 60,
30
+ * bodyParser: { sizeLimit: '10mb' }
31
+ * };
32
+ * ```
33
+ */
34
+ export {
35
+ ApiRouter,
36
+ parseQuery,
37
+ parseCookies,
38
+ createApiRequest,
39
+ createApiResponse,
40
+ } from "./router";
41
+ export { ApiLoader, createApiMiddleware } from "./loader";
@@ -0,0 +1,234 @@
1
+ import { readdirSync } from "fs";
2
+ import { join, resolve } from "path";
3
+ /**
4
+ * Loader for scanning and loading API route files
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const loader = new ApiLoader();
9
+ * const routes = await loader.loadRoutes('./src/api');
10
+ * // Routes format: [
11
+ * // { path: '/api/hello', handler: ..., config: ... },
12
+ * // { path: '/api/posts/[id]', handler: ..., config: ... },
13
+ * // { path: '/api/files/[...slug]', handler: ..., config: ... }
14
+ * // ]
15
+ * ```
16
+ */
17
+ export class ApiLoader {
18
+ /**
19
+ * Load all API routes from a directory
20
+ *
21
+ * @param apiDir Directory to scan for route files (e.g., 'src/api')
22
+ * @param baseRoute Base route prefix (default: '/api')
23
+ * @returns Array of loaded routes
24
+ */
25
+ async loadRoutes(apiDir, baseRoute = "/api") {
26
+ const routes = [];
27
+ const fullPath = resolve(apiDir);
28
+ try {
29
+ await this.scanDirectory(fullPath, baseRoute, routes);
30
+ } catch (err) {
31
+ console.error(`Failed to load API routes from ${apiDir}:`, err);
32
+ }
33
+ // Sort routes by specificity: exact > dynamic > catch-all
34
+ routes.sort((a, b) => {
35
+ const aIsCatchAll = a.path.includes("[...");
36
+ const bIsCatchAll = b.path.includes("[...");
37
+ const aIsDynamic = a.path.includes("[");
38
+ const bIsDynamic = b.path.includes("[");
39
+ if (aIsCatchAll && !bIsCatchAll) return 1;
40
+ if (!aIsCatchAll && bIsCatchAll) return -1;
41
+ if (aIsDynamic && !bIsDynamic) return 1;
42
+ if (!aIsDynamic && bIsDynamic) return -1;
43
+ return a.path.length - b.path.length;
44
+ });
45
+ return routes;
46
+ }
47
+ /**
48
+ * Recursively scan directory for API route files
49
+ *
50
+ * @private
51
+ */
52
+ async scanDirectory(dir, baseRoute, routes) {
53
+ const entries = readdirSync(dir, { withFileTypes: true });
54
+ for (const entry of entries) {
55
+ const fullPath = join(dir, entry.name);
56
+ // Skip hidden files and directories
57
+ if (entry.name.startsWith(".")) continue;
58
+ if (entry.isDirectory()) {
59
+ await this.scanDirectory(fullPath, baseRoute, routes);
60
+ } else if (this.isRouteFile(entry.name)) {
61
+ const routePath = this.filePathToRoute(fullPath, baseRoute);
62
+ const module = await this.loadModule(fullPath);
63
+ if (module && typeof module.default === "function") {
64
+ routes.push({
65
+ path: routePath,
66
+ handler: module.default,
67
+ config: module.config,
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ /**
74
+ * Check if file is a valid route file
75
+ *
76
+ * @private
77
+ */
78
+ isRouteFile(filename) {
79
+ return (
80
+ /^[^.][^/]*\.(ts|tsx|js|jsx)$/.test(filename) &&
81
+ !filename.endsWith(".d.ts")
82
+ );
83
+ }
84
+ /**
85
+ * Convert file path to API route path
86
+ *
87
+ * @private
88
+ * @example
89
+ * ```
90
+ * src/api/hello.ts -> /api/hello
91
+ * src/api/posts/[id].ts -> /api/posts/[id]
92
+ * src/api/files/[...slug].ts -> /api/files/[...slug]
93
+ * ```
94
+ */
95
+ filePathToRoute(filePath, baseRoute) {
96
+ let route = filePath
97
+ .replace(/\\/g, "/") // Windows path separator
98
+ .replace(/\.(ts|tsx|js|jsx)$/, "") // Remove extension
99
+ .replace(/\/index$/, ""); // Remove /index
100
+ // Extract path after 'api' directory
101
+ const apiIndex = route.lastIndexOf("/api");
102
+ if (apiIndex !== -1) {
103
+ route = route.slice(apiIndex);
104
+ }
105
+ return baseRoute + route;
106
+ }
107
+ /**
108
+ * Dynamically import a module
109
+ *
110
+ * @private
111
+ */
112
+ async loadModule(filePath) {
113
+ try {
114
+ // Convert Windows path to file:// URL
115
+ let importPath = filePath;
116
+ if (process.platform === "win32") {
117
+ // Normalize: backslashes → forward slashes
118
+ const normalized = filePath.replace(/\\/g, "/");
119
+ // Add file:// scheme (with third slash for absolute paths)
120
+ importPath = "file:///" + normalized;
121
+ }
122
+ // Handle both CommonJS and ESM
123
+ const module = await import(importPath);
124
+ return module;
125
+ } catch (err) {
126
+ console.error(`Failed to load API route ${filePath}:`, err);
127
+ return null;
128
+ }
129
+ }
130
+ }
131
+ /**
132
+ * Create a middleware function for Express-like servers
133
+ *
134
+ * @param routes Loaded API routes
135
+ * @returns Express middleware function
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import express from 'express';
140
+ * import { createApiMiddleware } from '../api/loader';
141
+ * import { ApiRouter } from '../api/router';
142
+ *
143
+ * const app = express();
144
+ * const loader = new ApiLoader();
145
+ * const routes = await loader.loadRoutes('./src/api');
146
+ *
147
+ * const router = new ApiRouter();
148
+ * routes.forEach(route => router.register(route.path, route.handler));
149
+ *
150
+ * app.use(createApiMiddleware(routes));
151
+ * ```
152
+ */
153
+ export function createApiMiddleware(routes) {
154
+ return async (req, res, next) => {
155
+ // Only handle API routes
156
+ if (!req.url.startsWith("/api")) {
157
+ return next();
158
+ }
159
+ // Find matching route
160
+ const match = findMatchingRoute(req.path, routes);
161
+ if (!match) {
162
+ return next(); // Let next middleware handle 404
163
+ }
164
+ try {
165
+ // Set up request/response
166
+ req.params = match.params;
167
+ // Execute handler
168
+ await match.route.handler(req, res);
169
+ } catch (err) {
170
+ console.error("API handler error:", err);
171
+ res.status(500).json({ error: "Internal server error" });
172
+ }
173
+ };
174
+ }
175
+ /**
176
+ * Find matching route using simple path matching
177
+ *
178
+ * @private
179
+ */
180
+ function findMatchingRoute(requestPath, routes) {
181
+ for (const route of routes) {
182
+ const match = matchPath(requestPath, route.path);
183
+ if (match) {
184
+ return { route, params: match };
185
+ }
186
+ }
187
+ return null;
188
+ }
189
+ /**
190
+ * Match a request path against a route pattern
191
+ *
192
+ * @private
193
+ */
194
+ function matchPath(requestPath, routePath) {
195
+ const routeParts = routePath.split("/").filter(Boolean);
196
+ const requestParts = requestPath.split("/").filter(Boolean);
197
+ // Skip 'api' prefix
198
+ if (routeParts[0] === "api") routeParts.shift();
199
+ if (requestParts[0] === "api") requestParts.shift();
200
+ const params = {};
201
+ let routeIndex = 0;
202
+ let requestIndex = 0;
203
+ while (routeIndex < routeParts.length && requestIndex < requestParts.length) {
204
+ const routePart = routeParts[routeIndex];
205
+ const requestPart = requestParts[requestIndex];
206
+ if (routePart.startsWith("[...")) {
207
+ // Catch-all
208
+ const paramName = routePart.slice(4, -1);
209
+ const remaining = requestParts.slice(requestIndex);
210
+ params[paramName] = remaining;
211
+ requestIndex = requestParts.length;
212
+ } else if (routePart.startsWith("[")) {
213
+ // Dynamic segment
214
+ const paramName = routePart.slice(1, -1);
215
+ params[paramName] = requestPart;
216
+ requestIndex++;
217
+ } else if (routePart === requestPart) {
218
+ // Exact match
219
+ requestIndex++;
220
+ } else {
221
+ // No match
222
+ return null;
223
+ }
224
+ routeIndex++;
225
+ }
226
+ // Check if all parts matched
227
+ if (
228
+ routeIndex === routeParts.length &&
229
+ requestIndex === requestParts.length
230
+ ) {
231
+ return params;
232
+ }
233
+ return null;
234
+ }
@@ -0,0 +1,259 @@
1
+ import { URL } from "url";
2
+ /**
3
+ * API Router for matching requests to handlers
4
+ */
5
+ export class ApiRouter {
6
+ routes = new Map();
7
+ /**
8
+ * Register an API route handler
9
+ *
10
+ * @param path Route path (e.g., '/api/posts', '/api/posts/[id]', '/api/posts/[...slug]')
11
+ * @param handler Request handler function
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * router.register('/api/posts', handler);
16
+ * router.register('/api/posts/[id]', handler);
17
+ * router.register('/api/files/[...path]', handler);
18
+ * ```
19
+ */
20
+ register(path, handler) {
21
+ const pattern = this.pathToRegex(path);
22
+ const isDynamic = path.includes("[");
23
+ const isCatchAll = path.includes("[...");
24
+ this.routes.set(path, { handler, pattern, isDynamic, isCatchAll });
25
+ }
26
+ /**
27
+ * Match a request path to a registered route
28
+ *
29
+ * @param requestPath Request path
30
+ * @returns Matched handler and extracted params, or null if no match
31
+ */
32
+ match(requestPath) {
33
+ // First try exact matches (non-dynamic routes)
34
+ for (const [path, route] of this.routes) {
35
+ if (!route.isDynamic && path === requestPath) {
36
+ return { handler: route.handler, params: {} };
37
+ }
38
+ }
39
+ // Then try dynamic routes (sort by specificity)
40
+ const dynamicRoutes = Array.from(this.routes.entries())
41
+ .filter(([, route]) => route.isDynamic)
42
+ .sort(([a], [b]) => {
43
+ // Predefined routes before catch-all
44
+ if (a.includes("[...")) return 1;
45
+ if (b.includes("[...")) return -1;
46
+ // More specific before less specific
47
+ return a.split("/").length - b.split("/").length;
48
+ });
49
+ for (const [path, route] of dynamicRoutes) {
50
+ const match = requestPath.match(route.pattern);
51
+ if (match) {
52
+ const params = this.extractParams(path, requestPath);
53
+ return { handler: route.handler, params };
54
+ }
55
+ }
56
+ return null;
57
+ }
58
+ /**
59
+ * Convert a path pattern to a regex
60
+ *
61
+ * @private
62
+ */
63
+ pathToRegex(path) {
64
+ // Convert /api/posts/[id] to /api/posts/([^/]+)
65
+ // Convert /api/files/[...slug] to /api/files/(.+)
66
+ // Convert /api/items/[[...optional]] to /api/items(/.*)?
67
+ let pattern = path
68
+ .replace(/\//g, "\\/")
69
+ .replace(/\[\[\.\.\.([^\]]+)\]\]/g, "(?:\\/(.+))?") // Optional catch-all (do first)
70
+ .replace(/\[\.\.\.([^\]]+)\]/g, "(.+)") // Required catch-all
71
+ .replace(/\[([^\]]+)\]/g, "([^\\/]+)"); // Dynamic segment
72
+ return new RegExp(`^${pattern}$`);
73
+ }
74
+ /**
75
+ * Extract parameters from a matched route
76
+ *
77
+ * @private
78
+ */
79
+ extractParams(routePath, requestPath) {
80
+ const params = {};
81
+ // Extract parameter names from route
82
+ const paramMatches = routePath.matchAll(/\[\.{0,3}(\w+)\]/g);
83
+ const paramNames = Array.from(paramMatches, (m) => m[1]);
84
+ // Match request path and extract values
85
+ const pattern = this.pathToRegex(routePath);
86
+ const match = requestPath.match(pattern);
87
+ if (!match) return params;
88
+ for (let i = 0; i < paramNames.length; i++) {
89
+ const name = paramNames[i];
90
+ const value = match[i + 1];
91
+ if (
92
+ routePath.includes(`[...${name}]`) ||
93
+ routePath.includes(`[[...${name}]]`)
94
+ ) {
95
+ // Catch-all: convert to array
96
+ params[name] = value ? value.split("/").filter(Boolean) : [];
97
+ } else {
98
+ params[name] = value;
99
+ }
100
+ }
101
+ return params;
102
+ }
103
+ }
104
+ /**
105
+ * Parse query string into object
106
+ *
107
+ * @private
108
+ */
109
+ export function parseQuery(queryString) {
110
+ const params = {};
111
+ if (!queryString) return params;
112
+ const pairs = queryString.split("&");
113
+ for (const pair of pairs) {
114
+ const [key, value] = pair.split("=");
115
+ const decodedKey = decodeURIComponent(key || "");
116
+ const decodedValue = decodeURIComponent(value || "");
117
+ if (params[decodedKey]) {
118
+ if (Array.isArray(params[decodedKey])) {
119
+ params[decodedKey].push(decodedValue);
120
+ } else {
121
+ params[decodedKey] = [params[decodedKey], decodedValue];
122
+ }
123
+ } else {
124
+ params[decodedKey] = decodedValue;
125
+ }
126
+ }
127
+ return params;
128
+ }
129
+ /**
130
+ * Parse cookies from request headers
131
+ *
132
+ * @private
133
+ */
134
+ export function parseCookies(cookieHeader) {
135
+ const cookies = {};
136
+ if (!cookieHeader) return cookies;
137
+ const pairs = cookieHeader.split(";");
138
+ for (const pair of pairs) {
139
+ const [key, value] = pair.trim().split("=");
140
+ if (key) cookies[key] = decodeURIComponent(value || "");
141
+ }
142
+ return cookies;
143
+ }
144
+ /**
145
+ * Create enhanced request object
146
+ *
147
+ * @private
148
+ */
149
+ export async function createApiRequest(req, params = {}) {
150
+ const url = new URL(req.url || "", `http://${req.headers.host}`);
151
+ const query = parseQuery(url.search.slice(1));
152
+ const cookies = parseCookies(req.headers.cookie || "");
153
+ let body = null;
154
+ // Parse body if present
155
+ if (req.method !== "GET" && req.method !== "HEAD") {
156
+ body = await new Promise((resolve, reject) => {
157
+ let data = "";
158
+ req.on("data", (chunk) => {
159
+ data += chunk.toString();
160
+ });
161
+ req.on("end", () => {
162
+ try {
163
+ const contentType = req.headers["content-type"] || "";
164
+ if (contentType.includes("application/json")) {
165
+ resolve(data ? JSON.parse(data) : null);
166
+ } else if (
167
+ contentType.includes("application/x-www-form-urlencoded")
168
+ ) {
169
+ resolve(parseQuery(data));
170
+ } else {
171
+ resolve(data || null);
172
+ }
173
+ } catch (err) {
174
+ reject(err);
175
+ }
176
+ });
177
+ req.on("error", reject);
178
+ });
179
+ }
180
+ return {
181
+ ...req,
182
+ method: req.method || "GET",
183
+ url: req.url || "/",
184
+ query,
185
+ body,
186
+ params,
187
+ cookies,
188
+ };
189
+ }
190
+ /**
191
+ * Create enhanced response object
192
+ *
193
+ * @private
194
+ */
195
+ export function createApiResponse(res) {
196
+ const apiRes = res;
197
+ let statusCode = 200;
198
+ let headersSent = false;
199
+ apiRes.status = function (code) {
200
+ statusCode = code;
201
+ res.statusCode = code;
202
+ return apiRes;
203
+ };
204
+ apiRes.header = function (key, value) {
205
+ res.setHeader(key, value);
206
+ return apiRes;
207
+ };
208
+ apiRes.json = function (body) {
209
+ if (!headersSent) {
210
+ res.setHeader("Content-Type", "application/json");
211
+ res.statusCode = statusCode;
212
+ headersSent = true;
213
+ }
214
+ res.end(JSON.stringify(body));
215
+ };
216
+ apiRes.send = function (body) {
217
+ if (!headersSent) {
218
+ if (typeof body === "object" && !(body instanceof Buffer)) {
219
+ res.setHeader("Content-Type", "application/json");
220
+ res.end(JSON.stringify(body));
221
+ } else {
222
+ res.end(body);
223
+ }
224
+ headersSent = true;
225
+ }
226
+ };
227
+ apiRes.redirect = function (statusOrPath, path) {
228
+ const redirectPath =
229
+ typeof statusOrPath === "string" ? statusOrPath : path || "/";
230
+ const code = typeof statusOrPath === "number" ? statusOrPath : 307;
231
+ res.statusCode = code;
232
+ res.setHeader("Location", redirectPath);
233
+ res.end();
234
+ headersSent = true;
235
+ };
236
+ apiRes.download = function (filepath, filename) {
237
+ res.setHeader(
238
+ "Content-Disposition",
239
+ `attachment; filename="${filename || filepath}"`,
240
+ );
241
+ apiRes.sendFile(filepath);
242
+ };
243
+ apiRes.sendFile = function (filepath) {
244
+ // Dynamic import for sendFile functionality
245
+ (async () => {
246
+ try {
247
+ const { createReadStream } = await import("fs");
248
+ const file = createReadStream(filepath);
249
+ file.pipe(res);
250
+ headersSent = true;
251
+ } catch (err) {
252
+ console.error("Error sending file:", err);
253
+ res.statusCode = 500;
254
+ res.end("Error sending file");
255
+ }
256
+ })();
257
+ };
258
+ return apiRes;
259
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,19 +1,6 @@
1
- /*
2
- * This file is part of Jen.js.
3
- * Copyright (C) 2026 oopsio
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
1
+ /**
2
+ * Secure cookie utilities for session management
3
+ * Ensures cookies have proper security flags
17
4
  */
18
5
  /**
19
6
  * Generate secure cookie header value
@@ -1,19 +1,2 @@
1
- /*
2
- * This file is part of Jen.js.
3
- * Copyright (C) 2026 oopsio
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
- */
18
1
  export * from "./jwt";
19
2
  export * from "./session";
@@ -1,20 +1,3 @@
1
- /*
2
- * This file is part of Jen.js.
3
- * Copyright (C) 2026 oopsio
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
- */
18
1
  /**
19
2
  * JWT token utilities for creating and validating JSON Web Tokens.
20
3
  * This module provides stub implementations that require an external JWT library.