@buenojs/bueno 0.8.4 → 0.8.6

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 (234) hide show
  1. package/README.md +264 -17
  2. package/dist/cli/{index.js → bin.js} +413 -332
  3. package/dist/container/index.js +273 -0
  4. package/dist/context/index.js +219 -0
  5. package/dist/database/index.js +493 -0
  6. package/dist/frontend/index.js +7697 -0
  7. package/dist/graphql/index.js +2156 -0
  8. package/dist/health/index.js +364 -0
  9. package/dist/i18n/index.js +345 -0
  10. package/dist/index.js +9694 -5047
  11. package/dist/jobs/index.js +819 -0
  12. package/dist/lock/index.js +367 -0
  13. package/dist/logger/index.js +281 -0
  14. package/dist/metrics/index.js +289 -0
  15. package/dist/middleware/index.js +77 -0
  16. package/dist/migrations/index.js +571 -0
  17. package/dist/modules/index.js +3411 -0
  18. package/dist/notification/index.js +484 -0
  19. package/dist/observability/index.js +331 -0
  20. package/dist/openapi/index.js +795 -0
  21. package/dist/orm/index.js +1356 -0
  22. package/dist/router/index.js +886 -0
  23. package/dist/rpc/index.js +691 -0
  24. package/dist/schema/index.js +400 -0
  25. package/dist/telemetry/index.js +595 -0
  26. package/dist/template/index.js +640 -0
  27. package/dist/templates/index.js +640 -0
  28. package/dist/testing/index.js +1111 -0
  29. package/dist/types/index.js +60 -0
  30. package/llms.txt +231 -0
  31. package/package.json +125 -27
  32. package/src/cache/index.ts +2 -1
  33. package/src/cli/ARCHITECTURE.md +3 -3
  34. package/src/cli/bin.ts +2 -2
  35. package/src/cli/commands/build.ts +183 -165
  36. package/src/cli/commands/dev.ts +96 -89
  37. package/src/cli/commands/generate.ts +142 -111
  38. package/src/cli/commands/help.ts +20 -16
  39. package/src/cli/commands/index.ts +3 -6
  40. package/src/cli/commands/migration.ts +124 -105
  41. package/src/cli/commands/new.ts +294 -232
  42. package/src/cli/commands/start.ts +81 -79
  43. package/src/cli/core/args.ts +68 -50
  44. package/src/cli/core/console.ts +89 -95
  45. package/src/cli/core/index.ts +4 -4
  46. package/src/cli/core/prompt.ts +65 -62
  47. package/src/cli/core/spinner.ts +23 -20
  48. package/src/cli/index.ts +46 -38
  49. package/src/cli/templates/database/index.ts +37 -18
  50. package/src/cli/templates/database/mysql.ts +3 -3
  51. package/src/cli/templates/database/none.ts +2 -2
  52. package/src/cli/templates/database/postgresql.ts +3 -3
  53. package/src/cli/templates/database/sqlite.ts +3 -3
  54. package/src/cli/templates/deploy.ts +29 -26
  55. package/src/cli/templates/docker.ts +41 -30
  56. package/src/cli/templates/frontend/index.ts +33 -15
  57. package/src/cli/templates/frontend/none.ts +2 -2
  58. package/src/cli/templates/frontend/react.ts +18 -18
  59. package/src/cli/templates/frontend/solid.ts +15 -15
  60. package/src/cli/templates/frontend/svelte.ts +17 -17
  61. package/src/cli/templates/frontend/vue.ts +15 -15
  62. package/src/cli/templates/generators/index.ts +29 -29
  63. package/src/cli/templates/generators/types.ts +21 -21
  64. package/src/cli/templates/index.ts +6 -6
  65. package/src/cli/templates/project/api.ts +37 -36
  66. package/src/cli/templates/project/default.ts +25 -25
  67. package/src/cli/templates/project/fullstack.ts +28 -26
  68. package/src/cli/templates/project/index.ts +55 -16
  69. package/src/cli/templates/project/minimal.ts +17 -12
  70. package/src/cli/templates/project/types.ts +10 -5
  71. package/src/cli/templates/project/website.ts +15 -15
  72. package/src/cli/utils/fs.ts +55 -41
  73. package/src/cli/utils/index.ts +3 -3
  74. package/src/cli/utils/strings.ts +47 -33
  75. package/src/cli/utils/version.ts +14 -8
  76. package/src/config/env-validation.ts +100 -0
  77. package/src/config/env.ts +169 -41
  78. package/src/config/index.ts +28 -20
  79. package/src/config/loader.ts +25 -16
  80. package/src/config/merge.ts +21 -10
  81. package/src/config/types.ts +566 -25
  82. package/src/config/validation.ts +215 -7
  83. package/src/container/forward-ref.ts +22 -22
  84. package/src/container/index.ts +34 -12
  85. package/src/context/index.ts +11 -1
  86. package/src/database/index.ts +7 -190
  87. package/src/database/orm/builder.ts +457 -0
  88. package/src/database/orm/casts/index.ts +130 -0
  89. package/src/database/orm/casts/types.ts +25 -0
  90. package/src/database/orm/compiler.ts +304 -0
  91. package/src/database/orm/hooks/index.ts +114 -0
  92. package/src/database/orm/index.ts +61 -0
  93. package/src/database/orm/model-registry.ts +59 -0
  94. package/src/database/orm/model.ts +821 -0
  95. package/src/database/orm/relationships/base.ts +146 -0
  96. package/src/database/orm/relationships/belongs-to-many.ts +179 -0
  97. package/src/database/orm/relationships/belongs-to.ts +56 -0
  98. package/src/database/orm/relationships/has-many.ts +45 -0
  99. package/src/database/orm/relationships/has-one.ts +41 -0
  100. package/src/database/orm/relationships/index.ts +11 -0
  101. package/src/database/orm/scopes/index.ts +55 -0
  102. package/src/events/__tests__/event-system.test.ts +235 -0
  103. package/src/events/config.ts +238 -0
  104. package/src/events/example-usage.ts +185 -0
  105. package/src/events/index.ts +278 -0
  106. package/src/events/manager.ts +385 -0
  107. package/src/events/registry.ts +182 -0
  108. package/src/events/types.ts +124 -0
  109. package/src/frontend/api-routes.ts +65 -23
  110. package/src/frontend/bundler.ts +76 -34
  111. package/src/frontend/console-client.ts +2 -2
  112. package/src/frontend/console-stream.ts +94 -38
  113. package/src/frontend/dev-server.ts +94 -46
  114. package/src/frontend/file-router.ts +61 -19
  115. package/src/frontend/frameworks/index.ts +37 -10
  116. package/src/frontend/frameworks/react.ts +10 -8
  117. package/src/frontend/frameworks/solid.ts +11 -9
  118. package/src/frontend/frameworks/svelte.ts +15 -9
  119. package/src/frontend/frameworks/vue.ts +13 -11
  120. package/src/frontend/hmr-client.ts +12 -10
  121. package/src/frontend/hmr.ts +146 -103
  122. package/src/frontend/index.ts +14 -5
  123. package/src/frontend/islands.ts +41 -22
  124. package/src/frontend/isr.ts +59 -37
  125. package/src/frontend/layout.ts +36 -21
  126. package/src/frontend/ssr/react.ts +74 -27
  127. package/src/frontend/ssr/solid.ts +54 -20
  128. package/src/frontend/ssr/svelte.ts +48 -14
  129. package/src/frontend/ssr/vue.ts +50 -18
  130. package/src/frontend/ssr.ts +83 -39
  131. package/src/frontend/types.ts +91 -56
  132. package/src/graphql/built-in-engine.ts +598 -0
  133. package/src/graphql/context-builder.ts +110 -0
  134. package/src/graphql/decorators.ts +358 -0
  135. package/src/graphql/execution-pipeline.ts +227 -0
  136. package/src/graphql/graphql-module.ts +563 -0
  137. package/src/graphql/index.ts +101 -0
  138. package/src/graphql/metadata.ts +237 -0
  139. package/src/graphql/schema-builder.ts +319 -0
  140. package/src/graphql/subscription-handler.ts +283 -0
  141. package/src/graphql/types.ts +324 -0
  142. package/src/health/index.ts +21 -9
  143. package/src/i18n/engine.ts +305 -0
  144. package/src/i18n/index.ts +38 -0
  145. package/src/i18n/loader.ts +218 -0
  146. package/src/i18n/middleware.ts +164 -0
  147. package/src/i18n/negotiator.ts +162 -0
  148. package/src/i18n/types.ts +158 -0
  149. package/src/index.ts +182 -27
  150. package/src/jobs/drivers/memory.ts +315 -0
  151. package/src/jobs/drivers/redis.ts +459 -0
  152. package/src/jobs/index.ts +30 -0
  153. package/src/jobs/queue.ts +281 -0
  154. package/src/jobs/types.ts +295 -0
  155. package/src/jobs/worker.ts +380 -0
  156. package/src/logger/index.ts +1 -3
  157. package/src/logger/transports/index.ts +62 -22
  158. package/src/metrics/index.ts +25 -16
  159. package/src/migrations/index.ts +9 -0
  160. package/src/modules/filters.ts +13 -17
  161. package/src/modules/guards.ts +49 -26
  162. package/src/modules/index.ts +457 -299
  163. package/src/modules/interceptors.ts +58 -20
  164. package/src/modules/lazy.ts +11 -19
  165. package/src/modules/lifecycle.ts +15 -7
  166. package/src/modules/metadata.ts +15 -5
  167. package/src/modules/pipes.ts +94 -72
  168. package/src/notification/channels/base.ts +68 -0
  169. package/src/notification/channels/email.ts +105 -0
  170. package/src/notification/channels/push.ts +104 -0
  171. package/src/notification/channels/sms.ts +105 -0
  172. package/src/notification/channels/whatsapp.ts +104 -0
  173. package/src/notification/index.ts +48 -0
  174. package/src/notification/service.ts +354 -0
  175. package/src/notification/types.ts +344 -0
  176. package/src/observability/__tests__/observability.test.ts +483 -0
  177. package/src/observability/breadcrumbs.ts +114 -0
  178. package/src/observability/index.ts +136 -0
  179. package/src/observability/interceptor.ts +85 -0
  180. package/src/observability/service.ts +303 -0
  181. package/src/observability/trace.ts +37 -0
  182. package/src/observability/types.ts +196 -0
  183. package/src/openapi/__tests__/decorators.test.ts +335 -0
  184. package/src/openapi/__tests__/document-builder.test.ts +285 -0
  185. package/src/openapi/__tests__/route-scanner.test.ts +334 -0
  186. package/src/openapi/__tests__/schema-generator.test.ts +275 -0
  187. package/src/openapi/decorators.ts +328 -0
  188. package/src/openapi/document-builder.ts +274 -0
  189. package/src/openapi/index.ts +112 -0
  190. package/src/openapi/metadata.ts +112 -0
  191. package/src/openapi/route-scanner.ts +289 -0
  192. package/src/openapi/schema-generator.ts +256 -0
  193. package/src/openapi/swagger-module.ts +166 -0
  194. package/src/openapi/types.ts +398 -0
  195. package/src/orm/index.ts +10 -0
  196. package/src/rpc/index.ts +3 -1
  197. package/src/schema/index.ts +9 -0
  198. package/src/security/index.ts +15 -6
  199. package/src/ssg/index.ts +9 -8
  200. package/src/telemetry/index.ts +76 -22
  201. package/src/template/index.ts +7 -0
  202. package/src/templates/engine.ts +224 -0
  203. package/src/templates/index.ts +9 -0
  204. package/src/templates/loader.ts +331 -0
  205. package/src/templates/renderers/markdown.ts +212 -0
  206. package/src/templates/renderers/simple.ts +269 -0
  207. package/src/templates/types.ts +154 -0
  208. package/src/testing/index.ts +100 -27
  209. package/src/types/optional-deps.d.ts +347 -187
  210. package/src/validation/index.ts +92 -2
  211. package/src/validation/schemas.ts +536 -0
  212. package/tests/integration/cli.test.ts +19 -19
  213. package/tests/integration/fullstack.test.ts +4 -4
  214. package/tests/unit/cli.test.ts +1 -1
  215. package/tests/unit/database.test.ts +2 -72
  216. package/tests/unit/env-validation.test.ts +166 -0
  217. package/tests/unit/events.test.ts +910 -0
  218. package/tests/unit/graphql.test.ts +991 -0
  219. package/tests/unit/i18n.test.ts +455 -0
  220. package/tests/unit/jobs.test.ts +493 -0
  221. package/tests/unit/notification.test.ts +988 -0
  222. package/tests/unit/observability.test.ts +453 -0
  223. package/tests/unit/orm/builder.test.ts +323 -0
  224. package/tests/unit/orm/casts.test.ts +179 -0
  225. package/tests/unit/orm/compiler.test.ts +220 -0
  226. package/tests/unit/orm/eager-loading.test.ts +285 -0
  227. package/tests/unit/orm/hooks.test.ts +191 -0
  228. package/tests/unit/orm/model.test.ts +373 -0
  229. package/tests/unit/orm/relationships.test.ts +303 -0
  230. package/tests/unit/orm/scopes.test.ts +74 -0
  231. package/tests/unit/templates-simple.test.ts +53 -0
  232. package/tests/unit/templates.test.ts +454 -0
  233. package/tests/unit/validation.test.ts +18 -24
  234. package/tsconfig.json +11 -3
