@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
@@ -13,26 +13,26 @@
13
13
  * - Build manifest for SSR integration
14
14
  */
15
15
 
16
- import { createLogger, type Logger } from "../logger/index.js";
17
16
  import { watch } from "fs";
18
17
  import type { FSWatcher } from "fs";
18
+ import { type Logger, createLogger } from "../logger/index.js";
19
+ import { getFrameworkConfig, getFrameworkMeta } from "./frameworks/index.js";
19
20
  import type {
20
- BundlerConfig,
21
- PartialBundlerConfig,
22
- BuildResult,
23
- BuildOutput,
24
21
  BuildError,
25
- BuildWarning,
26
22
  BuildManifest,
27
- BundleAnalysis,
23
+ BuildOutput,
24
+ BuildResult,
25
+ BuildWarning,
28
26
  BuildWatchCallback,
27
+ BundleAnalysis,
28
+ BundlerConfig,
29
29
  BundlerState,
30
- FrontendFramework,
31
30
  FrameworkBuildConfig,
32
31
  FrameworkDetectionResult,
32
+ FrontendFramework,
33
33
  PackageDependencies,
34
+ PartialBundlerConfig,
34
35
  } from "./types.js";
35
- import { getFrameworkConfig, getFrameworkMeta } from "./frameworks/index.js";
36
36
 
37
37
  // ============= Constants =============
38
38
 
@@ -64,7 +64,9 @@ function detectFramework(rootDir: string): FrameworkDetectionResult {
64
64
  }
65
65
 
66
66
  // Read package.json synchronously
