@buenojs/bueno 0.8.4 → 0.8.5
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 +136 -16
- package/dist/cli/{index.js → bin.js} +412 -331
- package/dist/container/index.js +250 -0
- package/dist/context/index.js +219 -0
- package/dist/database/index.js +493 -0
- package/dist/frontend/index.js +7697 -0
- package/dist/health/index.js +364 -0
- package/dist/i18n/index.js +345 -0
- package/dist/index.js +11043 -6482
- 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 +3346 -0
- package/dist/notification/index.js +484 -0
- package/dist/observability/index.js +331 -0
- package/dist/openapi/index.js +776 -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/package.json +121 -27
- package/src/cache/index.ts +2 -1
- 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 +14 -14
- 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 +545 -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/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 +179 -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 +409 -298
- 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/fullstack.test.ts +4 -4
- 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/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/config/index.ts
CHANGED
|
@@ -19,6 +19,9 @@ export type {
|
|
|
19
19
|
MetricsConfig,
|
|
20
20
|
TelemetryConfig,
|
|
21
21
|
FrontendConfig,
|
|
22
|
+
JobsConfig,
|
|
23
|
+
NotificationConfig,
|
|
24
|
+
I18nConfig,
|
|
22
25
|
DeepPartial,
|
|
23
26
|
UserConfig,
|
|
24
27
|
UserConfigFn,
|
|
@@ -70,21 +73,21 @@ export {
|
|
|
70
73
|
} from "./validation";
|
|
71
74
|
|
|
72
75
|
import type { StandardSchema } from "../types";
|
|
76
|
+
import { getEnvConfig, loadEnv } from "./env";
|
|
77
|
+
import { clearConfigCache, findConfigFile, loadConfig } from "./loader";
|
|
78
|
+
import { deepMerge, mergeConfigs } from "./merge";
|
|
73
79
|
import type {
|
|
74
80
|
BuenoConfig,
|
|
75
81
|
DeepPartial,
|
|
82
|
+
InferConfig,
|
|
76
83
|
UserConfig,
|
|
77
84
|
UserConfigFn,
|
|
78
|
-
InferConfig,
|
|
79
85
|
} from "./types";
|
|
80
|
-
import { deepMerge, mergeConfigs } from "./merge";
|
|
81
|
-
import { loadEnv, getEnvConfig } from "./env";
|
|
82
|
-
import { loadConfig, findConfigFile, clearConfigCache } from "./loader";
|
|
83
86
|
import {
|
|
87
|
+
type ConfigValidationResult,
|
|
88
|
+
assertValidConfig,
|
|
84
89
|
validateConfig,
|
|
85
90
|
validateConfigSync,
|
|
86
|
-
assertValidConfig,
|
|
87
|
-
type ConfigValidationResult,
|
|
88
91
|
} from "./validation";
|
|
89
92
|
|
|
90
93
|
/**
|
|
@@ -178,9 +181,9 @@ export class ConfigManager<T extends BuenoConfig = BuenoConfig> {
|
|
|
178
181
|
|
|
179
182
|
constructor(options: ConfigManagerOptions<T> = {}) {
|
|
180
183
|
this.options = options;
|
|
181
|
-
this.config = (
|
|
182
|
-
? { ...DEFAULT_CONFIG }
|
|
183
|
-
|
|
184
|
+
this.config = (
|
|
185
|
+
options.useDefaults !== false ? { ...DEFAULT_CONFIG } : {}
|
|
186
|
+
) as T;
|
|
184
187
|
|
|
185
188
|
// Apply initial config if provided
|
|
186
189
|
if (options.config) {
|
|
@@ -212,10 +215,10 @@ export class ConfigManager<T extends BuenoConfig = BuenoConfig> {
|
|
|
212
215
|
// Merge all sources
|
|
213
216
|
const merged = mergeConfigs(
|
|
214
217
|
{} as T,
|
|
215
|
-
this.options.useDefaults !== false ? DEFAULT_CONFIG : {} as T,
|
|
218
|
+
this.options.useDefaults !== false ? DEFAULT_CONFIG : ({} as T),
|
|
216
219
|
fileConfig as T,
|
|
217
220
|
envConfig as T,
|
|
218
|
-
this.options.config as T || {} as T,
|
|
221
|
+
(this.options.config as T) || ({} as T),
|
|
219
222
|
);
|
|
220
223
|
|
|
221
224
|
this.config = merged as T;
|
|
@@ -270,7 +273,10 @@ export class ConfigManager<T extends BuenoConfig = BuenoConfig> {
|
|
|
270
273
|
set(key: string, value: unknown): void;
|
|
271
274
|
set(key: string, value: unknown): void {
|
|
272
275
|
const parts = key.split(".");
|
|
273
|
-
let current: Record<string, unknown> = this.config as Record<
|
|
276
|
+
let current: Record<string, unknown> = this.config as Record<
|
|
277
|
+
string,
|
|
278
|
+
unknown
|
|
279
|
+
>;
|
|
274
280
|
|
|
275
281
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
276
282
|
const part = parts[i];
|
|
@@ -320,7 +326,9 @@ export class ConfigManager<T extends BuenoConfig = BuenoConfig> {
|
|
|
320
326
|
* Validate synchronously (only default rules)
|
|
321
327
|
*/
|
|
322
328
|
validateSync(): ConfigValidationResult {
|
|
323
|
-
return validateConfigSync(
|
|
329
|
+
return validateConfigSync(
|
|
330
|
+
this.config as unknown as DeepPartial<BuenoConfig>,
|
|
331
|
+
);
|
|
324
332
|
}
|
|
325
333
|
|
|
326
334
|
/**
|
|
@@ -452,9 +460,9 @@ export function defineConfigFn<T extends BuenoConfig = BuenoConfig>(
|
|
|
452
460
|
* const config = await createConfigManager();
|
|
453
461
|
* const port = config.get('server.port');
|
|
454
462
|
*/
|
|
455
|
-
export async function createConfigManager<
|
|
456
|
-
T
|
|
457
|
-
|
|
463
|
+
export async function createConfigManager<T extends BuenoConfig = BuenoConfig>(
|
|
464
|
+
options?: ConfigManagerOptions<T>,
|
|
465
|
+
): Promise<ConfigManager<T>> {
|
|
458
466
|
const manager = new ConfigManager<T>(options);
|
|
459
467
|
await manager.load();
|
|
460
468
|
return manager;
|
|
@@ -478,9 +486,9 @@ export function createConfigManagerSync<T extends BuenoConfig = BuenoConfig>(
|
|
|
478
486
|
* const config = await loadConfigDirect();
|
|
479
487
|
* console.log(config.server?.port);
|
|
480
488
|
*/
|
|
481
|
-
export async function loadConfigDirect<
|
|
482
|
-
T
|
|
483
|
-
|
|
489
|
+
export async function loadConfigDirect<T extends BuenoConfig = BuenoConfig>(
|
|
490
|
+
options?: ConfigManagerOptions<T>,
|
|
491
|
+
): Promise<T> {
|
|
484
492
|
const manager = await createConfigManager<T>(options);
|
|
485
493
|
return manager.getAll();
|
|
486
494
|
}
|
|
@@ -503,4 +511,4 @@ export function getConfigManager(): ConfigManager {
|
|
|
503
511
|
*/
|
|
504
512
|
export function setConfigManager(manager: ConfigManager): void {
|
|
505
513
|
defaultManager = manager;
|
|
506
|
-
}
|
|
514
|
+
}
|
package/src/config/loader.ts
CHANGED
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
* Uses Bun's native TypeScript loader to import config files
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { BuenoConfig, DeepPartial, UserConfig, UserConfigFn } from "./types";
|
|
7
6
|
import { deepMerge } from "./merge";
|
|
7
|
+
import type {
|
|
8
|
+
BuenoConfig,
|
|
9
|
+
DeepPartial,
|
|
10
|
+
UserConfig,
|
|
11
|
+
UserConfigFn,
|
|
12
|
+
} from "./types";
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
15
|
* Configuration file search order
|
|
@@ -74,7 +79,9 @@ export function clearConfigCache(): void {
|
|
|
74
79
|
/**
|
|
75
80
|
* Get cached config
|
|
76
81
|
*/
|
|
77
|
-
export function getCachedConfig(
|
|
82
|
+
export function getCachedConfig(
|
|
83
|
+
path: string,
|
|
84
|
+
): DeepPartial<BuenoConfig> | undefined {
|
|
78
85
|
return configCache.get(path);
|
|
79
86
|
}
|
|
80
87
|
|
|
@@ -152,18 +159,18 @@ export async function loadConfigFile<T extends BuenoConfig = BuenoConfig>(
|
|
|
152
159
|
* Load configuration from file
|
|
153
160
|
* Searches for config files in order and loads the first one found
|
|
154
161
|
*/
|
|
155
|
-
export async function loadConfig<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
): Promise<LoadedConfig> {
|
|
162
|
+
export async function loadConfig<
|
|
163
|
+
T extends BuenoConfig = BuenoConfig,
|
|
164
|
+
>(options?: {
|
|
165
|
+
/** Custom config file path */
|
|
166
|
+
configPath?: string;
|
|
167
|
+
/** Working directory to search for config */
|
|
168
|
+
cwd?: string;
|
|
169
|
+
/** Whether to use cache */
|
|
170
|
+
useCache?: boolean;
|
|
171
|
+
/** Additional context to pass to config function */
|
|
172
|
+
context?: Record<string, unknown>;
|
|
173
|
+
}): Promise<LoadedConfig> {
|
|
167
174
|
// If a specific path is provided, use it
|
|
168
175
|
if (options?.configPath) {
|
|
169
176
|
return loadConfigFile<T>(options.configPath, {
|
|
@@ -306,7 +313,9 @@ export function validateConfigStructure(
|
|
|
306
313
|
/**
|
|
307
314
|
* Extract config file path from CLI args
|
|
308
315
|
*/
|
|
309
|
-
export function getConfigPathFromArgs(
|
|
316
|
+
export function getConfigPathFromArgs(
|
|
317
|
+
args: string[] = process.argv,
|
|
318
|
+
): string | undefined {
|
|
310
319
|
const configIndex = args.indexOf("--config");
|
|
311
320
|
if (configIndex !== -1 && args[configIndex + 1]) {
|
|
312
321
|
return args[configIndex + 1];
|
|
@@ -326,4 +335,4 @@ export function getConfigPathFromArgs(args: string[] = process.argv): string | u
|
|
|
326
335
|
*/
|
|
327
336
|
export function getConfigPathFromEnv(): string | undefined {
|
|
328
337
|
return Bun.env.BUENO_CONFIG;
|
|
329
|
-
}
|
|
338
|
+
}
|
package/src/config/merge.ts
CHANGED
|
@@ -7,7 +7,9 @@ import type { BuenoConfig, DeepPartial } from "./types";
|
|
|
7
7
|
/**
|
|
8
8
|
* Check if a value is a plain object (not an array, not null, not a class instance)
|
|
9
9
|
*/
|
|
10
|
-
export function isPlainObject(
|
|
10
|
+
export function isPlainObject(
|
|
11
|
+
value: unknown,
|
|
12
|
+
): value is Record<string, unknown> {
|
|
11
13
|
if (value === null || typeof value !== "object") {
|
|
12
14
|
return false;
|
|
13
15
|
}
|
|
@@ -60,7 +62,10 @@ export function deepMerge<T>(target: T, source: DeepPartial<T>): T {
|
|
|
60
62
|
|
|
61
63
|
if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
|
|
62
64
|
// Both are objects, merge recursively
|
|
63
|
-
result[key] = deepMerge(
|
|
65
|
+
result[key] = deepMerge(
|
|
66
|
+
targetValue,
|
|
67
|
+
sourceValue as DeepPartial<typeof targetValue>,
|
|
68
|
+
);
|
|
64
69
|
} else if (Array.isArray(sourceValue) && Array.isArray(targetValue)) {
|
|
65
70
|
// Both are arrays, concatenate them
|
|
66
71
|
result[key] = [...targetValue, ...sourceValue];
|
|
@@ -80,13 +85,19 @@ export function deepMerge<T>(target: T, source: DeepPartial<T>): T {
|
|
|
80
85
|
export function mergeConfigs<T extends BuenoConfig = BuenoConfig>(
|
|
81
86
|
...configs: (DeepPartial<T> | undefined | null)[]
|
|
82
87
|
): DeepPartial<T> {
|
|
83
|
-
return configs.reduce<DeepPartial<T>>(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
return configs.reduce<DeepPartial<T>>(
|
|
89
|
+
(acc, config) => {
|
|
90
|
+
if (config === undefined || config === null) {
|
|
91
|
+
return acc;
|
|
92
|
+
}
|
|
93
|
+
// Use unknown as intermediate type to avoid recursive type issues
|
|
94
|
+
return deepMerge(
|
|
95
|
+
acc as unknown as T,
|
|
96
|
+
config as unknown as DeepPartial<T>,
|
|
97
|
+
) as unknown as DeepPartial<T>;
|
|
98
|
+
},
|
|
99
|
+
{} as DeepPartial<T>,
|
|
100
|
+
);
|
|
90
101
|
}
|
|
91
102
|
|
|
92
103
|
/**
|
|
@@ -282,4 +293,4 @@ export function diffConfigs(
|
|
|
282
293
|
}
|
|
283
294
|
|
|
284
295
|
return { added, removed, changed };
|
|
285
|
-
}
|
|
296
|
+
}
|