@@ -10,33 +10,37 @@
10
10
  * - Graceful shutdown handling
11
11
  */
12
12
 
13
- import { Router, type RouteMatch } from "../router/index.js";
14
- import { Logger, createLogger } from "../logger/index.js";
13
+ import { type Logger, createLogger } from "../logger/index.js";
14
+ import type { RouteMatch, Router } from "../router/index.js";
15
15
  import type { HTTPMethod } from "../types/index.js";
16
+ import {
17
+ type ConsoleStreamManager,
18
+ createConsoleStreamManager,
19
+ injectConsoleScript,
20
+ } from "./console-stream.js";
21
+ import { injectHMRScript } from "./hmr-client.js";
22
+ import { type HMRManager, createHMRManager } from "./hmr.js";
23
+ import { type SSRRenderer, createSSRRenderer } from "./ssr.js";
16
24
  import type {
25
+ BuildManifest,
26
+ ConsoleStreamConfig,
17
27
  DevServerConfig,
18
- PartialDevServerConfig,
28
+ DevServerEvent,
29
+ DevServerEventListener,
30
+ DevServerMiddleware,
19
31
  DevServerState,
20
- FrontendFramework,
21
- FrameworkDetectionResult,
22
- PackageDependencies,
23
32
  FileResolution,
24
- DevServerMiddleware,
25
- DevServerEventListener,
26
- DevServerEvent,
27
- TransformResult,
28
- TransformOptions,
33
+ FrameworkDetectionResult,
34
+ FrontendFramework,
29
35
  HMRConfig,
30
- ConsoleStreamConfig,
36
+ PackageDependencies,
31
37
  PartialConsoleStreamConfig,
32
- SSRConfig,
38
+ PartialDevServerConfig,
33
39
  PartialSSRConfig,
34
- BuildManifest,
40
+ SSRConfig,
41
+ TransformOptions,
42
+ TransformResult,
35
43
  } from "./types.js";
