@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.
- package/README.md +264 -17
- package/dist/cli/{index.js → bin.js} +413 -332
- package/dist/container/index.js +273 -0
- package/dist/context/index.js +219 -0
- package/dist/database/index.js +493 -0
- package/dist/frontend/index.js +7697 -0
- package/dist/graphql/index.js +2156 -0
- package/dist/health/index.js +364 -0
- package/dist/i18n/index.js +345 -0
- package/dist/index.js +9694 -5047
- package/dist/jobs/index.js +819 -0
- package/dist/lock/index.js +367 -0
- package/dist/logger/index.js +281 -0
- package/dist/metrics/index.js +289 -0
- package/dist/middleware/index.js +77 -0
- package/dist/migrations/index.js +571 -0
- package/dist/modules/index.js +3411 -0
- package/dist/notification/index.js +484 -0
- package/dist/observability/index.js +331 -0
- package/dist/openapi/index.js +795 -0
- package/dist/orm/index.js +1356 -0
- package/dist/router/index.js +886 -0
- package/dist/rpc/index.js +691 -0
- package/dist/schema/index.js +400 -0
- package/dist/telemetry/index.js +595 -0
- package/dist/template/index.js +640 -0
- package/dist/templates/index.js +640 -0
- package/dist/testing/index.js +1111 -0
- package/dist/types/index.js +60 -0
- package/llms.txt +231 -0
- package/package.json +125 -27
- package/src/cache/index.ts +2 -1
- package/src/cli/ARCHITECTURE.md +3 -3
- package/src/cli/bin.ts +2 -2
- package/src/cli/commands/build.ts +183 -165
- package/src/cli/commands/dev.ts +96 -89
- package/src/cli/commands/generate.ts +142 -111
- package/src/cli/commands/help.ts +20 -16
- package/src/cli/commands/index.ts +3 -6
- package/src/cli/commands/migration.ts +124 -105
- package/src/cli/commands/new.ts +294 -232
- package/src/cli/commands/start.ts +81 -79
- package/src/cli/core/args.ts +68 -50
- package/src/cli/core/console.ts +89 -95
- package/src/cli/core/index.ts +4 -4
- package/src/cli/core/prompt.ts +65 -62
- package/src/cli/core/spinner.ts +23 -20
- package/src/cli/index.ts +46 -38
- package/src/cli/templates/database/index.ts +37 -18
- package/src/cli/templates/database/mysql.ts +3 -3
- package/src/cli/templates/database/none.ts +2 -2
- package/src/cli/templates/database/postgresql.ts +3 -3
- package/src/cli/templates/database/sqlite.ts +3 -3
- package/src/cli/templates/deploy.ts +29 -26
- package/src/cli/templates/docker.ts +41 -30
- package/src/cli/templates/frontend/index.ts +33 -15
- package/src/cli/templates/frontend/none.ts +2 -2
- package/src/cli/templates/frontend/react.ts +18 -18
- package/src/cli/templates/frontend/solid.ts +15 -15
- package/src/cli/templates/frontend/svelte.ts +17 -17
- package/src/cli/templates/frontend/vue.ts +15 -15
- package/src/cli/templates/generators/index.ts +29 -29
- package/src/cli/templates/generators/types.ts +21 -21
- package/src/cli/templates/index.ts +6 -6
- package/src/cli/templates/project/api.ts +37 -36
- package/src/cli/templates/project/default.ts +25 -25
- package/src/cli/templates/project/fullstack.ts +28 -26
- package/src/cli/templates/project/index.ts +55 -16
- package/src/cli/templates/project/minimal.ts +17 -12
- package/src/cli/templates/project/types.ts +10 -5
- package/src/cli/templates/project/website.ts +15 -15
- package/src/cli/utils/fs.ts +55 -41
- package/src/cli/utils/index.ts +3 -3
- package/src/cli/utils/strings.ts +47 -33
- package/src/cli/utils/version.ts +14 -8
- package/src/config/env-validation.ts +100 -0
- package/src/config/env.ts +169 -41
- package/src/config/index.ts +28 -20
- package/src/config/loader.ts +25 -16
- package/src/config/merge.ts +21 -10
- package/src/config/types.ts +566 -25
- package/src/config/validation.ts +215 -7
- package/src/container/forward-ref.ts +22 -22
- package/src/container/index.ts +34 -12
- package/src/context/index.ts +11 -1
- package/src/database/index.ts +7 -190
- package/src/database/orm/builder.ts +457 -0
- package/src/database/orm/casts/index.ts +130 -0
- package/src/database/orm/casts/types.ts +25 -0
- package/src/database/orm/compiler.ts +304 -0
- package/src/database/orm/hooks/index.ts +114 -0
- package/src/database/orm/index.ts +61 -0
- package/src/database/orm/model-registry.ts +59 -0
- package/src/database/orm/model.ts +821 -0
- package/src/database/orm/relationships/base.ts +146 -0
- package/src/database/orm/relationships/belongs-to-many.ts +179 -0
- package/src/database/orm/relationships/belongs-to.ts +56 -0
- package/src/database/orm/relationships/has-many.ts +45 -0
- package/src/database/orm/relationships/has-one.ts +41 -0
- package/src/database/orm/relationships/index.ts +11 -0
- package/src/database/orm/scopes/index.ts +55 -0
- package/src/events/__tests__/event-system.test.ts +235 -0
- package/src/events/config.ts +238 -0
- package/src/events/example-usage.ts +185 -0
- package/src/events/index.ts +278 -0
- package/src/events/manager.ts +385 -0
- package/src/events/registry.ts +182 -0
- package/src/events/types.ts +124 -0
- package/src/frontend/api-routes.ts +65 -23
- package/src/frontend/bundler.ts +76 -34
- package/src/frontend/console-client.ts +2 -2
- package/src/frontend/console-stream.ts +94 -38
- package/src/frontend/dev-server.ts +94 -46
- package/src/frontend/file-router.ts +61 -19
- package/src/frontend/frameworks/index.ts +37 -10
- package/src/frontend/frameworks/react.ts +10 -8
- package/src/frontend/frameworks/solid.ts +11 -9
- package/src/frontend/frameworks/svelte.ts +15 -9
- package/src/frontend/frameworks/vue.ts +13 -11
- package/src/frontend/hmr-client.ts +12 -10
- package/src/frontend/hmr.ts +146 -103
- package/src/frontend/index.ts +14 -5
- package/src/frontend/islands.ts +41 -22
- package/src/frontend/isr.ts +59 -37
- package/src/frontend/layout.ts +36 -21
- package/src/frontend/ssr/react.ts +74 -27
- package/src/frontend/ssr/solid.ts +54 -20
- package/src/frontend/ssr/svelte.ts +48 -14
- package/src/frontend/ssr/vue.ts +50 -18
- package/src/frontend/ssr.ts +83 -39
- package/src/frontend/types.ts +91 -56
- package/src/graphql/built-in-engine.ts +598 -0
- package/src/graphql/context-builder.ts +110 -0
- package/src/graphql/decorators.ts +358 -0
- package/src/graphql/execution-pipeline.ts +227 -0
- package/src/graphql/graphql-module.ts +563 -0
- package/src/graphql/index.ts +101 -0
- package/src/graphql/metadata.ts +237 -0
- package/src/graphql/schema-builder.ts +319 -0
- package/src/graphql/subscription-handler.ts +283 -0
- package/src/graphql/types.ts +324 -0
- package/src/health/index.ts +21 -9
- package/src/i18n/engine.ts +305 -0
- package/src/i18n/index.ts +38 -0
- package/src/i18n/loader.ts +218 -0
- package/src/i18n/middleware.ts +164 -0
- package/src/i18n/negotiator.ts +162 -0
- package/src/i18n/types.ts +158 -0
- package/src/index.ts +182 -27
- package/src/jobs/drivers/memory.ts +315 -0
- package/src/jobs/drivers/redis.ts +459 -0
- package/src/jobs/index.ts +30 -0
- package/src/jobs/queue.ts +281 -0
- package/src/jobs/types.ts +295 -0
- package/src/jobs/worker.ts +380 -0
- package/src/logger/index.ts +1 -3
- package/src/logger/transports/index.ts +62 -22
- package/src/metrics/index.ts +25 -16
- package/src/migrations/index.ts +9 -0
- package/src/modules/filters.ts +13 -17
- package/src/modules/guards.ts +49 -26
- package/src/modules/index.ts +457 -299
- package/src/modules/interceptors.ts +58 -20
- package/src/modules/lazy.ts +11 -19
- package/src/modules/lifecycle.ts +15 -7
- package/src/modules/metadata.ts +15 -5
- package/src/modules/pipes.ts +94 -72
- package/src/notification/channels/base.ts +68 -0
- package/src/notification/channels/email.ts +105 -0
- package/src/notification/channels/push.ts +104 -0
- package/src/notification/channels/sms.ts +105 -0
- package/src/notification/channels/whatsapp.ts +104 -0
- package/src/notification/index.ts +48 -0
- package/src/notification/service.ts +354 -0
- package/src/notification/types.ts +344 -0
- package/src/observability/__tests__/observability.test.ts +483 -0
- package/src/observability/breadcrumbs.ts +114 -0
- package/src/observability/index.ts +136 -0
- package/src/observability/interceptor.ts +85 -0
- package/src/observability/service.ts +303 -0
- package/src/observability/trace.ts +37 -0
- package/src/observability/types.ts +196 -0
- package/src/openapi/__tests__/decorators.test.ts +335 -0
- package/src/openapi/__tests__/document-builder.test.ts +285 -0
- package/src/openapi/__tests__/route-scanner.test.ts +334 -0
- package/src/openapi/__tests__/schema-generator.test.ts +275 -0
- package/src/openapi/decorators.ts +328 -0
- package/src/openapi/document-builder.ts +274 -0
- package/src/openapi/index.ts +112 -0
- package/src/openapi/metadata.ts +112 -0
- package/src/openapi/route-scanner.ts +289 -0
- package/src/openapi/schema-generator.ts +256 -0
- package/src/openapi/swagger-module.ts +166 -0
- package/src/openapi/types.ts +398 -0
- package/src/orm/index.ts +10 -0
- package/src/rpc/index.ts +3 -1
- package/src/schema/index.ts +9 -0
- package/src/security/index.ts +15 -6
- package/src/ssg/index.ts +9 -8
- package/src/telemetry/index.ts +76 -22
- package/src/template/index.ts +7 -0
- package/src/templates/engine.ts +224 -0
- package/src/templates/index.ts +9 -0
- package/src/templates/loader.ts +331 -0
- package/src/templates/renderers/markdown.ts +212 -0
- package/src/templates/renderers/simple.ts +269 -0
- package/src/templates/types.ts +154 -0
- package/src/testing/index.ts +100 -27
- package/src/types/optional-deps.d.ts +347 -187
- package/src/validation/index.ts +92 -2
- package/src/validation/schemas.ts +536 -0
- package/tests/integration/cli.test.ts +19 -19
- package/tests/integration/fullstack.test.ts +4 -4
- package/tests/unit/cli.test.ts +1 -1
- package/tests/unit/database.test.ts +2 -72
- package/tests/unit/env-validation.test.ts +166 -0
- package/tests/unit/events.test.ts +910 -0
- package/tests/unit/graphql.test.ts +991 -0
- package/tests/unit/i18n.test.ts +455 -0
- package/tests/unit/jobs.test.ts +493 -0
- package/tests/unit/notification.test.ts +988 -0
- package/tests/unit/observability.test.ts +453 -0
- package/tests/unit/orm/builder.test.ts +323 -0
- package/tests/unit/orm/casts.test.ts +179 -0
- package/tests/unit/orm/compiler.test.ts +220 -0
- package/tests/unit/orm/eager-loading.test.ts +285 -0
- package/tests/unit/orm/hooks.test.ts +191 -0
- package/tests/unit/orm/model.test.ts +373 -0
- package/tests/unit/orm/relationships.test.ts +303 -0
- package/tests/unit/orm/scopes.test.ts +74 -0
- package/tests/unit/templates-simple.test.ts +53 -0
- package/tests/unit/templates.test.ts +454 -0
- package/tests/unit/validation.test.ts +18 -24
- package/tsconfig.json +11 -3
package/src/frontend/bundler.ts
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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[] = [
|
|
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:
|
|
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:
|
|
258
|
-
|
|
259
|
-
|
|
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:
|
|
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: {
|
|
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: {
|
|
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(
|
|
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(
|
|
565
|
-
|
|
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(
|
|
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 = [
|
|
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 {
|
|
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
|
-
|
|
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(
|
|
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 ?? [
|
|
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
|
|
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(
|
|
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
|
|
361
|
+
private formatValue(value: unknown, depth = 0): string {
|
|
346
362
|
if (depth > 3) {
|
|
347
|
-
return this.config.colorize
|
|
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
|
|
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
|
|
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
|
|
384
|
+
return this.config.colorize
|
|
385
|
+
? `${ANSI_COLORS.green}"${truncated}"${ANSI_COLORS.reset}`
|
|
386
|
+
: `"${truncated}"`;
|
|
363
387
|
}
|
|
364
|
-
return this.config.colorize
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
+
}
|