67
- const packageJson = JSON.parse(require("fs").readFileSync(packageJsonPath, "utf-8"));
67
+ const packageJson = JSON.parse(
68
+ require("fs").readFileSync(packageJsonPath, "utf-8"),
69
+ );
68
70
  const dependencies: PackageDependencies = {
69
71
  ...packageJson.dependencies,
70
72
  ...packageJson.devDependencies,
@@ -72,7 +74,12 @@ function detectFramework(rootDir: string): FrameworkDetectionResult {
72
74
 
73
75
  // Check for each framework in order of specificity
74
76
  // Solid and Svelte are more specific than React/Vue
75
- const frameworkOrder: FrontendFramework[] = ["solid", "svelte", "vue", "react"];
77
+ const frameworkOrder: FrontendFramework[] = [
78
+ "solid",
79
+ "svelte",
80
+ "vue",
81
+ "react",
82
+ ];
76
83
 
77
84
  for (const framework of frameworkOrder) {
78
85
  const indicators = FRAMEWORK_INDICATORS[framework];
@@ -243,20 +250,25 @@ export class Bundler {
243
250
  // Build using Bun.build()
244
251
  const buildResult = await Bun.build({
245
252
  entrypoints: entryPoints.map((e) =>
246
- e.startsWith("/") ? e : `${this.config.rootDir}/${e}`
253
+ e.startsWith("/") ? e : `${this.config.rootDir}/${e}`,
247
254
  ),
248
255
  outdir: this.config.outDir,
249
256
  minify: this.config.minify,
250
257
  splitting: this.config.splitting,
251
- sourcemap: this.config.sourcemap === "none" ? "external" : this.config.sourcemap,
258
+ sourcemap:
259
+ this.config.sourcemap === "none" ? "external" : this.config.sourcemap,
252
260
  define,
253
261
  external: [...this.config.external, ...frameworkConfig.external],
254
262
  target: this.config.target,
255
263
  format: this.config.format,
256
264
  // JSX configuration
257
- jsx: frameworkConfig.jsxRuntime === "automatic"
258
- ? { runtime: "automatic", importSource: frameworkConfig.jsxImportSource }
259
- : { runtime: "classic" },
265
+ jsx:
266
+ frameworkConfig.jsxRuntime === "automatic"
267
+ ? {
268
+ runtime: "automatic",
269
+ importSource: frameworkConfig.jsxImportSource,
270
+ }
271
+ : { runtime: "classic" },
260
272
  // Public path for assets
261
273
  publicPath: this.config.publicPath,
262
274
  // Generate manifest
@@ -321,7 +333,8 @@ export class Bundler {
321
333
  outputs: [],
322
334
  errors: [
323
335
  {
324
- message: error instanceof Error ? error.message : "Unknown build error",
336
+ message:
337
+ error instanceof Error ? error.message : "Unknown build error",
325
338
  stack: error instanceof Error ? error.stack : undefined,
326
339
  },
327
340
  ],
@@ -359,22 +372,22 @@ export class Bundler {
359
372
  : [this.config.entryPoints];
360
373
 
361
374
  const srcDir = `${this.config.rootDir}/src`;
362
-
375
+
363
376
  this.watcher = watch(
364
377
  srcDir,
365
378
  { recursive: true },
366
379
  async (event: "rename" | "change", filename: string | null) => {
367
380
  if (!filename) return;
368
-
381
+
369
382
  const filePath = `${srcDir}/${filename}`;
370
383
  this.logger.debug(`File changed: ${filePath}`);
371
-
384
+
372
385
  // Check if changed file is relevant
373
386
  if (this.isRelevantFile(filePath, entryPoints)) {
374
387
  const result = await this.build();
375
388
  callback(result);
376
389
  }
377
- }
390
+ },
378
391
  );
379
392
 
380
393
  this.logger.info("Watching for file changes...");
@@ -485,7 +498,11 @@ export class Bundler {
485
498
  /**
486
499
  * Parse build error from Bun build log
487
500
  */
488
- private parseBuildError(log: { message: string; position?: { line: number; column: number } | null; file?: string }): BuildError {
501
+ private parseBuildError(log: {
502
+ message: string;
503
+ position?: { line: number; column: number } | null;
504
+ file?: string;
505
+ }): BuildError {
489
506
  return {
490
507
  message: log.message,
491
508
  file: log.file,
@@ -497,7 +514,11 @@ export class Bundler {
497
514
  /**
498
515
  * Parse build warning from Bun build log
499
516
  */
500
- private parseBuildWarning(log: { message: string; position?: { line: number; column: number } | null; file?: string }): BuildWarning {
517
+ private parseBuildWarning(log: {
518
+ message: string;
519
+ position?: { line: number; column: number } | null;
520
+ file?: string;
521
+ }): BuildWarning {
501
522
  return {
502
523
  message: log.message,
503
524
  file: log.file,
@@ -509,7 +530,9 @@ export class Bundler {
509
530
  /**
510
531
  * Process build outputs from Bun.build result
511
532
  */
512
- private processBuildOutputs(outputs: Awaited<ReturnType<typeof Bun.build>>["outputs"]): BuildOutput[] {
533
+ private processBuildOutputs(
534
+ outputs: Awaited<ReturnType<typeof Bun.build>>["outputs"],
535
+ ): BuildOutput[] {
513
536
  return outputs.map((output) => {
514
537
  const path = output.path.replace(`${this.config.outDir}/`, "");
515
538
  const type = this.getOutputType(output.path);
@@ -553,7 +576,7 @@ export class Bundler {
553
576
  private async generateManifest(
554
577
  buildResult: Awaited<ReturnType<typeof Bun.build>>,
555
578
  outputs: BuildOutput[],
556
- duration: number
579
+ duration: number,
557
580
  ): Promise<BuildManifest> {
558
581
  const entryPoints: Record<string, string[]> = {};
559
582
  const files: BuildManifest["files"] = {};
@@ -561,17 +584,28 @@ export class Bundler {
561
584
 
562
585
  // Process entry points
563
586
  const entryNames = Array.isArray(this.config.entryPoints)
564
- ? this.config.entryPoints.map((e) => e.split("/").pop()?.replace(/\.[^.]+$/, "") || "main")
565
- : [this.config.entryPoints.split("/").pop()?.replace(/\.[^.]+$/, "") || "main"];
587
+ ? this.config.entryPoints.map(
588
+ (e) =>
589
+ e
590
+ .split("/")
591
+ .pop()
592
+ ?.replace(/\.[^.]+$/, "") || "main",
593
+ )
594
+ : [
595
+ this.config.entryPoints
596
+ .split("/")
597
+ .pop()
598
+ ?.replace(/\.[^.]+$/, "") || "main",
599
+ ];
566
600
 
567
601
  for (const name of entryNames) {
568
602
  entryPoints[name] = outputs
569
- .filter((o) => o.type === "js" && (o.entryPoint === name || !o.entryPoint))
603
+ .filter(
604
+ (o) => o.type === "js" && (o.entryPoint === name || !o.entryPoint),
605
+ )
570
606
  .map((o) => o.path);
571
607
 
572
- css[name] = outputs
573
- .filter((o) => o.type === "css")
574
- .map((o) => o.path);
608
+ css[name] = outputs.filter((o) => o.type === "css").map((o) => o.path);
575
609
  }
576
610
 
577
611
  // Process all files
@@ -612,7 +646,15 @@ export class Bundler {
612
646
  }
613
647
 
614
648
  // Check file extension
615
- const supportedExtensions = [".ts", ".tsx", ".js", ".jsx", ".css", ".vue", ".svelte"];
649
+ const supportedExtensions = [
650
+ ".ts",
651
+ ".tsx",
652
+ ".js",
653
+ ".jsx",
654
+ ".css",
655
+ ".vue",
656
+ ".svelte",
657
+ ];
616
658
  return supportedExtensions.some((ext) => filePath.endsWith(ext));
617
659
  }
618
660
  }
@@ -633,11 +675,11 @@ export function createBundler(config: PartialBundlerConfig): Bundler {
633
675
  */
634
676
  export async function build(
635
677
  entryPoints: string | string[],
636
- options?: Partial<Omit<PartialBundlerConfig, "entryPoints">>
678
+ options?: Partial<Omit<PartialBundlerConfig, "entryPoints">>,
637
679
  ): Promise<BuildResult> {
638
680
  const bundler = createBundler({
639
681
  entryPoints,
640
682
  ...options,
641
683
  });
642
684
  return bundler.build();
643
- }
685
+ }
@@ -414,6 +414,6 @@ export const CONSOLE_CLIENT_SCRIPT = `
414
414
  export function getConsoleClientScript(port: number): string {
415
415
  return CONSOLE_CLIENT_SCRIPT.replace(
416
416
  /typeof CONSOLE_PORT !== 'undefined' \? CONSOLE_PORT : \d+/,
417
- `typeof CONSOLE_PORT !== 'undefined' ? CONSOLE_PORT : ${port}`
417
+ `typeof CONSOLE_PORT !== 'undefined' ? CONSOLE_PORT : ${port}`,
418
418
  );
419
- }
419
+ }
@@ -7,17 +7,17 @@
7
7
  * @module frontend/console-stream
8
8
  */
9
9
 
10
- import { createLogger, type Logger } from "../logger/index.js";
10
+ import { type Logger, createLogger } from "../logger/index.js";
11
+ import { CONSOLE_CLIENT_SCRIPT } from "./console-client.js";
11
12
  import type {
12
- ConsoleMessage,
13
- ConsoleStreamConfig,
14
- ConsoleStreamClient,
15
13
  ConsoleClientMessage,
16
- ConsoleServerMessage,
14
+ ConsoleMessage,
17
15
  ConsoleMessageType,
16
+ ConsoleServerMessage,
17
+ ConsoleStreamClient,
18
+ ConsoleStreamConfig,
18
19
  PartialConsoleStreamConfig,
19
20
  } from "./types.js";
20
- import { CONSOLE_CLIENT_SCRIPT } from "./console-client.js";
21
21
 
22
22
  // ============= Constants =============
23
23
 
@@ -84,13 +84,23 @@ export class ConsoleStreamManager {
84
84
  /**
85
85
  * Normalize partial config to full config with defaults
86
86
  */
87
- private normalizeConfig(config?: PartialConsoleStreamConfig): ConsoleStreamConfig {
87
+ private normalizeConfig(
88
+ config?: PartialConsoleStreamConfig,
89
+ ): ConsoleStreamConfig {
88
90
  return {
89
91
  enabled: config?.enabled ?? true,
90
92
  showTimestamps: config?.showTimestamps ?? true,
91
93
  showFile: config?.showFile ?? true,
92
94
  colorize: config?.colorize ?? true,
93
- filter: config?.filter ?? ['log', 'info', 'warn', 'error', 'debug', 'trace', 'table'],
95
+ filter: config?.filter ?? [
96
+ "log",
97
+ "info",
98
+ "warn",
99
+ "error",
100
+ "debug",
101
+ "trace",
102
+ "table",
103
+ ],
94
104
  };
95
105
  }
96
106
 
@@ -287,7 +297,9 @@ export class ConsoleStreamManager {
287
297
  }
288
298
 
289
299
  // Message type with color
290
- const typeColor = this.config.colorize ? CONSOLE_TYPE_COLORS[message.consoleType] : "";
300
+ const typeColor = this.config.colorize
301
+ ? CONSOLE_TYPE_COLORS[message.consoleType]
302
+ : "";
291
303
  const typeReset = this.config.colorize ? ANSI_COLORS.reset : "";
292
304
  const typeLabel = message.consoleType.toUpperCase().padEnd(5);
293
305
  parts.push(`${typeColor}${typeLabel}${typeReset}`);
@@ -298,7 +310,11 @@ export class ConsoleStreamManager {
298
310
 
299
311
  // File:line information
300
312
  if (this.config.showFile && message.file) {
301
- const fileLink = this.formatFileLink(message.file, message.line, message.column);
313
+ const fileLink = this.formatFileLink(
314
+ message.file,
315
+ message.line,
316
+ message.column,
317
+ );
302
318
  parts.push(`\n at ${fileLink}`);
303
319
  }
304
320
 
@@ -333,48 +349,64 @@ export class ConsoleStreamManager {
333
349
 
334
350
  if (type === "trace") {
335
351
  // Trace already includes the stack in the args
336
- return args.map(arg => this.formatValue(arg)).join(" ");
352
+ return args.map((arg) => this.formatValue(arg)).join(" ");
337
353
  }
338
354
 
339
- return args.map(arg => this.formatValue(arg)).join(" ");
355
+ return args.map((arg) => this.formatValue(arg)).join(" ");
340
356
  }
341
357
 
342
358
  /**
343
359
  * Format a single value for display
344
360
  */
345
- private formatValue(value: unknown, depth: number = 0): string {
361
+ private formatValue(value: unknown, depth = 0): string {
346
362
  if (depth > 3) {
347
- return this.config.colorize ? `${ANSI_COLORS.dim}[...]${ANSI_COLORS.reset}` : "[...]";
363
+ return this.config.colorize
364
+ ? `${ANSI_COLORS.dim}[...]${ANSI_COLORS.reset}`
365
+ : "[...]";
348
366
  }
349
367
 
350
368
  if (value === null) {
351
- return this.config.colorize ? `${ANSI_COLORS.gray}null${ANSI_COLORS.reset}` : "null";
369
+ return this.config.colorize
370
+ ? `${ANSI_COLORS.gray}null${ANSI_COLORS.reset}`
371
+ : "null";
352
372
  }
353
373
 
354
374
  if (value === undefined) {
355
- return this.config.colorize ? `${ANSI_COLORS.gray}undefined${ANSI_COLORS.reset}` : "undefined";
375
+ return this.config.colorize
376
+ ? `${ANSI_COLORS.gray}undefined${ANSI_COLORS.reset}`
377
+ : "undefined";
356
378
  }
357
379
 
358
380
  if (typeof value === "string") {
359
381
  // Check if it's a long string
360
382
  if (value.length > 200) {
361
383
  const truncated = value.substring(0, 200) + "...";
362
- return this.config.colorize ? `${ANSI_COLORS.green}"${truncated}"${ANSI_COLORS.reset}` : `"${truncated}"`;
384
+ return this.config.colorize
385
+ ? `${ANSI_COLORS.green}"${truncated}"${ANSI_COLORS.reset}`
386
+ : `"${truncated}"`;
363
387
  }
364
- return this.config.colorize ? `${ANSI_COLORS.green}"${value}"${ANSI_COLORS.reset}` : `"${value}"`;
388
+ return this.config.colorize
389
+ ? `${ANSI_COLORS.green}"${value}"${ANSI_COLORS.reset}`
390
+ : `"${value}"`;
365
391
  }
366
392
 
367
393
  if (typeof value === "number") {
368
- return this.config.colorize ? `${ANSI_COLORS.yellow}${value}${ANSI_COLORS.reset}` : `${value}`;
394
+ return this.config.colorize
395
+ ? `${ANSI_COLORS.yellow}${value}${ANSI_COLORS.reset}`
396
+ : `${value}`;
369
397
  }
370
398
 
371
399
  if (typeof value === "boolean") {
372
- return this.config.colorize ? `${ANSI_COLORS.magenta}${value}${ANSI_COLORS.reset}` : `${value}`;
400
+ return this.config.colorize
401
+ ? `${ANSI_COLORS.magenta}${value}${ANSI_COLORS.reset}`
402
+ : `${value}`;
373
403
  }
374
404
 
375
405
  if (value instanceof Error) {
376
406
  const errorStr = `${value.name}: ${value.message}`;
377
- return this.config.colorize ? `${ANSI_COLORS.red}${errorStr}${ANSI_COLORS.reset}` : errorStr;
407
+ return this.config.colorize
408
+ ? `${ANSI_COLORS.red}${errorStr}${ANSI_COLORS.reset}`
409
+ : errorStr;
378
410
  }
379
411
 
380
412
  if (Array.isArray(value)) {
@@ -382,10 +414,12 @@ export class ConsoleStreamManager {
382
414
  return "[]";
383
415
  }
384
416
  if (value.length > 10) {
385
- const items = value.slice(0, 10).map(v => this.formatValue(v, depth + 1));
417
+ const items = value
418
+ .slice(0, 10)
419
+ .map((v) => this.formatValue(v, depth + 1));
386
420
  return `[${items.join(", ")}, ... ${value.length - 10} more items]`;
387
421
  }
388
- const items = value.map(v => this.formatValue(v, depth + 1));
422
+ const items = value.map((v) => this.formatValue(v, depth + 1));
389
423
  return `[${items.join(", ")}]`;
390
424
  }
391
425
 
@@ -396,10 +430,14 @@ export class ConsoleStreamManager {
396
430
  return "{}";
397
431
  }
398
432
  if (entries.length > 5) {
399
- const shown = entries.slice(0, 5).map(([k, v]) => `${k}: ${this.formatValue(v, depth + 1)}`);
433
+ const shown = entries
434
+ .slice(0, 5)
435
+ .map(([k, v]) => `${k}: ${this.formatValue(v, depth + 1)}`);
400
436
  return `{${shown.join(", ")}, ... ${entries.length - 5} more keys}`;
401
437
  }
402
- const formatted = entries.map(([k, v]) => `${k}: ${this.formatValue(v, depth + 1)}`);
438
+ const formatted = entries.map(
439
+ ([k, v]) => `${k}: ${this.formatValue(v, depth + 1)}`,
440
+ );
403
441
  return `{${formatted.join(", ")}}`;
404
442
  } catch {
405
443
  return "[Object]";
@@ -423,27 +461,45 @@ export class ConsoleStreamManager {
423
461
 
424
462
  // Simple table formatting
425
463
  const entries = Array.isArray(data) ? data : Object.entries(data as object);
426
-
464
+
427
465
  if (entries.length === 0) {
428
- return this.config.colorize ? `${ANSI_COLORS.dim}(empty table)${ANSI_COLORS.reset}` : "(empty table)";
466
+ return this.config.colorize
467
+ ? `${ANSI_COLORS.dim}(empty table)${ANSI_COLORS.reset}`
468
+ : "(empty table)";
429
469
  }
430
470
 
431
471
  const lines: string[] = [];
432
- lines.push(this.config.colorize ? `${ANSI_COLORS.blue}┌─────────${ANSI_COLORS.reset}` : "┌─────────");
472
+ lines.push(
473
+ this.config.colorize
474
+ ? `${ANSI_COLORS.blue}┌─────────${ANSI_COLORS.reset}`
475
+ : "┌─────────",
476
+ );
433
477
 
434
478
  const maxRows = 10;
435
479
  const shown = entries.slice(0, maxRows);
436
-
480
+
437
481
  for (const entry of shown) {
438
482
  const row = this.formatValue(entry, 1);
439
- lines.push(this.config.colorize ? `${ANSI_COLORS.blue}│${ANSI_COLORS.reset} ${row}` : `│ ${row}`);
483
+ lines.push(
484
+ this.config.colorize
485
+ ? `${ANSI_COLORS.blue}│${ANSI_COLORS.reset} ${row}`
486
+ : `│ ${row}`,
487
+ );
440
488
  }
441
489
 
442
490
  if (entries.length > maxRows) {
443
- lines.push(this.config.colorize ? `${ANSI_COLORS.blue}│${ANSI_COLORS.reset} ... ${entries.length - maxRows} more rows` : `│ ... ${entries.length - maxRows} more rows`);
491
+ lines.push(
492
+ this.config.colorize
493
+ ? `${ANSI_COLORS.blue}│${ANSI_COLORS.reset} ... ${entries.length - maxRows} more rows`
494
+ : `│ ... ${entries.length - maxRows} more rows`,
495
+ );
444
496
  }
445
497
 
446
- lines.push(this.config.colorize ? `${ANSI_COLORS.blue}└─────────${ANSI_COLORS.reset}` : "└─────────");
498
+ lines.push(
499
+ this.config.colorize
500
+ ? `${ANSI_COLORS.blue}└─────────${ANSI_COLORS.reset}`
501
+ : "└─────────",
502
+ );
447
503
 
448
504
  return "\n" + lines.join("\n");
449
505
  }
@@ -454,7 +510,7 @@ export class ConsoleStreamManager {
454
510
  private formatFileLink(file: string, line?: number, column?: number): string {
455
511
  const location = line ? `:${line}${column ? `:${column}` : ""}` : "";
456
512
  const link = `${file}${location}`;
457
-
513
+
458
514
  if (this.config.colorize) {
459
515
  return `${ANSI_COLORS.cyan}${link}${ANSI_COLORS.reset}`;
460
516
  }
@@ -469,11 +525,11 @@ export class ConsoleStreamManager {
469
525
  const formatted = lines.map((line, index) => {
470
526
  if (index === 0) {
471
527
  // First line is usually the error message
472
- return this.config.colorize
528
+ return this.config.colorize
473
529
  ? ` ${ANSI_COLORS.red}${line}${ANSI_COLORS.reset}`
474
530
  : ` ${line}`;
475
531
  }
476
-
532
+
477
533
  // Try to make file paths clickable
478
534
  const match = line.match(/at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/);
479
535
  if (match) {
@@ -484,7 +540,7 @@ export class ConsoleStreamManager {
484
540
  return ` at ${fn} (${file}:${lineNum}:${col})`;
485
541
  }
486
542
 
487
- return this.config.colorize
543
+ return this.config.colorize
488
544
  ? ` ${ANSI_COLORS.gray}${line}${ANSI_COLORS.reset}`
489
545
  : ` ${line}`;
490
546
  });
@@ -551,7 +607,7 @@ export class ConsoleStreamManager {
551
607
  */
552
608
  export function createConsoleStreamManager(
553
609
  devServerPort: number,
554
- config?: PartialConsoleStreamConfig
610
+ config?: PartialConsoleStreamConfig,
555
611
  ): ConsoleStreamManager {
556
612
  return new ConsoleStreamManager(devServerPort, config);
557
613
  }
@@ -584,4 +640,4 @@ export function injectConsoleScript(html: string, port: number): string {
584
640
 
585
641
  // If no head or body, prepend
586
642
  return script + html;
587
- }
643
+ }