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,92 @@
1
+ const SESSION_TIMEOUT = parseInt(process.env.SESSION_TIMEOUT ?? "86400000", 10); // 24 hours default
2
+ /**
3
+ * In-memory session manager
4
+ * WARNING: Sessions are lost on server restart
5
+ * For production, use persistent storage (Redis, Database, etc.)
6
+ */
7
+ export class SessionManager {
8
+ sessions = new Map();
9
+ constructor() {
10
+ // Cleanup expired sessions every 30 minutes
11
+ setInterval(() => this.cleanupExpiredSessions(), 30 * 60 * 1000);
12
+ }
13
+ /**
14
+ * Create a new session with automatic expiration
15
+ */
16
+ createSession(userId, data = {}) {
17
+ // Validate userId
18
+ if (!userId || typeof userId !== "string" || userId.length > 255) {
19
+ throw new Error("Invalid userId");
20
+ }
21
+ const sessionId = this.generateSecureSessionId();
22
+ const now = Date.now();
23
+ const session = {
24
+ userId,
25
+ createdAt: now,
26
+ expiresAt: now + SESSION_TIMEOUT,
27
+ ...data,
28
+ };
29
+ this.sessions.set(sessionId, session);
30
+ return sessionId;
31
+ }
32
+ /**
33
+ * Get session with expiration check
34
+ */
35
+ getSession(sessionId) {
36
+ if (!sessionId) return null;
37
+ const session = this.sessions.get(sessionId);
38
+ if (!session) return null;
39
+ // Check if session expired
40
+ if (Date.now() > session.expiresAt) {
41
+ this.sessions.delete(sessionId);
42
+ return null;
43
+ }
44
+ return session;
45
+ }
46
+ /**
47
+ * Destroy session immediately
48
+ */
49
+ destroySession(sessionId) {
50
+ this.sessions.delete(sessionId);
51
+ }
52
+ /**
53
+ * Verify session is valid and return user ID
54
+ */
55
+ verifySession(sessionId) {
56
+ const session = this.getSession(sessionId);
57
+ return session?.userId ?? null;
58
+ }
59
+ /**
60
+ * Update session expiration
61
+ */
62
+ refreshSession(sessionId) {
63
+ const session = this.getSession(sessionId);
64
+ if (!session) return false;
65
+ session.expiresAt = Date.now() + SESSION_TIMEOUT;
66
+ return true;
67
+ }
68
+ /**
69
+ * Generate cryptographically secure session ID
70
+ */
71
+ generateSecureSessionId() {
72
+ // In production, use crypto.randomBytes
73
+ const chars =
74
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
75
+ let result = "";
76
+ for (let i = 0; i < 32; i++) {
77
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
78
+ }
79
+ return result;
80
+ }
81
+ /**
82
+ * Clean up expired sessions
83
+ */
84
+ cleanupExpiredSessions() {
85
+ const now = Date.now();
86
+ for (const [sessionId, session] of this.sessions.entries()) {
87
+ if (now > session.expiresAt) {
88
+ this.sessions.delete(sessionId);
89
+ }
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,10 @@
1
+ export declare class AssetHasher {
2
+ /**
3
+ * Calculate hash of file content
4
+ */
5
+ static hashContent(content: string | Buffer): string;
6
+ /**
7
+ * Rename file to include hash (e.g. style.css -> style.a1b2c3.css)
8
+ */
9
+ static hashFile(filePath: string): string;
10
+ }
@@ -0,0 +1,25 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync, renameSync } from "node:fs";
3
+ import { join, dirname, basename, extname } from "node:path";
4
+ export class AssetHasher {
5
+ /**
6
+ * Calculate hash of file content
7
+ */
8
+ static hashContent(content) {
9
+ return createHash("md5").update(content).digest("hex").slice(0, 10);
10
+ }
11
+ /**
12
+ * Rename file to include hash (e.g. style.css -> style.a1b2c3.css)
13
+ */
14
+ static hashFile(filePath) {
15
+ const content = readFileSync(filePath);
16
+ const hash = this.hashContent(content);
17
+ const dir = dirname(filePath);
18
+ const ext = extname(filePath);
19
+ const name = basename(filePath, ext);
20
+ const newName = `${name}.${hash}${ext}`;
21
+ const newPath = join(dir, newName);
22
+ renameSync(filePath, newPath);
23
+ return newName;
24
+ }
25
+ }
@@ -0,0 +1,11 @@
1
+ export interface Manifest {
2
+ [key: string]: string;
3
+ }
4
+ export declare class AssetManifest {
5
+ private manifest;
6
+ private manifestPath;
7
+ constructor(distDir: string);
8
+ set(original: string, hashed: string): void;
9
+ get(original: string): string | undefined;
10
+ save(): void;
11
+ }
@@ -0,0 +1,21 @@
1
+ import { writeFileSync, readFileSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ export class AssetManifest {
4
+ manifest = {};
5
+ manifestPath;
6
+ constructor(distDir) {
7
+ this.manifestPath = join(distDir, "manifest.json");
8
+ if (existsSync(this.manifestPath)) {
9
+ this.manifest = JSON.parse(readFileSync(this.manifestPath, "utf8"));
10
+ }
11
+ }
12
+ set(original, hashed) {
13
+ this.manifest[original] = hashed;
14
+ }
15
+ get(original) {
16
+ return this.manifest[original];
17
+ }
18
+ save() {
19
+ writeFileSync(this.manifestPath, JSON.stringify(this.manifest, null, 2));
20
+ }
21
+ }
@@ -20,5 +20,5 @@ import type { FrameworkConfig } from "../core/config.js";
20
20
  * @throws Logs warnings for missing assets or component bundling failures but does not stop the build.
21
21
  */
22
22
  export declare function buildSite(opts: {
23
- config: FrameworkConfig;
23
+ config: FrameworkConfig;
24
24
  }): Promise<void>;
@@ -0,0 +1,141 @@
1
+ import {
2
+ mkdirSync,
3
+ rmSync,
4
+ writeFileSync,
5
+ existsSync,
6
+ copyFileSync,
7
+ readdirSync,
8
+ statSync,
9
+ } from "node:fs";
10
+ import { join } from "node:path";
11
+ import esbuild from "esbuild";
12
+ import { createScssCompiler } from "../css/compiler.js";
13
+ import {
14
+ vueEsbuildPlugin,
15
+ svelteEsbuildPlugin,
16
+ } from "../compilers/esbuild-plugins.js";
17
+ import { scanRoutes } from "../core/routes/scan.js";
18
+ import { resolveDistPath } from "../core/paths.js";
19
+ import { log } from "../shared/log.js";
20
+ import { renderRouteToHtml } from "../runtime/render.js";
21
+ /**
22
+ * Recursively copies a directory and all its contents.
23
+ * Used to copy static assets from the source directory to the build output.
24
+ * Creates the destination directory structure as needed.
25
+ *
26
+ * @param src The source directory path.
27
+ * @param dst The destination directory path.
28
+ */
29
+ function copyDir(src, dst) {
30
+ if (!existsSync(src)) return;
31
+ mkdirSync(dst, { recursive: true });
32
+ for (const name of readdirSync(src)) {
33
+ const sp = join(src, name);
34
+ const dp = join(dst, name);
35
+ const st = statSync(sp);
36
+ if (st.isDirectory()) copyDir(sp, dp);
37
+ else copyFileSync(sp, dp);
38
+ }
39
+ }
40
+ /**
41
+ * Builds a static site by pre-rendering all routes to HTML files.
42
+ * This is the core static site generation (SSG) function that runs at build time.
43
+ * It performs the following steps:
44
+ * 1. Clears the previous build output directory
45
+ * 2. Discovers all route files in the configured site directory
46
+ * 3. Renders each route to a static HTML file
47
+ * 4. Copies static assets from the source directory
48
+ * 5. Bundles Vue and Svelte components for client-side rehydration
49
+ * 6. Compiles SCSS to CSS for the global stylesheet
50
+ *
51
+ * Routes are rendered with empty req/res objects (SSG mode) to avoid middleware execution.
52
+ * This produces pure static HTML that can be served by any web server.
53
+ * Hydration scripts are still injected if the route has hydrate:true, allowing for
54
+ * optional client-side interactivity in otherwise static pages.
55
+ *
56
+ * @param opts Configuration object.
57
+ * @param opts.config The Jen.js framework configuration.
58
+ * @throws Logs warnings for missing assets or component bundling failures but does not stop the build.
59
+ */
60
+ export async function buildSite(opts) {
61
+ const { config } = opts;
62
+ // Clear and recreate the dist directory for a clean build.
63
+ const dist = resolveDistPath(config);
64
+ rmSync(dist, { recursive: true, force: true });
65
+ mkdirSync(dist, { recursive: true });
66
+ // Discover all routes and pre-render each to a static HTML file.
67
+ const routes = scanRoutes(config);
68
+ log.info(`Building SSG: ${routes.length} routes`);
69
+ for (const r of routes) {
70
+ // Create a synthetic URL for each route. Used as the request URL during rendering.
71
+ const url = new URL("http://localhost" + r.urlPath);
72
+ // Render the route to HTML. Empty req/res indicates SSG mode (no middleware execution).
73
+ const html = await renderRouteToHtml({
74
+ config,
75
+ route: r,
76
+ req: {},
77
+ res: {},
78
+ url,
79
+ params: {},
80
+ query: {},
81
+ headers: {},
82
+ cookies: {},
83
+ });
84
+ // Calculate output path. Root route goes to index.html, nested routes get their own directories.
85
+ const outPath =
86
+ r.urlPath === "/"
87
+ ? join(dist, "index.html")
88
+ : join(dist, r.urlPath.slice(1), "index.html");
89
+ mkdirSync(join(outPath, ".."), { recursive: true });
90
+ writeFileSync(outPath, html, "utf8");
91
+ log.info(`SSG: ${r.urlPath} -> ${outPath}`);
92
+ }
93
+ // Copy static assets from the source assets directory to the built site.
94
+ copyDir(join(process.cwd(), config.siteDir, "assets"), join(dist, "assets"));
95
+ // Bundle Vue and Svelte components found in the site directory.
96
+ // These are transpiled to JavaScript modules for client-side use in interactive pages.
97
+ const siteSourceDir = join(process.cwd(), config.siteDir);
98
+ const vueFiles = readdirSync(siteSourceDir, { recursive: true }).filter(
99
+ (f) => String(f).endsWith(".vue") || String(f).endsWith(".svelte"),
100
+ );
101
+ if (vueFiles.length > 0) {
102
+ log.info(`Found ${vueFiles.length} Vue/Svelte components, bundling...`);
103
+ try {
104
+ await esbuild.build({
105
+ entryPoints: vueFiles.map((f) => join(siteSourceDir, String(f))),
106
+ outdir: join(dist, "components"),
107
+ format: "esm",
108
+ target: "es2022",
109
+ bundle: false,
110
+ plugins: [vueEsbuildPlugin(), svelteEsbuildPlugin()],
111
+ external: ["preact", "vue", "svelte"],
112
+ logLevel: "info",
113
+ });
114
+ log.info("Vue/Svelte components bundled successfully.");
115
+ } catch (err) {
116
+ log.warn(`Failed to bundle Vue/Svelte components: ${err.message}`);
117
+ }
118
+ }
119
+ // Compile the global SCSS file to CSS.
120
+ // This stylesheet is injected into every page and contains framework-wide styles.
121
+ // Minification is enabled for production builds.
122
+ const scssPath = join(process.cwd(), config.css.globalScss);
123
+ if (existsSync(scssPath)) {
124
+ const compiler = createScssCompiler();
125
+ const result = compiler.compile({
126
+ inputPath: scssPath,
127
+ minified: true,
128
+ });
129
+ if (result.error) {
130
+ log.error(`SCSS Compilation Failed: ${result.error}`);
131
+ writeFileSync(join(dist, "styles.css"), "/* SCSS Compilation Failed */");
132
+ } else {
133
+ writeFileSync(join(dist, "styles.css"), result.css);
134
+ log.info(`Compiled global SCSS: ${config.css.globalScss}`);
135
+ }
136
+ } else {
137
+ log.warn(`Global SCSS file not found: ${scssPath}`);
138
+ writeFileSync(join(dist, "styles.css"), "/* No global SCSS found */");
139
+ }
140
+ log.info("Build complete.");
141
+ }
@@ -1,10 +1,10 @@
1
1
  export interface Island {
2
- id: string;
3
- component: string;
4
- props: any;
2
+ id: string;
3
+ component: string;
4
+ props: any;
5
5
  }
6
6
  export interface IslandRegistry {
7
- islands: Island[];
7
+ islands: Island[];
8
8
  }
9
9
  /**
10
10
  * Creates an empty island registry for a request
@@ -22,4 +22,7 @@ export declare function extractIslandsFromHtml(html: string): Island[];
22
22
  /**
23
23
  * Inject hydration script into HTML
24
24
  */
25
- export declare function injectIslandScript(html: string, islands: Island[]): string;
25
+ export declare function injectIslandScript(
26
+ html: string,
27
+ islands: Island[],
28
+ ): string;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Creates an empty island registry for a request
3
+ */
4
+ export function createIslandRegistry() {
5
+ return { islands: [] };
6
+ }
7
+ /**
8
+ * Mark a component as an island (placeholder implementation)
9
+ * In a real framework, this would be a decorator or a HOC
10
+ */
11
+ export function markIsland(name, props) {
12
+ const id = `island-${Math.random().toString(36).slice(2, 9)}`;
13
+ return `<div data-island="${name}" data-props='${JSON.stringify(props)}' id="${id}"></div>`;
14
+ }
15
+ /**
16
+ * Extract islands from HTML string
17
+ */
18
+ export function extractIslandsFromHtml(html) {
19
+ const islands = [];
20
+ const regex = /data-island="([^"]+)" data-props='([^']+)' id="([^"]+)"/g;
21
+ let match;
22
+ while ((match = regex.exec(html)) !== null) {
23
+ islands.push({
24
+ component: match[1],
25
+ props: JSON.parse(match[2]),
26
+ id: match[3],
27
+ });
28
+ }
29
+ return islands;
30
+ }
31
+ /**
32
+ * Inject hydration script into HTML
33
+ */
34
+ export function injectIslandScript(html, islands) {
35
+ if (islands.length === 0) return html;
36
+ const script = `
37
+ <script type="module">
38
+ import { hydrate } from '/__runtime/hydrate.js';
39
+ const islands = ${JSON.stringify(islands)};
40
+ islands.forEach(i => hydrate(i.component, i.id, i.props));
41
+ </script>
42
+ `;
43
+ return html.replace("</body>", `${script}</body>`);
44
+ }
@@ -0,0 +1,20 @@
1
+ export interface MinifyOptions {
2
+ minifyIdentifiers?: boolean;
3
+ minifySyntax?: boolean;
4
+ minifyWhitespace?: boolean;
5
+ target?: string | string[];
6
+ }
7
+ export declare class Minifier {
8
+ /**
9
+ * Minify JavaScript/TypeScript using esbuild
10
+ */
11
+ static minifyJs(code: string, options?: MinifyOptions): Promise<string>;
12
+ /**
13
+ * Minify CSS using esbuild
14
+ */
15
+ static minifyCss(code: string): Promise<string>;
16
+ /**
17
+ * Minify HTML (basic regex/string-based, as esbuild doesn't handle HTML)
18
+ */
19
+ static minifyHtml(html: string): string;
20
+ }
@@ -0,0 +1,46 @@
1
+ import * as esbuild from "esbuild";
2
+ import { log } from "../shared/log.js";
3
+ export class Minifier {
4
+ /**
5
+ * Minify JavaScript/TypeScript using esbuild
6
+ */
7
+ static async minifyJs(code, options = {}) {
8
+ try {
9
+ const result = await esbuild.transform(code, {
10
+ loader: "js",
11
+ minify: true,
12
+ legalComments: "none",
13
+ ...options,
14
+ });
15
+ return result.code;
16
+ } catch (err) {
17
+ log.error("Minification failed (JS)");
18
+ throw err;
19
+ }
20
+ }
21
+ /**
22
+ * Minify CSS using esbuild
23
+ */
24
+ static async minifyCss(code) {
25
+ try {
26
+ const result = await esbuild.transform(code, {
27
+ loader: "css",
28
+ minify: true,
29
+ });
30
+ return result.code;
31
+ } catch (err) {
32
+ log.error("Minification failed (CSS)");
33
+ throw err;
34
+ }
35
+ }
36
+ /**
37
+ * Minify HTML (basic regex/string-based, as esbuild doesn't handle HTML)
38
+ */
39
+ static minifyHtml(html) {
40
+ return html
41
+ .replace(/<!--[\s\S]*?-->/g, "") // Remove comments
42
+ .replace(/>\s+</g, "><") // Remove whitespace between tags
43
+ .replace(/\s{2,}/g, " ") // Collapse multiple whitespaces
44
+ .trim();
45
+ }
46
+ }
@@ -0,0 +1,17 @@
1
+ import { FrameworkConfig } from "../core/config.js";
2
+ import { RouteEntry } from "../core/routes/scan.js";
3
+ export interface PageRenderContext {
4
+ config: FrameworkConfig;
5
+ route: RouteEntry;
6
+ url: URL;
7
+ params: Record<string, string>;
8
+ query: Record<string, string>;
9
+ headers: Record<string, string>;
10
+ cookies: Record<string, string>;
11
+ }
12
+ export declare class PageRenderer {
13
+ /**
14
+ * Render a route to a full HTML string, including minification if requested
15
+ */
16
+ static render(ctx: PageRenderContext, minify?: boolean): Promise<string>;
17
+ }
@@ -0,0 +1,28 @@
1
+ import { renderRouteToHtml } from "../runtime/render.js";
2
+ import { Minifier } from "./minifier.js";
3
+ export class PageRenderer {
4
+ /**
5
+ * Render a route to a full HTML string, including minification if requested
6
+ */
7
+ static async render(ctx, minify = false) {
8
+ // 1. Core Preact render
9
+ let html = await renderRouteToHtml({
10
+ config: ctx.config,
11
+ route: ctx.route,
12
+ req: {},
13
+ res: {},
14
+ url: ctx.url,
15
+ params: ctx.params,
16
+ query: ctx.query,
17
+ headers: ctx.headers,
18
+ cookies: ctx.cookies,
19
+ });
20
+ // 2. Post-processing (Layout injection, hydration script injection)
21
+ // Note: Hydration logic is handled by island-hydration.ts usually
22
+ // 3. Optional Minification
23
+ if (minify) {
24
+ html = Minifier.minifyHtml(html);
25
+ }
26
+ return html;
27
+ }
28
+ }
@@ -0,0 +1,10 @@
1
+ import { FrameworkConfig } from "../core/config.js";
2
+ export interface ProductionBuildConfig {
3
+ config: FrameworkConfig;
4
+ }
5
+ export declare class ProductionBuilder {
6
+ /**
7
+ * Run the production build sequence
8
+ */
9
+ static build(opts: ProductionBuildConfig): Promise<void>;
10
+ }
@@ -0,0 +1,13 @@
1
+ import { SSGPipeline } from "./ssg-pipeline.js";
2
+ import { log } from "../shared/log.js";
3
+ export class ProductionBuilder {
4
+ /**
5
+ * Run the production build sequence
6
+ */
7
+ static async build(opts) {
8
+ log.info("--- PRODUCTION BUILD START ---");
9
+ const pipeline = new SSGPipeline(opts.config);
10
+ await pipeline.run();
11
+ log.info("--- PRODUCTION BUILD COMPLETE ---");
12
+ }
13
+ }
@@ -0,0 +1,15 @@
1
+ import { FrameworkConfig } from "../core/config.js";
2
+ export declare class SSGPipeline {
3
+ private config;
4
+ private dist;
5
+ constructor(config: FrameworkConfig);
6
+ /**
7
+ * Run the full SSG Pipeline
8
+ */
9
+ run(): Promise<void>;
10
+ private prepareDist;
11
+ private processAssets;
12
+ private compileStyles;
13
+ private renderPages;
14
+ private copyRecursive;
15
+ }
@@ -0,0 +1,113 @@
1
+ import {
2
+ mkdirSync,
3
+ rmSync,
4
+ writeFileSync,
5
+ existsSync,
6
+ copyFileSync,
7
+ readdirSync,
8
+ statSync,
9
+ } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { scanRoutes } from "../core/routes/scan.js";
12
+ import { resolveDistPath } from "../core/paths.js";
13
+ import { log } from "../shared/log.js";
14
+ import { PageRenderer } from "./page-renderer.js";
15
+ import { AssetHasher } from "./asset-hashing.js";
16
+ import { createScssCompiler } from "../css/compiler.js";
17
+ export class SSGPipeline {
18
+ config;
19
+ dist;
20
+ constructor(config) {
21
+ this.config = config;
22
+ this.dist = resolveDistPath(config);
23
+ }
24
+ /**
25
+ * Run the full SSG Pipeline
26
+ */
27
+ async run() {
28
+ log.info("Starting SSG Pipeline (Enterprise Build)");
29
+ // 1. Prepare dist
30
+ this.prepareDist();
31
+ // 2. Process Assets
32
+ await this.processAssets();
33
+ // 3. Compile Styles
34
+ const cssPath = await this.compileStyles();
35
+ // 4. Render Pages
36
+ await this.renderPages();
37
+ log.info("Pipeline complete.");
38
+ }
39
+ prepareDist() {
40
+ rmSync(this.dist, { recursive: true, force: true });
41
+ mkdirSync(this.dist, { recursive: true });
42
+ }
43
+ async processAssets() {
44
+ const assetDir = join(process.cwd(), this.config.siteDir, "assets");
45
+ const targetDir = join(this.dist, "assets");
46
+ if (existsSync(assetDir)) {
47
+ this.copyRecursive(assetDir, targetDir);
48
+ log.info("Assets copied to dist");
49
+ }
50
+ }
51
+ async compileStyles() {
52
+ const scssPath = join(process.cwd(), this.config.css.globalScss);
53
+ if (!existsSync(scssPath)) return null;
54
+ const compiler = createScssCompiler();
55
+ const result = compiler.compile({
56
+ inputPath: scssPath,
57
+ minified: true,
58
+ });
59
+ if (result.error) {
60
+ log.error(`SCSS Failed: ${result.error}`);
61
+ return null;
62
+ }
63
+ const cssFile = join(this.dist, "styles.css");
64
+ writeFileSync(cssFile, result.css);
65
+ // Hash the CSS
66
+ const hashedName = AssetHasher.hashFile(cssFile);
67
+ log.info(`Styles compiled and hashed: ${hashedName}`);
68
+ return hashedName;
69
+ }
70
+ async renderPages() {
71
+ const routes = scanRoutes(this.config);
72
+ for (const r of routes) {
73
+ try {
74
+ const url = new URL("http://localhost" + r.urlPath);
75
+ const html = await PageRenderer.render(
76
+ {
77
+ config: this.config,
78
+ route: r,
79
+ url,
80
+ params: {},
81
+ query: {},
82
+ headers: {},
83
+ cookies: {},
84
+ },
85
+ true,
86
+ );
87
+ const outDir = join(
88
+ this.dist,
89
+ r.urlPath === "/" ? "" : r.urlPath.slice(1),
90
+ );
91
+ mkdirSync(outDir, { recursive: true });
92
+ writeFileSync(join(outDir, "index.html"), html);
93
+ log.info(`Rendered ${r.urlPath}`);
94
+ } catch (err) {
95
+ const errorMsg = err instanceof Error ? err.message : String(err);
96
+ log.error(`Failed to render ${r.urlPath}: ${errorMsg}`);
97
+ throw err;
98
+ }
99
+ }
100
+ }
101
+ copyRecursive(src, dst) {
102
+ mkdirSync(dst, { recursive: true });
103
+ for (const name of readdirSync(src)) {
104
+ const sp = join(src, name);
105
+ const dp = join(dst, name);
106
+ if (statSync(sp).isDirectory()) {
107
+ this.copyRecursive(sp, dp);
108
+ } else {
109
+ copyFileSync(sp, dp);
110
+ }
111
+ }
112
+ }
113
+ }