@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
|
@@ -10,33 +10,37 @@
|
|
|
10
10
|
* - Graceful shutdown handling
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
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
|
-
|
|
28
|
+
DevServerEvent,
|
|
29
|
+
DevServerEventListener,
|
|
30
|
+
DevServerMiddleware,
|
|
19
31
|
DevServerState,
|
|
20
|
-
FrontendFramework,
|
|
21
|
-
FrameworkDetectionResult,
|
|
22
|
-
PackageDependencies,
|
|
23
32
|
FileResolution,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
DevServerEvent,
|
|
27
|
-
TransformResult,
|
|
28
|
-
TransformOptions,
|
|
33
|
+
FrameworkDetectionResult,
|
|
34
|
+
FrontendFramework,
|
|
29
35
|
HMRConfig,
|
|
30
|
-
|
|
36
|
+
PackageDependencies,
|
|
31
37
|
PartialConsoleStreamConfig,
|
|
32
|
-
|
|
38
|
+
PartialDevServerConfig,
|
|
33
39
|
PartialSSRConfig,
|
|
34
|
-
|
|
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(
|
|
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[] = [
|
|
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(
|
|
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":
|
|
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:
|
|
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(
|
|
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
|
|
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
|
|
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", {
|
|
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",
|
|
830
|
-
".
|
|
831
|
-
".
|
|
832
|
-
".
|
|
833
|
-
".
|
|
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
|
-
|
|
843
|
-
|
|
844
|
-
export function createDevServer(
|
|
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 {
|
|
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(
|
|
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 (
|
|
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): {
|
|
185
|
+
private parseRoutePattern(routePath: string): {
|
|
186
|
+
pattern: string;
|
|
187
|
+
params: string[];
|
|
188
|
+
} {
|
|
180
189
|
const params: string[] = [];
|
|
181
|
-
|
|
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(
|
|
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<
|
|
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 [
|
|
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](
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
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 {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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(
|
|
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(
|
|
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 {
|
|
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(
|
|
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 {
|
|
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(
|
|
33
|
+
"process.env.NODE_ENV": JSON.stringify(
|
|
34
|
+
process.env.NODE_ENV || "development",
|
|
35
|
+
),
|
|
34
36
|
// Solid-specific flags
|
|
35
|
-
|
|
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 {
|
|
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(
|
|
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: ({
|
|
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
|
+
};
|