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,945 @@
1
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
2
+ import { join, basename } from "node:path";
3
+ import { resolveDistPath } from "../core/paths.js";
4
+ import { log } from "../shared/log.js";
5
+ async function gzipSize(buffer) {
6
+ const zlib = await import("node:zlib");
7
+ return new Promise((resolve, reject) => {
8
+ zlib.gzip(buffer, (err, result) => {
9
+ if (err) reject(err);
10
+ else resolve(result.length);
11
+ });
12
+ });
13
+ }
14
+ function extractPackageName(modulePath) {
15
+ if (modulePath.includes("node_modules")) {
16
+ const parts = modulePath.split("node_modules");
17
+ const afterModules = parts[1];
18
+ if (afterModules) {
19
+ const match = afterModules.match(/[/\\]([^/\\]+)/);
20
+ return match ? match[1] : "unknown";
21
+ }
22
+ }
23
+ return "local";
24
+ }
25
+ function categorizeModule(modulePath) {
26
+ if (modulePath.includes("node_modules")) {
27
+ return "dependencies";
28
+ }
29
+ if (modulePath.startsWith("/") || modulePath.includes(":")) {
30
+ return "src";
31
+ }
32
+ return "other";
33
+ }
34
+ export async function analyzeBundle(config) {
35
+ const dist = resolveDistPath(config);
36
+ const metaFiles = [
37
+ join(dist, "preact-runtime-meta.json"),
38
+ join(dist, "polyfills-meta.json"),
39
+ ];
40
+ const allModules = [];
41
+ const packageMap = new Map();
42
+ const duplicateMap = new Map();
43
+ const pathCountMap = new Map();
44
+ let totalSize = 0;
45
+ let totalGzipSize = 0;
46
+ const entryPoints = [];
47
+ for (const metaFile of metaFiles) {
48
+ if (!existsSync(metaFile)) {
49
+ continue;
50
+ }
51
+ try {
52
+ const metaContent = readFileSync(metaFile, "utf-8");
53
+ const meta = JSON.parse(metaContent);
54
+ const inputs = meta.inputs || {};
55
+ const outputs = meta.outputs || {};
56
+ for (const [outputPath, outputData] of Object.entries(outputs)) {
57
+ const entryPoint = outputData.entryPoint;
58
+ if (entryPoint) {
59
+ entryPoints.push(entryPoint);
60
+ }
61
+ }
62
+ for (const [inputPath, inputData] of Object.entries(inputs)) {
63
+ const bytes = inputData.bytes || 0;
64
+ if (bytes === 0) continue;
65
+ const normalizedPath = inputPath.replace(/^<(.+)>$/, "$1");
66
+ pathCountMap.set(
67
+ normalizedPath,
68
+ (pathCountMap.get(normalizedPath) || 0) + 1,
69
+ );
70
+ let gzipBytes = 0;
71
+ const fullInputPath = join(dist, "..", normalizedPath);
72
+ if (existsSync(fullInputPath)) {
73
+ const content = readFileSync(fullInputPath);
74
+ gzipBytes = await gzipSize(content);
75
+ }
76
+ if (gzipBytes === 0) {
77
+ gzipBytes = Math.floor(bytes * 0.3);
78
+ }
79
+ const packageName = extractPackageName(normalizedPath);
80
+ const module = {
81
+ path: normalizedPath,
82
+ name: basename(normalizedPath),
83
+ size: bytes,
84
+ gzipSize: gzipBytes,
85
+ percentage: 0,
86
+ imports: inputData.imports?.map((i) => i.original || "") || [],
87
+ importedBy: [],
88
+ package: packageName,
89
+ isLarge: bytes > 50000,
90
+ };
91
+ allModules.push(module);
92
+ totalSize += bytes;
93
+ totalGzipSize += gzipBytes;
94
+ if (!packageMap.has(packageName)) {
95
+ packageMap.set(packageName, { size: 0, modules: [] });
96
+ }
97
+ const pkg = packageMap.get(packageName);
98
+ pkg.size += bytes;
99
+ pkg.modules.push(normalizedPath);
100
+ }
101
+ } catch (err) {
102
+ log.warn(`Failed to parse metafile ${metaFile}: ${err}`);
103
+ }
104
+ }
105
+ for (const [path, count] of pathCountMap) {
106
+ if (count > 1) {
107
+ duplicateMap.set(path, count);
108
+ }
109
+ }
110
+ for (const mod of allModules) {
111
+ mod.percentage = totalSize > 0 ? (mod.size / totalSize) * 100 : 0;
112
+ }
113
+ allModules.sort((a, b) => b.size - a.size);
114
+ return {
115
+ modules: allModules,
116
+ totalSize,
117
+ totalGzipSize,
118
+ duplicateModules: duplicateMap,
119
+ packages: packageMap,
120
+ timestamp: new Date().toISOString(),
121
+ entryPoints,
122
+ };
123
+ }
124
+ function buildTreemap(modules) {
125
+ const packageGroups = new Map();
126
+ for (const mod of modules) {
127
+ const pkg = mod.package || "other";
128
+ if (!packageGroups.has(pkg)) {
129
+ packageGroups.set(pkg, []);
130
+ }
131
+ packageGroups.get(pkg).push(mod);
132
+ }
133
+ const children = [];
134
+ for (const [pkg, mods] of packageGroups) {
135
+ const pkgSize = mods.reduce((sum, m) => sum + m.size, 0);
136
+ const totalSize = modules.reduce((sum, m) => sum + m.size, 0);
137
+ const pkgChildren = mods.map((m) => ({
138
+ name: m.name,
139
+ path: m.path,
140
+ value: m.size,
141
+ percentage: m.percentage,
142
+ isLarge: m.isLarge,
143
+ package: m.package,
144
+ }));
145
+ children.push({
146
+ name: pkg,
147
+ path: pkg,
148
+ value: pkgSize,
149
+ percentage: totalSize > 0 ? (pkgSize / totalSize) * 100 : 0,
150
+ children: pkgChildren,
151
+ });
152
+ }
153
+ return {
154
+ name: "bundle",
155
+ path: "bundle",
156
+ value: modules.reduce((sum, m) => sum + m.size, 0),
157
+ percentage: 100,
158
+ children,
159
+ };
160
+ }
161
+ function formatBytes(bytes) {
162
+ if (bytes === 0) return "0 B";
163
+ const k = 1024;
164
+ const sizes = ["B", "KB", "MB", "GB"];
165
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
166
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
167
+ }
168
+ function minifyHtml(html) {
169
+ return html
170
+ .replace(/<!--[\s\S]*?-->/g, "")
171
+ .replace(/\s+/g, " ")
172
+ .replace(/>\s+</g, "><")
173
+ .replace(/\s*([{}:;,=])\s*/g, "$1")
174
+ .trim();
175
+ }
176
+ function escapeHtml(str) {
177
+ return str
178
+ .replace(/&/g, "&amp;")
179
+ .replace(/</g, "&lt;")
180
+ .replace(/>/g, "&gt;")
181
+ .replace(/"/g, "&quot;")
182
+ .replace(/'/g, "&#039;");
183
+ }
184
+ export async function generateBundleReport(config) {
185
+ log.info("Analyzing bundle...");
186
+ const analysis = await analyzeBundle(config);
187
+ const treemapData = buildTreemap(analysis.modules);
188
+ // Prepare data for template
189
+ const modulesJson = JSON.stringify(analysis.modules);
190
+ const treemapJson = JSON.stringify(treemapData);
191
+ const packagesJson = JSON.stringify(Object.fromEntries(analysis.packages));
192
+ const duplicatesJson = JSON.stringify(
193
+ Object.fromEntries(analysis.duplicateModules),
194
+ );
195
+ const html = `
196
+ body {
197
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
198
+ background: var(--bg-primary);
199
+ color: var(--text-primary);
200
+ min-height: 100vh;
201
+ }
202
+ .header {
203
+ background: var(--bg-secondary);
204
+ border-bottom: 1px solid var(--border);
205
+ padding: 16px 24px;
206
+ display: flex;
207
+ justify-content: space-between;
208
+ align-items: center;
209
+ flex-wrap: wrap;
210
+ gap: 16px;
211
+ }
212
+ .header h1 { font-size: 20px; font-weight: 600; }
213
+ .header .badge {
214
+ background: var(--accent);
215
+ color: var(--bg-primary);
216
+ padding: 4px 12px;
217
+ border-radius: 12px;
218
+ font-size: 12px;
219
+ font-weight: 600;
220
+ }
221
+ .stats-bar {
222
+ display: flex;
223
+ gap: 24px;
224
+ padding: 16px 24px;
225
+ background: var(--bg-secondary);
226
+ border-bottom: 1px solid var(--border);
227
+ flex-wrap: wrap;
228
+ }
229
+ .stat {
230
+ display: flex;
231
+ flex-direction: column;
232
+ gap: 4px;
233
+ }
234
+ .stat-label {
235
+ font-size: 12px;
236
+ color: var(--text-secondary);
237
+ text-transform: uppercase;
238
+ letter-spacing: 0.5px;
239
+ }
240
+ .stat-value {
241
+ font-size: 20px;
242
+ font-weight: 600;
243
+ }
244
+ .controls {
245
+ display: flex;
246
+ gap: 12px;
247
+ padding: 16px 24px;
248
+ border-bottom: 1px solid var(--border);
249
+ flex-wrap: wrap;
250
+ align-items: center;
251
+ }
252
+ .search-box {
253
+ flex: 1;
254
+ min-width: 200px;
255
+ max-width: 400px;
256
+ position: relative;
257
+ }
258
+ .search-box input {
259
+ width: 100%;
260
+ padding: 8px 12px 8px 36px;
261
+ background: var(--bg-tertiary);
262
+ border: 1px solid var(--border);
263
+ border-radius: 6px;
264
+ color: var(--text-primary);
265
+ font-size: 14px;
266
+ }
267
+ .search-box input:focus {
268
+ outline: none;
269
+ border-color: var(--accent);
270
+ }
271
+ .search-box::before {
272
+ content: "⌕";
273
+ position: absolute;
274
+ left: 12px;
275
+ top: 50%;
276
+ transform: translateY(-50%);
277
+ color: var(--text-secondary);
278
+ }
279
+ .btn {
280
+ padding: 8px 16px;
281
+ background: var(--bg-tertiary);
282
+ border: 1px solid var(--border);
283
+ border-radius: 6px;
284
+ color: var(--text-primary);
285
+ font-size: 13px;
286
+ cursor: pointer;
287
+ transition: all 0.15s;
288
+ }
289
+ .btn:hover { background: var(--border); }
290
+ .btn.active {
291
+ background: var(--accent);
292
+ border-color: var(--accent);
293
+ color: var(--bg-primary);
294
+ }
295
+ .toggle-group {
296
+ display: flex;
297
+ gap: 4px;
298
+ background: var(--bg-tertiary);
299
+ border-radius: 6px;
300
+ padding: 4px;
301
+ }
302
+ .toggle-group .btn {
303
+ border: none;
304
+ background: transparent;
305
+ padding: 6px 12px;
306
+ }
307
+ .toggle-group .btn.active {
308
+ background: var(--accent);
309
+ color: var(--bg-primary);
310
+ }
311
+ .main-content {
312
+ display: grid;
313
+ grid-template-columns: 1fr 400px;
314
+ gap: 0;
315
+ height: calc(100vh - 200px);
316
+ }
317
+ @media (max-width: 1024px) {
318
+ .main-content { grid-template-columns: 1fr; height: auto; }
319
+ }
320
+ .treemap-container {
321
+ background: var(--bg-secondary);
322
+ margin: 16px;
323
+ border-radius: 8px;
324
+ border: 1px solid var(--border);
325
+ overflow: hidden;
326
+ position: relative;
327
+ }
328
+ .treemap-header {
329
+ padding: 12px 16px;
330
+ border-bottom: 1px solid var(--border);
331
+ font-weight: 600;
332
+ font-size: 14px;
333
+ }
334
+ #treemap {
335
+ width: 100%;
336
+ height: calc(100% - 45px);
337
+ position: relative;
338
+ }
339
+ .treemap-cell {
340
+ position: absolute;
341
+ border: 1px solid var(--bg-primary);
342
+ overflow: hidden;
343
+ cursor: pointer;
344
+ transition: transform 0.1s, box-shadow 0.1s;
345
+ }
346
+ .treemap-cell:hover {
347
+ z-index: 10;
348
+ box-shadow: 0 4px 12px rgba(0,0,0,0.5);
349
+ }
350
+ .treemap-cell.large {
351
+ background: linear-gradient(135deg, var(--danger) 0%, #ff6b6b 100%);
352
+ }
353
+ .treemap-cell.medium {
354
+ background: linear-gradient(135deg, var(--warning) 0%, #ffd43b 100%);
355
+ }
356
+ .treemap-cell.small {
357
+ background: linear-gradient(135deg, var(--accent) 0%, #79c0ff 100%);
358
+ }
359
+ .treemap-cell.local {
360
+ background: linear-gradient(135deg, var(--success) 0%, #56d364 100%);
361
+ }
362
+ .treemap-cell-label {
363
+ padding: 4px;
364
+ font-size: 11px;
365
+ color: white;
366
+ text-shadow: 0 1px 2px rgba(0,0,0,0.5);
367
+ word-break: break-all;
368
+ }
369
+ .module-list {
370
+ background: var(--bg-secondary);
371
+ margin: 16px;
372
+ margin-left: 0;
373
+ border-radius: 8px;
374
+ border: 1px solid var(--border);
375
+ display: flex;
376
+ flex-direction: column;
377
+ max-height: 100%;
378
+ }
379
+ .module-list-header {
380
+ padding: 12px 16px;
381
+ border-bottom: 1px solid var(--border);
382
+ font-weight: 600;
383
+ font-size: 14px;
384
+ }
385
+ .module-table-wrapper {
386
+ overflow: auto;
387
+ flex: 1;
388
+ }
389
+ .module-table {
390
+ width: 100%;
391
+ border-collapse: collapse;
392
+ font-size: 13px;
393
+ }
394
+ .module-table th {
395
+ position: sticky;
396
+ top: 0;
397
+ background: var(--bg-tertiary);
398
+ padding: 10px 12px;
399
+ text-align: left;
400
+ font-weight: 600;
401
+ color: var(--text-secondary);
402
+ cursor: pointer;
403
+ white-space: nowrap;
404
+ }
405
+ .module-table th:hover { color: var(--text-primary); }
406
+ .module-table td {
407
+ padding: 8px 12px;
408
+ border-bottom: 1px solid var(--border);
409
+ }
410
+ .module-table tr:hover td { background: var(--bg-tertiary); }
411
+ .module-table tr.clickable { cursor: pointer; }
412
+ .module-name {
413
+ max-width: 200px;
414
+ overflow: hidden;
415
+ text-overflow: ellipsis;
416
+ white-space: nowrap;
417
+ }
418
+ .size-bar {
419
+ height: 4px;
420
+ background: var(--bg-tertiary);
421
+ border-radius: 2px;
422
+ overflow: hidden;
423
+ margin-top: 4px;
424
+ }
425
+ .size-bar-fill {
426
+ height: 100%;
427
+ background: var(--accent);
428
+ transition: width 0.3s;
429
+ }
430
+ .percentage { color: var(--text-secondary); font-size: 12px; }
431
+ .large-badge {
432
+ background: var(--danger);
433
+ color: white;
434
+ padding: 2px 6px;
435
+ border-radius: 4px;
436
+ font-size: 10px;
437
+ font-weight: 600;
438
+ margin-left: 8px;
439
+ }
440
+ .detail-panel {
441
+ position: fixed;
442
+ right: -400px;
443
+ top: 0;
444
+ width: 400px;
445
+ height: 100vh;
446
+ background: var(--bg-secondary);
447
+ border-left: 1px solid var(--border);
448
+ transition: right 0.3s;
449
+ z-index: 100;
450
+ display: flex;
451
+ flex-direction: column;
452
+ }
453
+ .detail-panel.open { right: 0; }
454
+ .detail-header {
455
+ padding: 16px;
456
+ border-bottom: 1px solid var(--border);
457
+ display: flex;
458
+ justify-content: space-between;
459
+ align-items: center;
460
+ }
461
+ .detail-header h3 { font-size: 14px; }
462
+ .detail-close {
463
+ background: none;
464
+ border: none;
465
+ color: var(--text-secondary);
466
+ font-size: 20px;
467
+ cursor: pointer;
468
+ }
469
+ .detail-content {
470
+ padding: 16px;
471
+ overflow: auto;
472
+ flex: 1;
473
+ }
474
+ .detail-section {
475
+ margin-bottom: 20px;
476
+ }
477
+ .detail-section h4 {
478
+ font-size: 12px;
479
+ color: var(--text-secondary);
480
+ text-transform: uppercase;
481
+ margin-bottom: 8px;
482
+ }
483
+ .detail-value {
484
+ font-size: 14px;
485
+ word-break: break-all;
486
+ }
487
+ .import-chain {
488
+ background: var(--bg-tertiary);
489
+ padding: 12px;
490
+ border-radius: 6px;
491
+ font-size: 12px;
492
+ font-family: monospace;
493
+ }
494
+ .import-chain-item {
495
+ padding: 4px 0;
496
+ color: var(--text-secondary);
497
+ }
498
+ .import-chain-item::before {
499
+ content: "→ ";
500
+ color: var(--accent);
501
+ }
502
+ .packages-list {
503
+ display: flex;
504
+ flex-direction: column;
505
+ gap: 8px;
506
+ }
507
+ .package-item {
508
+ display: flex;
509
+ justify-content: space-between;
510
+ align-items: center;
511
+ padding: 8px 12px;
512
+ background: var(--bg-tertiary);
513
+ border-radius: 6px;
514
+ }
515
+ .package-name { font-weight: 500; }
516
+ .package-size { color: var(--text-secondary); font-size: 13px; }
517
+ .tab-content { display: none; }
518
+ .tab-content.active { display: block; }
519
+ .zoom-controls {
520
+ position: absolute;
521
+ bottom: 16px;
522
+ right: 16px;
523
+ display: flex;
524
+ gap: 8px;
525
+ z-index: 20;
526
+ }
527
+ .zoom-btn {
528
+ width: 36px;
529
+ height: 36px;
530
+ border-radius: 50%;
531
+ background: var(--bg-tertiary);
532
+ border: 1px solid var(--border);
533
+ color: var(--text-primary);
534
+ font-size: 18px;
535
+ cursor: pointer;
536
+ display: flex;
537
+ align-items: center;
538
+ justify-content: center;
539
+ }
540
+ .zoom-btn:hover { background: var(--border); }
541
+ .breadcrumb {
542
+ padding: 8px 16px;
543
+ background: var(--bg-tertiary);
544
+ font-size: 13px;
545
+ display: flex;
546
+ gap: 8px;
547
+ align-items: center;
548
+ }
549
+ .breadcrumb-item {
550
+ color: var(--text-secondary);
551
+ cursor: pointer;
552
+ }
553
+ .breadcrumb-item:hover { color: var(--accent); }
554
+ .breadcrumb-item::after { content: " /"; color: var(--border); margin-left: 8px; }
555
+ .breadcrumb-item:last-child::after { display: none; }
556
+ </style>
557
+ </head>
558
+ <body>
559
+ <div class="header">
560
+ <h1>📦 Bundle Analyzer</h1>
561
+ <span class="badge">Jen.js</span>
562
+ </div>
563
+
564
+ <div class="stats-bar">
565
+ <div class="stat">
566
+ <span class="stat-label">Total Size</span>
567
+ <span class="stat-value" id="totalSize">${formatBytes(analysis.totalSize)}</span>
568
+ </div>
569
+ <div class="stat">
570
+ <span class="stat-label">Gzipped</span>
571
+ <span class="stat-value" id="gzipSize">${formatBytes(analysis.totalGzipSize)}</span>
572
+ </div>
573
+ <div class="stat">
574
+ <span class="stat-label">Modules</span>
575
+ <span class="stat-value" id="moduleCount">${analysis.modules.length}</span>
576
+ </div>
577
+ <div class="stat">
578
+ <span class="stat-label">Packages</span>
579
+ <span class="stat-value" id="packageCount">${analysis.packages.size}</span>
580
+ </div>
581
+ ${
582
+ analysis.duplicateModules.size > 0
583
+ ? `
584
+ <div class="stat">
585
+ <span class="stat-label">Duplicates</span>
586
+ <span class="stat-value" style="color: var(--warning)">${analysis.duplicateModules.size}</span>
587
+ </div>
588
+ `
589
+ : ""
590
+ }
591
+ </div>
592
+
593
+ <div class="controls">
594
+ <div class="search-box">
595
+ <input type="text" id="searchInput" placeholder="Search modules...">
596
+ </div>
597
+ <div class="toggle-group">
598
+ <button class="btn active" data-view="treemap">Treemap</button>
599
+ <button class="btn" data-view="table">Table</button>
600
+ <button class="btn" data-view="packages">Packages</button>
601
+ </div>
602
+ <div class="toggle-group">
603
+ <button class="btn active" data-size="raw">Raw</button>
604
+ <button class="btn" data-size="gzip">Gzip</button>
605
+ </div>
606
+ </div>
607
+
608
+ <div class="main-content">
609
+ <div class="treemap-container" id="treemapContainer">
610
+ <div class="treemap-header">Bundle Treemap</div>
611
+ <div class="breadcrumb" id="breadcrumb"></div>
612
+ <div id="treemap"></div>
613
+ <div class="zoom-controls">
614
+ <button class="zoom-btn" id="zoomIn">+</button>
615
+ <button class="zoom-btn" id="zoomOut">−</button>
616
+ <button class="zoom-btn" id="zoomReset">↺</button>
617
+ </div>
618
+ </div>
619
+
620
+ <div class="module-list" id="tableContainer" style="display: none;">
621
+ <div class="module-list-header">All Modules</div>
622
+ <div class="module-table-wrapper">
623
+ <table class="module-table">
624
+ <thead>
625
+ <tr>
626
+ <th data-sort="name">Module</th>
627
+ <th data-sort="size" data-dir="desc">Size</th>
628
+ <th data-sort="gzipSize">Gzip</th>
629
+ <th data-sort="percentage" data-dir="desc">%</th>
630
+ </tr>
631
+ </thead>
632
+ <tbody id="moduleTableBody"></tbody>
633
+ </table>
634
+ </div>
635
+ </div>
636
+
637
+ <div class="module-list" id="packagesContainer" style="display: none;">
638
+ <div class="module-list-header">Bundle Composition by Package</div>
639
+ <div class="module-table-wrapper">
640
+ <div class="packages-list" id="packagesList"></div>
641
+ </div>
642
+ </div>
643
+ </div>
644
+
645
+ <div class="detail-panel" id="detailPanel">
646
+ <div class="detail-header">
647
+ <h3>Module Details</h3>
648
+ <button class="detail-close" id="detailClose">×</button>
649
+ </div>
650
+ <div class="detail-content">
651
+ <div class="detail-section">
652
+ <h4>Path</h4>
653
+ <div class="detail-value" id="detailPath"></div>
654
+ </div>
655
+ <div class="detail-section">
656
+ <h4>Size</h4>
657
+ <div class="detail-value" id="detailSize"></div>
658
+ </div>
659
+ <div class="detail-section">
660
+ <h4>Gzipped</h4>
661
+ <div class="detail-value" id="detailGzip"></div>
662
+ </div>
663
+ <div class="detail-section">
664
+ <h4>Percentage</h4>
665
+ <div class="detail-value" id="detailPercentage"></div>
666
+ </div>
667
+ <div class="detail-section">
668
+ <h4>Package</h4>
669
+ <div class="detail-value" id="detailPackage"></div>
670
+ </div>
671
+ </div>
672
+ </div>
673
+
674
+ <script>
675
+ const modules = ${modulesJson};
676
+ const treemapData = ${treemapJson};
677
+ const packagesData = ${packagesJson};
678
+ const duplicatesData = ${duplicatesJson};
679
+
680
+ let currentView = 'treemap';
681
+ let currentSize = 'raw';
682
+ let currentSort = { field: 'size', dir: 'desc' };
683
+ let treemapZoom = 1;
684
+ let treemapOffset = { x: 0, y: 0 };
685
+ let currentTreemapNode = treemapData;
686
+ let treemapHistory = [treemapData];
687
+
688
+ function formatBytes(bytes) {
689
+ if (bytes === 0) return '0 B';
690
+ const k = 1024;
691
+ const sizes = ['B', 'KB', 'MB', 'GB'];
692
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
693
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
694
+ }
695
+
696
+ function escapeHtml(str) {
697
+ return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
698
+ }
699
+
700
+ function getSize(m) {
701
+ return currentSize === 'gzip' ? m.gzipSize : m.size;
702
+ }
703
+
704
+ function sortModules(mods) {
705
+ return [...mods].sort((a, b) => {
706
+ const aVal = currentSort.field === 'name' ? a[currentSort.field] : getSize(a);
707
+ const bVal = currentSort.field === 'name' ? b[currentSort.field] : getSize(b);
708
+ const cmp = aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
709
+ return currentSort.dir === 'desc' ? -cmp : cmp;
710
+ });
711
+ }
712
+
713
+ function renderTable(filteredModules) {
714
+ const sorted = sortModules(filteredModules);
715
+ const tbody = document.getElementById('moduleTableBody');
716
+ tbody.innerHTML = sorted.map(m => {
717
+ const size = getSize(m);
718
+ const pct = (size / ${analysis.totalSize}) * 100;
719
+ return \`<tr class="clickable" data-path="\${escapeHtml(m.path)}">
720
+ <td class="module-name">\${escapeHtml(m.name)}<span class="path-hint" style="color: var(--text-secondary); font-size: 11px;">\${escapeHtml(m.path.replace(m.name, ''))}</span>\${m.isLarge ? '<span class="large-badge">LARGE</span>' : ''}</td>
721
+ <td>\${formatBytes(m.size)}<div class="size-bar"><div class="size-bar-fill" style="width: \${Math.min(pct * 10, 100)}%"></div></div></td>
722
+ <td>\${formatBytes(m.gzipSize)}</td>
723
+ <td class="percentage">\${pct.toFixed(2)}%</td>
724
+ </tr>\`;
725
+ }).join('');
726
+
727
+ tbody.querySelectorAll('tr').forEach(row => {
728
+ row.addEventListener('click', () => showDetail(row.dataset.path));
729
+ });
730
+ }
731
+
732
+ function renderPackages() {
733
+ const list = document.getElementById('packagesList');
734
+ const sorted = Object.entries(packagesData).sort((a, b) => b[1].size - a[1].size);
735
+ list.innerHTML = sorted.map(([name, data]) => {
736
+ const pct = (data.size / ${analysis.totalSize}) * 100;
737
+ return \`<div class="package-item">
738
+ <span class="package-name">\${escapeHtml(name)}</span>
739
+ <span class="package-size">\${formatBytes(data.size)} (\${pct.toFixed(1)}%)</span>
740
+ </div>\`;
741
+ }).join('');
742
+ }
743
+
744
+ function renderTreemap(node) {
745
+ const container = document.getElementById('treemap');
746
+ const rect = container.getBoundingClientRect();
747
+ const width = rect.width;
748
+ const height = rect.height;
749
+
750
+ container.innerHTML = '';
751
+
752
+ if (!node.children || node.children.length === 0) return;
753
+
754
+ const totalValue = node.children.reduce((sum, c) => sum + getSize(c), 0);
755
+
756
+ const rows = [];
757
+ let currentRow = [];
758
+ let currentRowHeight = 0;
759
+
760
+ for (const child of node.children) {
761
+ const size = getSize(child);
762
+ const childHeight = (size / totalValue) * height;
763
+
764
+ if (childHeight > 50 || currentRowHeight < 50) {
765
+ if (currentRow.length > 0 && Math.abs(childHeight - currentRowHeight) > currentRowHeight * 0.5) {
766
+ rows.push(currentRow);
767
+ currentRow = [];
768
+ }
769
+ currentRow.push(child);
770
+ currentRowHeight = childHeight;
771
+ } else {
772
+ currentRow.push(child);
773
+ }
774
+ }
775
+ if (currentRow.length > 0) rows.push(currentRow);
776
+
777
+ let y = 0;
778
+ rows.forEach(row => {
779
+ const rowTotal = row.reduce((sum, c) => sum + getSize(c), 0);
780
+ const rowHeight = Math.max(30, (rowTotal / totalValue) * height * 0.9);
781
+
782
+ let x = 0;
783
+ row.forEach(child => {
784
+ const size = getSize(child);
785
+ const cellWidth = (size / rowTotal) * width;
786
+ const cellHeight = rowHeight;
787
+
788
+ const el = document.createElement('div');
789
+ el.className = 'treemap-cell';
790
+
791
+ let cellClass = 'small';
792
+ if (child.isLarge || (child.value && child.value > 50000)) cellClass = 'large';
793
+ else if (child.value && child.value > 20000) cellClass = 'medium';
794
+ if (child.package === 'local' || (!child.package && child.path && !child.path.includes('node_modules'))) cellClass = 'local';
795
+
796
+ el.classList.add(cellClass);
797
+ el.style.left = (x * treemapZoom + treemapOffset.x) + 'px';
798
+ el.style.top = (y * treemapZoom + treemapOffset.y) + 'px';
799
+ el.style.width = (cellWidth * treemapZoom - 2) + 'px';
800
+ el.style.height = (cellHeight * treemapZoom - 2) + 'px';
801
+
802
+ const label = document.createElement('div');
803
+ label.className = 'treemap-cell-label';
804
+ label.textContent = child.name.length > 20 ? child.name.slice(0, 17) + '...' : child.name;
805
+ el.appendChild(label);
806
+
807
+ el.addEventListener('click', () => {
808
+ if (child.children && child.children.length > 0) {
809
+ treemapHistory.push(child);
810
+ currentTreemapNode = child;
811
+ renderTreemap(child);
812
+ updateBreadcrumb();
813
+ } else {
814
+ showDetail(child.path);
815
+ }
816
+ });
817
+
818
+ container.appendChild(el);
819
+ x += cellWidth;
820
+ });
821
+ y += rowHeight;
822
+ });
823
+
824
+ updateBreadcrumb();
825
+ }
826
+
827
+ function updateBreadcrumb() {
828
+ const breadcrumb = document.getElementById('breadcrumb');
829
+ breadcrumb.innerHTML = treemapHistory.map((node, i) => {
830
+ const isLast = i === treemapHistory.length - 1;
831
+ return \`<span class="breadcrumb-item" data-index="\${i}">\${node.name}\${isLast ? '' : '/'}</span>\`;
832
+ }).join('');
833
+
834
+ breadcrumb.querySelectorAll('.breadcrumb-item').forEach(item => {
835
+ item.addEventListener('click', () => {
836
+ const idx = parseInt(item.dataset.index);
837
+ treemapHistory = treemapHistory.slice(0, idx + 1);
838
+ currentTreemapNode = treemapHistory[treemapHistory.length - 1];
839
+ renderTreemap(currentTreemapNode);
840
+ });
841
+ });
842
+ }
843
+
844
+ function showDetail(path) {
845
+ const m = modules.find(mod => mod.path === path);
846
+ if (!m) return;
847
+
848
+ document.getElementById('detailPath').textContent = m.path;
849
+ document.getElementById('detailSize').textContent = formatBytes(m.size);
850
+ document.getElementById('detailGzip').textContent = formatBytes(m.gzipSize);
851
+ document.getElementById('detailPercentage').textContent = m.percentage.toFixed(2) + '%';
852
+ document.getElementById('detailPackage').textContent = m.package || 'unknown';
853
+
854
+ document.getElementById('detailPanel').classList.add('open');
855
+ }
856
+
857
+ document.getElementById('detailClose').addEventListener('click', () => {
858
+ document.getElementById('detailPanel').classList.remove('open');
859
+ });
860
+
861
+ document.getElementById('searchInput').addEventListener('input', (e) => {
862
+ const q = e.target.value.toLowerCase();
863
+ const filtered = modules.filter(m =>
864
+ m.path.toLowerCase().includes(q) || m.name.toLowerCase().includes(q)
865
+ );
866
+
867
+ if (currentView === 'table') {
868
+ renderTable(filtered);
869
+ }
870
+ });
871
+
872
+ document.querySelectorAll('[data-view]').forEach(btn => {
873
+ btn.addEventListener('click', () => {
874
+ document.querySelectorAll('[data-view]').forEach(b => b.classList.remove('active'));
875
+ btn.classList.add('active');
876
+ currentView = btn.dataset.view;
877
+
878
+ document.getElementById('treemapContainer').style.display = currentView === 'treemap' ? 'block' : 'none';
879
+ document.getElementById('tableContainer').style.display = currentView === 'table' ? 'flex' : 'none';
880
+ document.getElementById('packagesContainer').style.display = currentView === 'packages' ? 'flex' : 'none';
881
+
882
+ if (currentView === 'table') renderTable(modules);
883
+ if (currentView === 'packages') renderPackages();
884
+ });
885
+ });
886
+
887
+ document.querySelectorAll('[data-size]').forEach(btn => {
888
+ btn.addEventListener('click', () => {
889
+ document.querySelectorAll('[data-size]').forEach(b => b.classList.remove('active'));
890
+ btn.classList.add('active');
891
+ currentSize = btn.dataset.size;
892
+
893
+ document.getElementById('totalSize').textContent = formatBytes(${analysis.totalSize});
894
+ document.getElementById('gzipSize').textContent = formatBytes(${analysis.totalGzipSize});
895
+
896
+ if (currentView === 'treemap') renderTreemap(currentTreemapNode);
897
+ if (currentView === 'table') renderTable(modules);
898
+ });
899
+ });
900
+
901
+ document.querySelectorAll('.module-table th').forEach(th => {
902
+ th.addEventListener('click', () => {
903
+ const field = th.dataset.sort;
904
+ if (currentSort.field === field) {
905
+ currentSort.dir = currentSort.dir === 'asc' ? 'desc' : 'asc';
906
+ } else {
907
+ currentSort.field = field;
908
+ currentSort.dir = 'desc';
909
+ }
910
+ renderTable(modules);
911
+ });
912
+ });
913
+
914
+ document.getElementById('zoomIn').addEventListener('click', () => {
915
+ treemapZoom = Math.min(treemapZoom * 1.2, 5);
916
+ renderTreemap(currentTreemapNode);
917
+ });
918
+
919
+ document.getElementById('zoomOut').addEventListener('click', () => {
920
+ treemapZoom = Math.max(treemapZoom / 1.2, 0.5);
921
+ renderTreemap(currentTreemapNode);
922
+ });
923
+
924
+ document.getElementById('zoomReset').addEventListener('click', () => {
925
+ treemapZoom = 1;
926
+ treemapOffset = { x: 0, y: 0 };
927
+ currentTreemapNode = treemapData;
928
+ treemapHistory = [treemapData];
929
+ renderTreemap(currentTreemapNode);
930
+ });
931
+
932
+ renderTreemap(treemapData);
933
+ </script>
934
+ </body>
935
+ </html>`;
936
+ return minifyHtml(html);
937
+ }
938
+ export async function runBundleAnalyzer(config) {
939
+ const dist = resolveDistPath(config);
940
+ const reportPath = join(dist, "bundle-report.html");
941
+ const htmlContent = await generateBundleReport(config);
942
+ writeFileSync(reportPath, htmlContent, "utf-8");
943
+ log.info(`Bundle report generated: ${reportPath}`);
944
+ return reportPath;
945
+ }