@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/types.ts
CHANGED
|
@@ -78,6 +78,17 @@ export interface MetricsConfig {
|
|
|
78
78
|
maxHistorySize?: number;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
// ============= Observability Configuration =============
|
|
82
|
+
|
|
83
|
+
export interface ObservabilityConfig {
|
|
84
|
+
/** Enable the observability integration layer */
|
|
85
|
+
enabled?: boolean;
|
|
86
|
+
/** Maximum breadcrumb ring buffer size (default: 20) */
|
|
87
|
+
breadcrumbsSize?: number;
|
|
88
|
+
/** HTTP status codes to suppress from error reporting (e.g. [404, 401]) */
|
|
89
|
+
ignoreStatusCodes?: number[];
|
|
90
|
+
}
|
|
91
|
+
|
|
81
92
|
// ============= Telemetry Configuration =============
|
|
82
93
|
|
|
83
94
|
export interface TelemetryConfig {
|
|
@@ -91,6 +102,139 @@ export interface TelemetryConfig {
|
|
|
91
102
|
sampleRate?: number;
|
|
92
103
|
}
|
|
93
104
|
|
|
105
|
+
// ============= Jobs Configuration =============
|
|
106
|
+
|
|
107
|
+
export interface JobsConfig {
|
|
108
|
+
/** Enable background jobs */
|
|
109
|
+
enabled?: boolean;
|
|
110
|
+
/** Job queue driver type */
|
|
111
|
+
driver?: "redis" | "memory";
|
|
112
|
+
/** Redis connection URL */
|
|
113
|
+
url?: string;
|
|
114
|
+
/** Key prefix for jobs (default: 'jobs:') */
|
|
115
|
+
keyPrefix?: string;
|
|
116
|
+
/** Max concurrent jobs (default: 10) */
|
|
117
|
+
concurrency?: number;
|
|
118
|
+
/** Max retry attempts (default: 3) */
|
|
119
|
+
maxRetries?: number;
|
|
120
|
+
/** Retry delay in seconds (default: 1) */
|
|
121
|
+
retryDelay?: number;
|
|
122
|
+
/** Job batch size (default: 10) */
|
|
123
|
+
batchSize?: number;
|
|
124
|
+
/** Poll interval in milliseconds (default: 1000) */
|
|
125
|
+
pollInterval?: number;
|
|
126
|
+
/** Job timeout in milliseconds (default: 300000 / 5 minutes) */
|
|
127
|
+
jobTimeout?: number;
|
|
128
|
+
/** Enable metrics collection */
|
|
129
|
+
enableMetrics?: boolean;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ============= Template Configuration =============
|
|
133
|
+
|
|
134
|
+
export interface TemplateConfig {
|
|
135
|
+
/** Enable template system */
|
|
136
|
+
enabled?: boolean;
|
|
137
|
+
/** Base path to templates directory (default: 'resources/templates') */
|
|
138
|
+
basePath?: string;
|
|
139
|
+
/** Cache configuration */
|
|
140
|
+
cache?: {
|
|
141
|
+
/** Enable template caching (default: true) */
|
|
142
|
+
enabled?: boolean;
|
|
143
|
+
/** Cache TTL in seconds (default: 3600) */
|
|
144
|
+
ttl?: number;
|
|
145
|
+
/** Maximum templates in cache (default: 100) */
|
|
146
|
+
maxSize?: number;
|
|
147
|
+
};
|
|
148
|
+
/** Enable file watching for hot reload in development */
|
|
149
|
+
watch?: boolean;
|
|
150
|
+
/** Default output format: 'html' or 'text' */
|
|
151
|
+
defaultFormat?: "html" | "text";
|
|
152
|
+
/** Channel to variant mapping for auto-detection */
|
|
153
|
+
channelVariantMap?: Record<string, string>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ============= Notification Configuration =============
|
|
157
|
+
|
|
158
|
+
export interface NotificationConfig {
|
|
159
|
+
/** Enable notification service */
|
|
160
|
+
enabled?: boolean;
|
|
161
|
+
/** Enable metrics collection */
|
|
162
|
+
enableMetrics?: boolean;
|
|
163
|
+
/** Default channel for sending */
|
|
164
|
+
defaultChannel?: string;
|
|
165
|
+
/** Enable job queue integration for async sending */
|
|
166
|
+
queue?: boolean;
|
|
167
|
+
/** Email channel configuration */
|
|
168
|
+
email?: {
|
|
169
|
+
enabled?: boolean;
|
|
170
|
+
driver?: "smtp" | "sendgrid" | "brevo" | "resend";
|
|
171
|
+
from?: string;
|
|
172
|
+
fromName?: string;
|
|
173
|
+
dryRun?: boolean;
|
|
174
|
+
smtp?: {
|
|
175
|
+
host?: string;
|
|
176
|
+
port?: number;
|
|
177
|
+
secure?: boolean;
|
|
178
|
+
username?: string;
|
|
179
|
+
password?: string;
|
|
180
|
+
};
|
|
181
|
+
apiKey?: string;
|
|
182
|
+
};
|
|
183
|
+
/** SMS channel configuration */
|
|
184
|
+
sms?: {
|
|
185
|
+
enabled?: boolean;
|
|
186
|
+
driver?: "twilio" | "aws-sns" | "custom";
|
|
187
|
+
dryRun?: boolean;
|
|
188
|
+
accountSid?: string;
|
|
189
|
+
authToken?: string;
|
|
190
|
+
fromNumber?: string;
|
|
191
|
+
apiKey?: string;
|
|
192
|
+
};
|
|
193
|
+
/** WhatsApp channel configuration */
|
|
194
|
+
whatsapp?: {
|
|
195
|
+
enabled?: boolean;
|
|
196
|
+
driver?: "twilio" | "custom";
|
|
197
|
+
dryRun?: boolean;
|
|
198
|
+
accountSid?: string;
|
|
199
|
+
authToken?: string;
|
|
200
|
+
businessPhoneNumber?: string;
|
|
201
|
+
apiKey?: string;
|
|
202
|
+
};
|
|
203
|
+
/** Push notification channel configuration */
|
|
204
|
+
push?: {
|
|
205
|
+
enabled?: boolean;
|
|
206
|
+
driver?: "firebase" | "apns" | "custom";
|
|
207
|
+
dryRun?: boolean;
|
|
208
|
+
serverKey?: string;
|
|
209
|
+
certificatePath?: string;
|
|
210
|
+
apiKey?: string;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ============= i18n Configuration =============
|
|
215
|
+
|
|
216
|
+
export interface I18nConfig {
|
|
217
|
+
/** Enable i18n system */
|
|
218
|
+
enabled?: boolean;
|
|
219
|
+
/** Default locale — used as fallback when requested locale has missing keys (default: "en") */
|
|
220
|
+
defaultLocale?: string;
|
|
221
|
+
/** List of supported locale identifiers (default: ["en"]) */
|
|
222
|
+
supportedLocales?: string[];
|
|
223
|
+
/** Base directory for locale JSON files (default: "resources/i18n") */
|
|
224
|
+
basePath?: string;
|
|
225
|
+
/**
|
|
226
|
+
* Fall back to defaultLocale when a key is missing in the requested locale.
|
|
227
|
+
* (default: true)
|
|
228
|
+
*/
|
|
229
|
+
fallbackToDefault?: boolean;
|
|
230
|
+
/** Cookie name used to persist locale choice (default: "bueno_locale") */
|
|
231
|
+
cookieName?: string;
|
|
232
|
+
/** Cookie max-age in seconds (default: 31536000 — 1 year) */
|
|
233
|
+
cookieMaxAge?: number;
|
|
234
|
+
/** Enable file watching for hot reload in development */
|
|
235
|
+
watch?: boolean;
|
|
236
|
+
}
|
|
237
|
+
|
|
94
238
|
// ============= Frontend Configuration =============
|
|
95
239
|
|
|
96
240
|
export interface FrontendConfig {
|
|
@@ -114,6 +258,14 @@ export interface BuenoConfig {
|
|
|
114
258
|
database?: DatabaseConfig;
|
|
115
259
|
/** Cache configuration */
|
|
116
260
|
cache?: CacheConfig;
|
|
261
|
+
/** Jobs configuration */
|
|
262
|
+
jobs?: JobsConfig;
|
|
263
|
+
/** Template configuration */
|
|
264
|
+
template?: TemplateConfig;
|
|
265
|
+
/** Notification configuration */
|
|
266
|
+
notification?: NotificationConfig;
|
|
267
|
+
/** i18n configuration */
|
|
268
|
+
i18n?: I18nConfig;
|
|
117
269
|
/** Logger configuration */
|
|
118
270
|
logger?: LoggerConfig;
|
|
119
271
|
/** Health check configuration */
|
|
@@ -122,6 +274,8 @@ export interface BuenoConfig {
|
|
|
122
274
|
metrics?: MetricsConfig;
|
|
123
275
|
/** Telemetry configuration */
|
|
124
276
|
telemetry?: TelemetryConfig;
|
|
277
|
+
/** Observability / error tracking configuration */
|
|
278
|
+
observability?: ObservabilityConfig;
|
|
125
279
|
/** Frontend configuration */
|
|
126
280
|
frontend?: FrontendConfig;
|
|
127
281
|
}
|
|
@@ -197,20 +351,23 @@ export type UserConfig<T extends BuenoConfig = BuenoConfig> = DeepPartial<T>;
|
|
|
197
351
|
/**
|
|
198
352
|
* User configuration function type
|
|
199
353
|
*/
|
|
200
|
-
export type UserConfigFn<T extends BuenoConfig = BuenoConfig> = (
|
|
354
|
+
export type UserConfigFn<T extends BuenoConfig = BuenoConfig> = (
|
|
355
|
+
env: string,
|
|
356
|
+
) => UserConfig<T> | Promise<UserConfig<T>>;
|
|
201
357
|
|
|
202
358
|
/**
|
|
203
359
|
* Configuration value type for a given key path
|
|
204
360
|
*/
|
|
205
|
-
export type ConfigValueForKey<TKey extends string> =
|
|
206
|
-
|
|
207
|
-
?
|
|
208
|
-
?
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
361
|
+
export type ConfigValueForKey<TKey extends string> =
|
|
362
|
+
TKey extends `${infer T}.${infer Rest}`
|
|
363
|
+
? T extends keyof BuenoConfig
|
|
364
|
+
? Rest extends string
|
|
365
|
+
? ConfigValueForKey<Rest>
|
|
366
|
+
: BuenoConfig[T]
|
|
367
|
+
: unknown
|
|
368
|
+
: TKey extends keyof BuenoConfig
|
|
369
|
+
? BuenoConfig[TKey]
|
|
370
|
+
: unknown;
|
|
214
371
|
|
|
215
372
|
// ============= Default Configuration =============
|
|
216
373
|
|
|
@@ -233,6 +390,75 @@ export const DEFAULT_CONFIG: Required<BuenoConfig> = {
|
|
|
233
390
|
keyPrefix: "",
|
|
234
391
|
enableMetrics: true,
|
|
235
392
|
},
|
|
393
|
+
jobs: {
|
|
394
|
+
enabled: false,
|
|
395
|
+
driver: "memory",
|
|
396
|
+
url: undefined,
|
|
397
|
+
keyPrefix: "jobs:",
|
|
398
|
+
concurrency: 10,
|
|
399
|
+
maxRetries: 3,
|
|
400
|
+
retryDelay: 1,
|
|
401
|
+
batchSize: 10,
|
|
402
|
+
pollInterval: 1000,
|
|
403
|
+
jobTimeout: 300000,
|
|
404
|
+
enableMetrics: true,
|
|
405
|
+
},
|
|
406
|
+
template: {
|
|
407
|
+
enabled: true,
|
|
408
|
+
basePath: "resources/templates",
|
|
409
|
+
cache: {
|
|
410
|
+
enabled: true,
|
|
411
|
+
ttl: 3600,
|
|
412
|
+
maxSize: 100,
|
|
413
|
+
},
|
|
414
|
+
watch: false,
|
|
415
|
+
defaultFormat: "html",
|
|
416
|
+
channelVariantMap: {
|
|
417
|
+
email: "email",
|
|
418
|
+
sms: "sms",
|
|
419
|
+
push: "push",
|
|
420
|
+
whatsapp: "whatsapp",
|
|
421
|
+
web: "web",
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
notification: {
|
|
425
|
+
enabled: false,
|
|
426
|
+
enableMetrics: true,
|
|
427
|
+
queue: false,
|
|
428
|
+
defaultChannel: "email",
|
|
429
|
+
email: {
|
|
430
|
+
enabled: true,
|
|
431
|
+
driver: "smtp",
|
|
432
|
+
from: "noreply@example.com",
|
|
433
|
+
fromName: "Bueno App",
|
|
434
|
+
dryRun: false,
|
|
435
|
+
},
|
|
436
|
+
sms: {
|
|
437
|
+
enabled: false,
|
|
438
|
+
driver: "twilio",
|
|
439
|
+
dryRun: false,
|
|
440
|
+
},
|
|
441
|
+
whatsapp: {
|
|
442
|
+
enabled: false,
|
|
443
|
+
driver: "twilio",
|
|
444
|
+
dryRun: false,
|
|
445
|
+
},
|
|
446
|
+
push: {
|
|
447
|
+
enabled: false,
|
|
448
|
+
driver: "firebase",
|
|
449
|
+
dryRun: false,
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
i18n: {
|
|
453
|
+
enabled: false,
|
|
454
|
+
defaultLocale: "en",
|
|
455
|
+
supportedLocales: ["en"],
|
|
456
|
+
basePath: "resources/i18n",
|
|
457
|
+
fallbackToDefault: true,
|
|
458
|
+
cookieName: "bueno_locale",
|
|
459
|
+
cookieMaxAge: 31536000,
|
|
460
|
+
watch: false,
|
|
461
|
+
},
|
|
236
462
|
logger: {
|
|
237
463
|
level: "info",
|
|
238
464
|
pretty: true,
|
|
@@ -274,47 +500,341 @@ export interface EnvMapping {
|
|
|
274
500
|
|
|
275
501
|
export const ENV_MAPPINGS: EnvMapping[] = [
|
|
276
502
|
// Server
|
|
277
|
-
{
|
|
503
|
+
{
|
|
504
|
+
envVar: "BUENO_PORT",
|
|
505
|
+
configKey: "server.port",
|
|
506
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
507
|
+
},
|
|
278
508
|
{ envVar: "BUENO_HOST", configKey: "server.host" },
|
|
279
|
-
{
|
|
280
|
-
|
|
509
|
+
{
|
|
510
|
+
envVar: "BUENO_DEV",
|
|
511
|
+
configKey: "server.development",
|
|
512
|
+
transform: (v) => v === "true",
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
envVar: "PORT",
|
|
516
|
+
configKey: "server.port",
|
|
517
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
518
|
+
},
|
|
281
519
|
{ envVar: "HOST", configKey: "server.host" },
|
|
282
520
|
|
|
283
521
|
// Database
|
|
284
522
|
{ envVar: "DATABASE_URL", configKey: "database.url" },
|
|
285
523
|
{ envVar: "BUENO_DATABASE_URL", configKey: "database.url" },
|
|
286
|
-
{
|
|
287
|
-
|
|
288
|
-
|
|
524
|
+
{
|
|
525
|
+
envVar: "BUENO_DB_POOL_SIZE",
|
|
526
|
+
configKey: "database.poolSize",
|
|
527
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
envVar: "BUENO_DB_METRICS",
|
|
531
|
+
configKey: "database.enableMetrics",
|
|
532
|
+
transform: (v) => v === "true",
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
envVar: "BUENO_DB_SLOW_QUERY",
|
|
536
|
+
configKey: "database.slowQueryThreshold",
|
|
537
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
538
|
+
},
|
|
289
539
|
|
|
290
540
|
// Cache
|
|
291
541
|
{ envVar: "REDIS_URL", configKey: "cache.url" },
|
|
292
542
|
{ envVar: "BUENO_REDIS_URL", configKey: "cache.url" },
|
|
293
543
|
{ envVar: "BUENO_CACHE_DRIVER", configKey: "cache.driver" },
|
|
294
|
-
{
|
|
544
|
+
{
|
|
545
|
+
envVar: "BUENO_CACHE_TTL",
|
|
546
|
+
configKey: "cache.ttl",
|
|
547
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
548
|
+
},
|
|
295
549
|
{ envVar: "BUENO_CACHE_PREFIX", configKey: "cache.keyPrefix" },
|
|
296
550
|
|
|
551
|
+
// Jobs
|
|
552
|
+
{
|
|
553
|
+
envVar: "BUENO_JOBS_ENABLED",
|
|
554
|
+
configKey: "jobs.enabled",
|
|
555
|
+
transform: (v) => v === "true",
|
|
556
|
+
},
|
|
557
|
+
{ envVar: "BUENO_JOBS_DRIVER", configKey: "jobs.driver" },
|
|
558
|
+
{ envVar: "BUENO_JOBS_URL", configKey: "jobs.url" },
|
|
559
|
+
{
|
|
560
|
+
envVar: "BUENO_JOBS_CONCURRENCY",
|
|
561
|
+
configKey: "jobs.concurrency",
|
|
562
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
envVar: "BUENO_JOBS_MAX_RETRIES",
|
|
566
|
+
configKey: "jobs.maxRetries",
|
|
567
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
envVar: "BUENO_JOBS_RETRY_DELAY",
|
|
571
|
+
configKey: "jobs.retryDelay",
|
|
572
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
envVar: "BUENO_JOBS_BATCH_SIZE",
|
|
576
|
+
configKey: "jobs.batchSize",
|
|
577
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
envVar: "BUENO_JOBS_POLL_INTERVAL",
|
|
581
|
+
configKey: "jobs.pollInterval",
|
|
582
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
envVar: "BUENO_JOBS_TIMEOUT",
|
|
586
|
+
configKey: "jobs.jobTimeout",
|
|
587
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
588
|
+
},
|
|
589
|
+
|
|
590
|
+
// Template
|
|
591
|
+
{
|
|
592
|
+
envVar: "BUENO_TEMPLATE_ENABLED",
|
|
593
|
+
configKey: "template.enabled",
|
|
594
|
+
transform: (v) => v === "true",
|
|
595
|
+
},
|
|
596
|
+
{ envVar: "BUENO_TEMPLATE_BASE_PATH", configKey: "template.basePath" },
|
|
597
|
+
{
|
|
598
|
+
envVar: "BUENO_TEMPLATE_CACHE_ENABLED",
|
|
599
|
+
configKey: "template.cache.enabled",
|
|
600
|
+
transform: (v) => v === "true",
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
envVar: "BUENO_TEMPLATE_CACHE_TTL",
|
|
604
|
+
configKey: "template.cache.ttl",
|
|
605
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
envVar: "BUENO_TEMPLATE_CACHE_MAX_SIZE",
|
|
609
|
+
configKey: "template.cache.maxSize",
|
|
610
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
envVar: "BUENO_TEMPLATE_WATCH",
|
|
614
|
+
configKey: "template.watch",
|
|
615
|
+
transform: (v) => v === "true",
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
envVar: "BUENO_TEMPLATE_DEFAULT_FORMAT",
|
|
619
|
+
configKey: "template.defaultFormat",
|
|
620
|
+
},
|
|
621
|
+
|
|
622
|
+
// Notification
|
|
623
|
+
{
|
|
624
|
+
envVar: "BUENO_NOTIFICATION_ENABLED",
|
|
625
|
+
configKey: "notification.enabled",
|
|
626
|
+
transform: (v) => v === "true",
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
envVar: "BUENO_NOTIFICATION_METRICS",
|
|
630
|
+
configKey: "notification.enableMetrics",
|
|
631
|
+
transform: (v) => v === "true",
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
envVar: "BUENO_NOTIFICATION_QUEUE",
|
|
635
|
+
configKey: "notification.queue",
|
|
636
|
+
transform: (v) => v === "true",
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
envVar: "BUENO_NOTIFICATION_DEFAULT",
|
|
640
|
+
configKey: "notification.defaultChannel",
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
// Email Channel
|
|
644
|
+
{
|
|
645
|
+
envVar: "BUENO_EMAIL_ENABLED",
|
|
646
|
+
configKey: "notification.email.enabled",
|
|
647
|
+
transform: (v) => v === "true",
|
|
648
|
+
},
|
|
649
|
+
{ envVar: "BUENO_EMAIL_DRIVER", configKey: "notification.email.driver" },
|
|
650
|
+
{ envVar: "BUENO_EMAIL_FROM", configKey: "notification.email.from" },
|
|
651
|
+
{ envVar: "BUENO_EMAIL_FROM_NAME", configKey: "notification.email.fromName" },
|
|
652
|
+
{ envVar: "BUENO_EMAIL_API_KEY", configKey: "notification.email.apiKey" },
|
|
653
|
+
{
|
|
654
|
+
envVar: "BUENO_EMAIL_DRY_RUN",
|
|
655
|
+
configKey: "notification.email.dryRun",
|
|
656
|
+
transform: (v) => v === "true",
|
|
657
|
+
},
|
|
658
|
+
{ envVar: "BUENO_SMTP_HOST", configKey: "notification.email.smtp.host" },
|
|
659
|
+
{
|
|
660
|
+
envVar: "BUENO_SMTP_PORT",
|
|
661
|
+
configKey: "notification.email.smtp.port",
|
|
662
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
663
|
+
},
|
|
664
|
+
{ envVar: "BUENO_SMTP_USER", configKey: "notification.email.smtp.username" },
|
|
665
|
+
{
|
|
666
|
+
envVar: "BUENO_SMTP_PASSWORD",
|
|
667
|
+
configKey: "notification.email.smtp.password",
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
envVar: "BUENO_SMTP_SECURE",
|
|
671
|
+
configKey: "notification.email.smtp.secure",
|
|
672
|
+
transform: (v) => v === "true",
|
|
673
|
+
},
|
|
674
|
+
|
|
675
|
+
// SMS Channel
|
|
676
|
+
{
|
|
677
|
+
envVar: "BUENO_SMS_ENABLED",
|
|
678
|
+
configKey: "notification.sms.enabled",
|
|
679
|
+
transform: (v) => v === "true",
|
|
680
|
+
},
|
|
681
|
+
{ envVar: "BUENO_SMS_DRIVER", configKey: "notification.sms.driver" },
|
|
682
|
+
{
|
|
683
|
+
envVar: "BUENO_SMS_DRY_RUN",
|
|
684
|
+
configKey: "notification.sms.dryRun",
|
|
685
|
+
transform: (v) => v === "true",
|
|
686
|
+
},
|
|
687
|
+
{ envVar: "BUENO_SMS_ACCOUNT_SID", configKey: "notification.sms.accountSid" },
|
|
688
|
+
{ envVar: "BUENO_SMS_AUTH_TOKEN", configKey: "notification.sms.authToken" },
|
|
689
|
+
{ envVar: "BUENO_SMS_FROM_NUMBER", configKey: "notification.sms.fromNumber" },
|
|
690
|
+
|
|
691
|
+
// WhatsApp Channel
|
|
692
|
+
{
|
|
693
|
+
envVar: "BUENO_WHATSAPP_ENABLED",
|
|
694
|
+
configKey: "notification.whatsapp.enabled",
|
|
695
|
+
transform: (v) => v === "true",
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
envVar: "BUENO_WHATSAPP_DRIVER",
|
|
699
|
+
configKey: "notification.whatsapp.driver",
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
envVar: "BUENO_WHATSAPP_DRY_RUN",
|
|
703
|
+
configKey: "notification.whatsapp.dryRun",
|
|
704
|
+
transform: (v) => v === "true",
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
envVar: "BUENO_WHATSAPP_ACCOUNT_SID",
|
|
708
|
+
configKey: "notification.whatsapp.accountSid",
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
envVar: "BUENO_WHATSAPP_AUTH_TOKEN",
|
|
712
|
+
configKey: "notification.whatsapp.authToken",
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
envVar: "BUENO_WHATSAPP_BUSINESS_PHONE",
|
|
716
|
+
configKey: "notification.whatsapp.businessPhoneNumber",
|
|
717
|
+
},
|
|
718
|
+
|
|
719
|
+
// Push Channel
|
|
720
|
+
{
|
|
721
|
+
envVar: "BUENO_PUSH_ENABLED",
|
|
722
|
+
configKey: "notification.push.enabled",
|
|
723
|
+
transform: (v) => v === "true",
|
|
724
|
+
},
|
|
725
|
+
{ envVar: "BUENO_PUSH_DRIVER", configKey: "notification.push.driver" },
|
|
726
|
+
{
|
|
727
|
+
envVar: "BUENO_PUSH_DRY_RUN",
|
|
728
|
+
configKey: "notification.push.dryRun",
|
|
729
|
+
transform: (v) => v === "true",
|
|
730
|
+
},
|
|
731
|
+
{ envVar: "BUENO_PUSH_SERVER_KEY", configKey: "notification.push.serverKey" },
|
|
732
|
+
{
|
|
733
|
+
envVar: "BUENO_PUSH_CERTIFICATE_PATH",
|
|
734
|
+
configKey: "notification.push.certificatePath",
|
|
735
|
+
},
|
|
736
|
+
|
|
737
|
+
// i18n
|
|
738
|
+
{
|
|
739
|
+
envVar: "BUENO_I18N_ENABLED",
|
|
740
|
+
configKey: "i18n.enabled",
|
|
741
|
+
transform: (v) => v === "true",
|
|
742
|
+
},
|
|
743
|
+
{ envVar: "BUENO_I18N_DEFAULT_LOCALE", configKey: "i18n.defaultLocale" },
|
|
744
|
+
{
|
|
745
|
+
envVar: "BUENO_I18N_SUPPORTED_LOCALES",
|
|
746
|
+
configKey: "i18n.supportedLocales",
|
|
747
|
+
transform: (v) => v.split(",").map((s) => s.trim()),
|
|
748
|
+
},
|
|
749
|
+
{ envVar: "BUENO_I18N_BASE_PATH", configKey: "i18n.basePath" },
|
|
750
|
+
{
|
|
751
|
+
envVar: "BUENO_I18N_FALLBACK",
|
|
752
|
+
configKey: "i18n.fallbackToDefault",
|
|
753
|
+
transform: (v) => v === "true",
|
|
754
|
+
},
|
|
755
|
+
{ envVar: "BUENO_I18N_COOKIE_NAME", configKey: "i18n.cookieName" },
|
|
756
|
+
{
|
|
757
|
+
envVar: "BUENO_I18N_COOKIE_MAX_AGE",
|
|
758
|
+
configKey: "i18n.cookieMaxAge",
|
|
759
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
envVar: "BUENO_I18N_WATCH",
|
|
763
|
+
configKey: "i18n.watch",
|
|
764
|
+
transform: (v) => v === "true",
|
|
765
|
+
},
|
|
766
|
+
|
|
297
767
|
// Logger
|
|
298
768
|
{ envVar: "LOG_LEVEL", configKey: "logger.level" },
|
|
299
769
|
{ envVar: "BUENO_LOG_LEVEL", configKey: "logger.level" },
|
|
300
|
-
{
|
|
770
|
+
{
|
|
771
|
+
envVar: "BUENO_LOG_PRETTY",
|
|
772
|
+
configKey: "logger.pretty",
|
|
773
|
+
transform: (v) => v === "true",
|
|
774
|
+
},
|
|
301
775
|
|
|
302
776
|
// Health
|
|
303
|
-
{
|
|
777
|
+
{
|
|
778
|
+
envVar: "BUENO_HEALTH_ENABLED",
|
|
779
|
+
configKey: "health.enabled",
|
|
780
|
+
transform: (v) => v === "true",
|
|
781
|
+
},
|
|
304
782
|
{ envVar: "BUENO_HEALTH_PATH", configKey: "health.healthPath" },
|
|
305
783
|
{ envVar: "BUENO_READY_PATH", configKey: "health.readyPath" },
|
|
306
784
|
|
|
307
785
|
// Metrics
|
|
308
|
-
{
|
|
309
|
-
|
|
786
|
+
{
|
|
787
|
+
envVar: "BUENO_METRICS_ENABLED",
|
|
788
|
+
configKey: "metrics.enabled",
|
|
789
|
+
transform: (v) => v === "true",
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
envVar: "BUENO_METRICS_INTERVAL",
|
|
793
|
+
configKey: "metrics.collectInterval",
|
|
794
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
795
|
+
},
|
|
310
796
|
|
|
311
797
|
// Telemetry
|
|
312
|
-
{
|
|
798
|
+
{
|
|
799
|
+
envVar: "BUENO_TELEMETRY_ENABLED",
|
|
800
|
+
configKey: "telemetry.enabled",
|
|
801
|
+
transform: (v) => v === "true",
|
|
802
|
+
},
|
|
313
803
|
{ envVar: "BUENO_SERVICE_NAME", configKey: "telemetry.serviceName" },
|
|
314
804
|
{ envVar: "BUENO_OTEL_ENDPOINT", configKey: "telemetry.endpoint" },
|
|
315
805
|
{ envVar: "OTEL_EXPORTER_OTLP_ENDPOINT", configKey: "telemetry.endpoint" },
|
|
316
806
|
|
|
807
|
+
// Observability
|
|
808
|
+
{
|
|
809
|
+
envVar: "BUENO_OBSERVABILITY_ENABLED",
|
|
810
|
+
configKey: "observability.enabled",
|
|
811
|
+
transform: (v) => v === "true",
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
envVar: "BUENO_OBSERVABILITY_BREADCRUMBS_SIZE",
|
|
815
|
+
configKey: "observability.breadcrumbsSize",
|
|
816
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
envVar: "BUENO_OBSERVABILITY_IGNORE_STATUS_CODES",
|
|
820
|
+
configKey: "observability.ignoreStatusCodes",
|
|
821
|
+
transform: (v) =>
|
|
822
|
+
v
|
|
823
|
+
.split(",")
|
|
824
|
+
.map((s) => s.trim())
|
|
825
|
+
.filter(Boolean)
|
|
826
|
+
.map((s) => Number.parseInt(s, 10)),
|
|
827
|
+
},
|
|
828
|
+
|
|
317
829
|
// Frontend
|
|
318
|
-
{
|
|
319
|
-
|
|
320
|
-
|
|
830
|
+
{
|
|
831
|
+
envVar: "BUENO_FRONTEND_PORT",
|
|
832
|
+
configKey: "frontend.port",
|
|
833
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
834
|
+
},
|
|
835
|
+
{
|
|
836
|
+
envVar: "BUENO_HMR",
|
|
837
|
+
configKey: "frontend.hmr",
|
|
838
|
+
transform: (v) => v === "true",
|
|
839
|
+
},
|
|
840
|
+
];
|