36
- import { HMRManager, createHMRManager } from "./hmr.js";
37
- import { injectHMRScript } from "./hmr-client.js";
38
- import { ConsoleStreamManager, createConsoleStreamManager, injectConsoleScript } from "./console-stream.js";
39
- import { SSRRenderer, createSSRRenderer } from "./ssr.js";
40
44
 
41
45
  // ============= Constants =============
42
46
 
@@ -101,7 +105,9 @@ function detectFramework(rootDir: string): FrameworkDetectionResult {
101
105
  }
102
106
 
103
107
  // Read package.json synchronously using Bun's sync read
104
- const packageJson = JSON.parse(require("fs").readFileSync(packageJsonPath, "utf-8"));
108
+ const packageJson = JSON.parse(
109
+ require("fs").readFileSync(packageJsonPath, "utf-8"),
110
+ );
105
111
  const dependencies: PackageDependencies = {
106
112
  ...packageJson.dependencies,
107
113
  ...packageJson.devDependencies,
@@ -109,7 +115,12 @@ function detectFramework(rootDir: string): FrameworkDetectionResult {
109
115
 
110
116
  // Check for each framework in order of specificity
111
117
  // Solid and Svelte are more specific than React/Vue
112
- const frameworkOrder: FrontendFramework[] = ["solid", "svelte", "vue", "react"];
118
+ const frameworkOrder: FrontendFramework[] = [
119
+ "solid",
120
+ "svelte",
121
+ "vue",
122
+ "react",
123
+ ];
113
124
 
114
125
  for (const framework of frameworkOrder) {
115
126
  const indicators = FRAMEWORK_INDICATORS[framework];
@@ -192,7 +203,7 @@ export class DevServer {
192
203
  if (this.config.hmr) {
193
204
  this.hmrManager = createHMRManager(
194
205
  frameworkResult.framework,
195
- this.config.port
206
+ this.config.port,
196
207
  );
197
208
  this.logger.info("HMR enabled");
198
209
  }
@@ -201,7 +212,7 @@ export class DevServer {
201
212
  if (this.config.consoleStream?.enabled !== false) {
202
213
  this.consoleStreamManager = createConsoleStreamManager(
203
214
  this.config.port,
204
- this.config.consoleStream
215
+ this.config.consoleStream,
205
216
  );
206
217
  this.logger.info("Console streaming enabled");
207
218
  }
@@ -341,7 +352,9 @@ export class DevServer {
341
352
  /**
342
353
  * Transform a file based on its type
343
354
  */
344
- private async transformFile(options: TransformOptions): Promise<TransformResult> {
355
+ private async transformFile(
356
+ options: TransformOptions,
357
+ ): Promise<TransformResult> {
345
358
  const { filePath, content, framework } = options;
346
359
 
347
360
  // For JSX/TSX files, Bun handles transpilation automatically
@@ -387,17 +400,17 @@ export class DevServer {
387
400
  // Inject HMR and Console scripts for HTML files
388
401
  if (resolution.contentType === "text/html; charset=utf-8") {
389
402
  let html = await file.text();
390
-
403
+
391
404
  // Inject HMR script
392
405
  if (this.hmrManager) {
393
406
  html = injectHMRScript(html, this.hmrManager.getPort());
394
407
  }
395
-
408
+
396
409
  // Inject Console Stream script
397
410
  if (this.consoleStreamManager) {
398
411
  html = injectConsoleScript(html, this.consoleStreamManager.getPort());
399
412
  }
400
-
413
+
401
414
  return new Response(html, {
402
415
  headers: {
403
416
  "Content-Type": "text/html; charset=utf-8",
@@ -407,7 +420,8 @@ export class DevServer {
407
420
 
408
421
  return new Response(file, {
409
422
  headers: {
410
- "Content-Type": resolution.contentType || this.getContentType(resolution.filePath),
423
+ "Content-Type":
424
+ resolution.contentType || this.getContentType(resolution.filePath),
411
425
  },
412
426
  });
413
427
  }
@@ -461,7 +475,7 @@ export class DevServer {
461
475
  error: "Internal Server Error",
462
476
  statusCode: 500,
463
477
  },
464
- { status: 500 }
478
+ { status: 500 },
465
479
  );
466
480
  }
467
481
  }
@@ -544,7 +558,7 @@ export class DevServer {
544
558
  error: "Not Found",
545
559
  statusCode: 404,
546
560
  },
547
- { status: 404 }
561
+ { status: 404 },
548
562
  );
549
563
  } catch (error) {
550
564
  this.logger.error(`Request error: ${pathname}`, error);
@@ -552,9 +566,12 @@ export class DevServer {
552
566
  {
553
567
  error: "Internal Server Error",
554
568
  statusCode: 500,
555
- stack: process.env.NODE_ENV !== "production" && error instanceof Error ? error.stack : undefined,
569
+ stack:
570
+ process.env.NODE_ENV !== "production" && error instanceof Error
571
+ ? error.stack
572
+ : undefined,
556
573
  },
557
- { status: 500 }
574
+ { status: 500 },
558
575
  );
559
576
  } finally {
560
577
  this.state.activeConnections--;
@@ -607,7 +624,7 @@ export class DevServer {
607
624
  }
608
625
 
609
626
  this.logger.info(
610
- `Development server started at http://${this.config.hostname}:${this.config.port}`
627
+ `Development server started at http://${this.config.hostname}:${this.config.port}`,
611
628
  );
612
629
 
613
630
  this.emitEvent({
@@ -650,7 +667,9 @@ export class DevServer {
650
667
  this.state.running = false;
651
668
  this.state.startTime = null;
652
669
 
653
- this.logger.info(`Development server stopped${reason ? `: ${reason}` : ""}`);
670
+ this.logger.info(
671
+ `Development server stopped${reason ? `: ${reason}` : ""}`,
672
+ );
654
673
 
655
674
  this.emitEvent({
656
675
  type: "stop",
@@ -720,14 +739,19 @@ export class DevServer {
720
739
  * Check if console streaming is enabled
721
740
  */
722
741
  isConsoleStreamEnabled(): boolean {
723
- return this.consoleStreamManager !== null && this.consoleStreamManager.isEnabled();
742
+ return (
743
+ this.consoleStreamManager !== null &&
744
+ this.consoleStreamManager.isEnabled()
745
+ );
724
746
  }
725
747
 
726
748
  /**
727
749
  * Get Console Stream WebSocket URL
728
750
  */
729
751
  getConsoleStreamUrl(): string | null {
730
- return this.consoleStreamManager ? this.consoleStreamManager.getWebSocketUrl() : null;
752
+ return this.consoleStreamManager
753
+ ? this.consoleStreamManager.getWebSocketUrl()
754
+ : null;
731
755
  }
732
756
 
733
757
  // ============= SSR Methods =============
@@ -741,7 +765,9 @@ export class DevServer {
741
765
  framework: config.framework || this.state.framework,
742
766
  });
743
767
  this.ssrEnabled = true;
744
- this.logger.info("SSR enabled", { framework: config.framework || this.state.framework });
768
+ this.logger.info("SSR enabled", {
769
+ framework: config.framework || this.state.framework,
770
+ });
745
771
  }
746
772
 
747
773
  /**
@@ -826,21 +852,43 @@ export class DevServer {
826
852
  */
827
853
  private isStaticAsset(pathname: string): boolean {
828
854
  const staticExtensions = [
829
- ".js", ".mjs", ".css", ".json",
830
- ".png", ".jpg", ".jpeg", ".gif", ".svg", ".ico", ".webp", ".avif",
831
- ".woff", ".woff2", ".ttf", ".eot",
832
- ".mp4", ".webm", ".mp3", ".wav",
833
- ".pdf", ".zip", ".wasm",
855
+ ".js",
856
+ ".mjs",
857
+ ".css",
858
+ ".json",
859
+ ".png",
860
+ ".jpg",
861
+ ".jpeg",
862
+ ".gif",
863
+ ".svg",
864
+ ".ico",
865
+ ".webp",
866
+ ".avif",
867
+ ".woff",
868
+ ".woff2",
869
+ ".ttf",
870
+ ".eot",
871
+ ".mp4",
872
+ ".webm",
873
+ ".mp3",
874
+ ".wav",
875
+ ".pdf",
876
+ ".zip",
877
+ ".wasm",
834
878
  ];
835
- return staticExtensions.some(ext => pathname.endsWith(ext));
879
+ return staticExtensions.some((ext) => pathname.endsWith(ext));
836
880
  }
837
881
  }
838
882
 
839
883
  // ============= Factory Function =============
840
884
 
841
885
  /**
842
- * Create a development server
843
- */
844
- export function createDevServer(config: PartialDevServerConfig & { consoleStream?: PartialConsoleStreamConfig }): DevServer {
886
+ * Create a development server
887
+ */
888
+ export function createDevServer(
889
+ config: PartialDevServerConfig & {
890
+ consoleStream?: PartialConsoleStreamConfig;
891
+ },
892
+ ): DevServer {
845
893
  return new DevServer(config);
846
- }
894
+ }
@@ -8,17 +8,17 @@
8
8
  * - Integration with existing Router
9
9
  */
10
10
 
11
- import { createLogger, type Logger } from "../logger/index.js";
11
+ import { type Logger, createLogger } from "../logger/index.js";
12
12
  import { Router } from "../router/index.js";
13
13
  import type {
14
+ DynamicRoute,
15
+ FileRouteOptions,
14
16
  FileRouterConfig,
15
17
  PartialFileRouterConfig,
16
18
  RouteDefinition,
17
- RouteMatch,
18
- DynamicRoute,
19
19
  RouteHandler,
20
+ RouteMatch,
20
21
  RouteMiddleware,
21
- FileRouteOptions,
22
22
  RouteType,
23
23
  } from "./types.js";
24
24
  import type { SSRPage } from "./types.js";
@@ -103,7 +103,10 @@ export class FileRouter {
103
103
  /**
104
104
  * Process a single route file
105
105
  */
106
- private async processRouteFile(filePath: string, basePath: string): Promise<void> {
106
+ private async processRouteFile(
107
+ filePath: string,
108
+ basePath: string,
109
+ ): Promise<void> {
107
110
  const fullPath = `${basePath}/${filePath}`;
108
111
  const routePath = this.filePathToRoute(filePath);
109
112
 
@@ -167,7 +170,10 @@ export class FileRouter {
167
170
  * Determine route type from file path
168
171
  */
169
172
  private getRouteType(filePath: string): RouteType {
170
- if (filePath.startsWith(`${this.config.apiDir}/`) || filePath.startsWith("api/")) {
173
+ if (
174
+ filePath.startsWith(`${this.config.apiDir}/`) ||
175
+ filePath.startsWith("api/")
176
+ ) {
171
177
  return "api";
172
178
  }
173
179
  return "page";
@@ -176,9 +182,12 @@ export class FileRouter {
176
182
  /**
177
183
  * Parse route pattern and extract parameters
178
184
  */
179
- private parseRoutePattern(routePath: string): { pattern: string; params: string[] } {
185
+ private parseRoutePattern(routePath: string): {
186
+ pattern: string;
187
+ params: string[];
188
+ } {
180
189
  const params: string[] = [];
181
- let pattern = routePath;
190
+ const pattern = routePath;
182
191
 
183
192
  // Match [param] - single parameter
184
193
  const singleParamRegex = /\[([^\]]+)\]/g;
@@ -235,7 +244,10 @@ export class FileRouter {
235
244
 
236
245
  for (const route of sortedRoutes) {
237
246
  if (route.type === "page") {
238
- this.router.get(route.path, this.createPageHandler(route) as import("../types").RouteHandler);
247
+ this.router.get(
248
+ route.path,
249
+ this.createPageHandler(route) as import("../types").RouteHandler,
250
+ );
239
251
  } else if (route.type === "api") {
240
252
  this.registerApiRoute(route);
241
253
  }
@@ -298,7 +310,10 @@ export class FileRouter {
298
310
  if (!module) return;
299
311
 
300
312
  const handlers: Record<string, RouteHandler> = {};
301
- const methodMap: Record<string, (pattern: string, handler: import("../types").RouteHandler) => void> = {
313
+ const methodMap: Record<
314
+ string,
315
+ (pattern: string, handler: import("../types").RouteHandler) => void
316
+ > = {
302
317
  GET: this.router.get.bind(this.router),
303
318
  POST: this.router.post.bind(this.router),
304
319
  PUT: this.router.put.bind(this.router),
@@ -308,10 +323,21 @@ export class FileRouter {
308
323
  OPTIONS: this.router.options.bind(this.router),
309
324
  };
310
325
 
311
- for (const method of ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"] as const) {
326
+ for (const method of [
327
+ "GET",
328
+ "POST",
329
+ "PUT",
330
+ "PATCH",
331
+ "DELETE",
332
+ "HEAD",
333
+ "OPTIONS",
334
+ ] as const) {
312
335
  if (module[method]) {
313
336
  handlers[method] = module[method];
314
- methodMap[method](route.path, this.createApiHandler(route, method) as import("../types").RouteHandler);
337
+ methodMap[method](
338
+ route.path,
339
+ this.createApiHandler(route, method) as RouteHandler,
340
+ );
315
341
  }
316
342
  }
317
343
 
@@ -321,7 +347,10 @@ export class FileRouter {
321
347
  /**
322
348
  * Create API handler for a route and method
323
349
  */
324
- private createApiHandler(route: RouteDefinition, method: string): RouteHandler {
350
+ private createApiHandler(
351
+ route: RouteDefinition,
352
+ method: string,
353
+ ): RouteHandler {
325
354
  return async (request: Request) => {
326
355
  const module = await this.loadApiModule(route.filePath);
327
356
  if (!module || !module[method]) {
@@ -357,7 +386,9 @@ export class FileRouter {
357
386
  /**
358
387
  * Load API module dynamically
359
388
  */
360
- private async loadApiModule(filePath: string): Promise<Record<string, RouteHandler> | null> {
389
+ private async loadApiModule(
390
+ filePath: string,
391
+ ): Promise<Record<string, RouteHandler> | null> {
361
392
  try {
362
393
  const module = await import(filePath);
363
394
  return module;
@@ -370,7 +401,10 @@ export class FileRouter {
370
401
  /**
371
402
  * Extract params from URL using route definition
372
403
  */
373
- private extractParams(pathname: string, route: RouteDefinition): Record<string, string> {
404
+ private extractParams(
405
+ pathname: string,
406
+ route: RouteDefinition,
407
+ ): Record<string, string> {
374
408
  const params: Record<string, string> = {};
375
409
  const match = pathname.match(route.regex);
376
410
 
@@ -386,7 +420,10 @@ export class FileRouter {
386
420
  /**
387
421
  * Create context for request
388
422
  */
389
- private createContext(request: Request, params: Record<string, string> = {}): import("./types").SSRContext {
423
+ private createContext(
424
+ request: Request,
425
+ params: Record<string, string> = {},
426
+ ): import("./types").SSRContext {
390
427
  const url = new URL(request.url);
391
428
  return {
392
429
  request,
@@ -483,7 +520,10 @@ export class FileRouter {
483
520
  /**
484
521
  * Generate URL for a route
485
522
  */
486
- generateUrl(routeId: string, params: Record<string, string> = {}): string | null {
523
+ generateUrl(
524
+ routeId: string,
525
+ params: Record<string, string> = {},
526
+ ): string | null {
487
527
  for (const route of this.routes.values()) {
488
528
  if (route.id === routeId) {
489
529
  let url = route.path;
@@ -530,7 +570,9 @@ export class FileRouter {
530
570
  /**
531
571
  * Create a file router
532
572
  */
533
- export function createFileRouter(config: PartialFileRouterConfig = {}): FileRouter {
573
+ export function createFileRouter(
574
+ config: PartialFileRouterConfig = {},
575
+ ): FileRouter {
534
576
  return new FileRouter(config);
535
577
  }
536
578
 
@@ -608,4 +650,4 @@ export function compareRouteSpecificity(a: string, b: string): number {
608
650
 
609
651
  // Alphabetical comparison
610
652
  return a.localeCompare(b);
611
- }
653
+ }
@@ -5,19 +5,42 @@
5
5
  * Each framework module provides configuration for JSX runtime, plugins, and defines.
6
6
  */
7
7
 
8
- import type { FrontendFramework, FrameworkBuildConfig } from "../types.js";
8
+ import type { FrameworkBuildConfig, FrontendFramework } from "../types.js";
9
9
 
10
10
  // Import framework configurations for internal use
11
11
  import { getReactBuildConfig, reactFrameworkMeta } from "./react.js";
12
- import { getVueBuildConfig, vueFrameworkMeta } from "./vue.js";
13
- import { getSvelteBuildConfig, svelteFrameworkMeta } from "./svelte.js";
14
12
  import { getSolidBuildConfig, solidFrameworkMeta } from "./solid.js";
13
+ import { getSvelteBuildConfig, svelteFrameworkMeta } from "./svelte.js";
14
+ import { getVueBuildConfig, vueFrameworkMeta } from "./vue.js";
15
15
 
16
16
  // Re-export framework configurations
17
- export { getReactBuildConfig, isReactComponent, getReactRefreshPreamble, reactFrameworkMeta } from "./react.js";
18
- export { getVueBuildConfig, isVueComponent, isVueJsx, getVueBlockTypes, vueFrameworkMeta } from "./vue.js";
19
- export { getSvelteBuildConfig, isSvelteComponent, getSveltePreprocessConfig, getSvelteCompilerOptions, svelteFrameworkMeta } from "./svelte.js";
20
- export { getSolidBuildConfig, isSolidComponent, getSolidRefreshPreamble, getSolidTransformOptions, solidFrameworkMeta } from "./solid.js";
17
+ export {
18
+ getReactBuildConfig,
19
+ isReactComponent,
20
+ getReactRefreshPreamble,
21
+ reactFrameworkMeta,
22
+ } from "./react.js";
23
+ export {
24
+ getVueBuildConfig,
25
+ isVueComponent,
26
+ isVueJsx,
27
+ getVueBlockTypes,
28
+ vueFrameworkMeta,
29
+ } from "./vue.js";
30
+ export {
31
+ getSvelteBuildConfig,
32
+ isSvelteComponent,
33
+ getSveltePreprocessConfig,
34
+ getSvelteCompilerOptions,
35
+ svelteFrameworkMeta,
36
+ } from "./svelte.js";
37
+ export {
38
+ getSolidBuildConfig,
39
+ isSolidComponent,
40
+ getSolidRefreshPreamble,
41
+ getSolidTransformOptions,
42
+ solidFrameworkMeta,
43
+ } from "./solid.js";
21
44
 
22
45
  // Framework metadata types
23
46
  export interface FrameworkMeta {
@@ -33,7 +56,9 @@ export interface FrameworkMeta {
33
56
  /**
34
57
  * Get framework build configuration by framework name
35
58
  */
36
- export function getFrameworkConfig(framework: FrontendFramework): FrameworkBuildConfig {
59
+ export function getFrameworkConfig(
60
+ framework: FrontendFramework,
61
+ ): FrameworkBuildConfig {
37
62
  switch (framework) {
38
63
  case "react":
39
64
  return getReactBuildConfig();
@@ -70,7 +95,9 @@ export function getFrameworkMeta(framework: FrontendFramework): FrameworkMeta {
70
95
  /**
71
96
  * Detect framework from file extension
72
97
  */
73
- export function detectFrameworkFromExtension(filePath: string): FrontendFramework | null {
98
+ export function detectFrameworkFromExtension(
99
+ filePath: string,
100
+ ): FrontendFramework | null {
74
101
  if (filePath.endsWith(".vue")) {
75
102
  return "vue";
76
103
  }
@@ -103,4 +130,4 @@ export function getAllSupportedExtensions(): string[] {
103
130
  export function isSupportedExtension(filePath: string): boolean {
104
131
  const extensions = getAllSupportedExtensions();
105
132
  return extensions.some((ext) => filePath.endsWith(ext));
106
- }
133
+ }
@@ -5,7 +5,7 @@
5
5
  * including JSX runtime, automatic import handling, and React-specific defines.
6
6
  */
7
7
 
8
- import type { FrameworkBuildConfig, BuildPlugin } from "../types.js";
8
+ import type { BuildPlugin, FrameworkBuildConfig } from "../types.js";
9
9
 
10
10
  /**
11
11
  * React-specific build plugins
@@ -20,22 +20,24 @@ export function getReactBuildConfig(): FrameworkBuildConfig {
20
20
  // React 17+ automatic JSX runtime
21
21
  jsxRuntime: "automatic",
22
22
  jsxImportSource: "react",
23
-
23
+
24
24
  // React-specific file extensions
25
25
  extensions: [".jsx", ".tsx", ".js", ".ts"],
26
-
26
+
27
27
  // React-specific plugins
28
28
  plugins: reactPlugins,
29
-
29
+
30
30
  // React-specific global defines
31
31
  define: {
32
32
  // Enable React production mode in production builds
33
- "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development"),
33
+ "process.env.NODE_ENV": JSON.stringify(
34
+ process.env.NODE_ENV || "development",
35
+ ),
34
36
  },
35
-
37
+
36
38
  // External dependencies (should not be bundled in library mode)
37
39
  external: [],
38
-
40
+
39
41
  // Loader configurations for React files
40
42
  loaders: {
41
43
  ".jsx": "jsx",
@@ -82,4 +84,4 @@ export const reactFrameworkMeta: {
82
84
  needsRefreshRuntime: true,
83
85
  supportsHMR: true,
84
86
  supportsSSR: true,
85
- };
87
+ };
@@ -5,7 +5,7 @@
5
5
  * including Solid JSX transforms and Solid-specific optimizations.
6
6
  */
7
7
 
8
- import type { FrameworkBuildConfig, BuildPlugin } from "../types.js";
8
+ import type { BuildPlugin, FrameworkBuildConfig } from "../types.js";
9
9
 
10
10
  /**
11
11
  * Solid-specific build plugins
@@ -20,24 +20,26 @@ export function getSolidBuildConfig(): FrameworkBuildConfig {
20
20
  // Solid uses automatic JSX runtime with solid-js
21
21
  jsxRuntime: "automatic",
22
22
  jsxImportSource: "solid-js",
23
-
23
+
24
24
  // Solid-specific file extensions
25
25
  extensions: [".jsx", ".tsx", ".js", ".ts"],
26
-
26
+
27
27
  // Solid-specific plugins
28
28
  plugins: solidPlugins,
29
-
29
+
30
30
  // Solid-specific global defines
31
31
  define: {
32
32
  // Solid production mode
33
- "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development"),
33
+ "process.env.NODE_ENV": JSON.stringify(
34
+ process.env.NODE_ENV || "development",
35
+ ),
34
36
  // Solid-specific flags
35
- "DEV": JSON.stringify(process.env.NODE_ENV !== "production"),
37
+ DEV: JSON.stringify(process.env.NODE_ENV !== "production"),
36
38
  },
37
-
39
+
38
40
  // External dependencies
39
41
  external: [],
40
-
42
+
41
43
  // Loader configurations for Solid files
42
44
  loaders: {
43
45
  ".jsx": "jsx",
@@ -101,4 +103,4 @@ export const solidFrameworkMeta: {
101
103
  needsRefreshRuntime: true,
102
104
  supportsHMR: true,
103
105
  supportsSSR: true,
104
- };
106
+ };
@@ -5,7 +5,7 @@
5
5
  * including Svelte SFC support and Svelte-specific preprocessing.
6
6
  */
7
7
 
8
- import type { FrameworkBuildConfig, BuildPlugin } from "../types.js";
8
+ import type { BuildPlugin, FrameworkBuildConfig } from "../types.js";
9
9
 
10
10
  /**
11
11
  * Svelte-specific build plugins
@@ -20,22 +20,24 @@ export function getSvelteBuildConfig(): FrameworkBuildConfig {
20
20
  return {
21
21
  // Svelte doesn't use JSX runtime in the traditional sense
22
22
  jsxRuntime: "classic",
23
-
23
+
24
24
  // Svelte-specific file extensions
25
25
  extensions: [".svelte", ".js", ".ts"],
26
-
26
+
27
27
  // Svelte-specific plugins
28
28
  plugins: sveltePlugins,
29
-
29
+
30
30
  // Svelte-specific global defines
31
31
  define: {
32
32
  // Svelte production mode
33
- "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development"),
33
+ "process.env.NODE_ENV": JSON.stringify(
34
+ process.env.NODE_ENV || "development",
35
+ ),
34
36
  },
35
-
37
+
36
38
  // External dependencies
37
39
  external: [],
38
-
40
+
39
41
  // Loader configurations for Svelte files
40
42
  loaders: {
41
43
  ".svelte": "js", // Svelte SFCs are compiled to JS
@@ -76,7 +78,11 @@ export function getSveltePreprocessConfig() {
76
78
  export function getSvelteCompilerOptions() {
77
79
  return {
78
80
  // Enable CSS hashing for scoped styles
79
- cssHash: ({ hash, css, name }: { hash: (s: string) => string; css: string; name: string }) => {
81
+ cssHash: ({
82
+ hash,
83
+ css,
84
+ name,
85
+ }: { hash: (s: string) => string; css: string; name: string }) => {
80
86
  return `svelte-${hash(css)}-${name}`;
81
87
  },
82
88
  // Generate SSR-friendly code
@@ -107,4 +113,4 @@ export const svelteFrameworkMeta: {
107
113
  needsRefreshRuntime: false, // Svelte has built-in HMR
108
114
  supportsHMR: true,
109
115
  supportsSSR: true,
110
- };
116
+ };