@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/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 {
|
|
@@ -102,6 +246,25 @@ export interface FrontendConfig {
|
|
|
102
246
|
port?: number;
|
|
103
247
|
}
|
|
104
248
|
|
|
249
|
+
// ============= GraphQL Configuration =============
|
|
250
|
+
|
|
251
|
+
export interface GraphQLConfig {
|
|
252
|
+
/** Enable GraphQL support (default: false) */
|
|
253
|
+
enabled?: boolean;
|
|
254
|
+
/** HTTP path for GraphQL endpoint (default: '/graphql') */
|
|
255
|
+
path?: string;
|
|
256
|
+
/** Enable GraphiQL playground (default: auto — true with adapter, false with built-in) */
|
|
257
|
+
playground?: boolean;
|
|
258
|
+
/** Enable SDL introspection endpoint at GET <path>/schema (default: true) */
|
|
259
|
+
introspection?: boolean;
|
|
260
|
+
/** Maximum query complexity score (default: 1000) */
|
|
261
|
+
complexityLimit?: number;
|
|
262
|
+
/** Maximum query depth (default: 10) */
|
|
263
|
+
maxDepth?: number;
|
|
264
|
+
/** Enable WebSocket subscriptions (default: false) */
|
|
265
|
+
subscriptions?: boolean;
|
|
266
|
+
}
|
|
267
|
+
|
|
105
268
|
// ============= Main Configuration Interface =============
|
|
106
269
|
|
|
107
270
|
/**
|
|
@@ -114,6 +277,14 @@ export interface BuenoConfig {
|
|
|
114
277
|
database?: DatabaseConfig;
|
|
115
278
|
/** Cache configuration */
|
|
116
279
|
cache?: CacheConfig;
|
|
280
|
+
/** Jobs configuration */
|
|
281
|
+
jobs?: JobsConfig;
|
|
282
|
+
/** Template configuration */
|
|
283
|
+
template?: TemplateConfig;
|
|
284
|
+
/** Notification configuration */
|
|
285
|
+
notification?: NotificationConfig;
|
|
286
|
+
/** i18n configuration */
|
|
287
|
+
i18n?: I18nConfig;
|
|
117
288
|
/** Logger configuration */
|
|
118
289
|
logger?: LoggerConfig;
|
|
119
290
|
/** Health check configuration */
|
|
@@ -122,8 +293,12 @@ export interface BuenoConfig {
|
|
|
122
293
|
metrics?: MetricsConfig;
|
|
123
294
|
/** Telemetry configuration */
|
|
124
295
|
telemetry?: TelemetryConfig;
|
|
296
|
+
/** Observability / error tracking configuration */
|
|
297
|
+
observability?: ObservabilityConfig;
|
|
125
298
|
/** Frontend configuration */
|
|
126
299
|
frontend?: FrontendConfig;
|
|
300
|
+
/** GraphQL configuration */
|
|
301
|
+
graphql?: GraphQLConfig;
|
|
127
302
|
}
|
|
128
303
|
|
|
129
304
|
// ============= Configuration Manager Options =============
|
|
@@ -197,20 +372,23 @@ export type UserConfig<T extends BuenoConfig = BuenoConfig> = DeepPartial<T>;
|
|
|
197
372
|
/**
|
|
198
373
|
* User configuration function type
|
|
199
374
|
*/
|
|
200
|
-
export type UserConfigFn<T extends BuenoConfig = BuenoConfig> = (
|
|
375
|
+
export type UserConfigFn<T extends BuenoConfig = BuenoConfig> = (
|
|
376
|
+
env: string,
|
|
377
|
+
) => UserConfig<T> | Promise<UserConfig<T>>;
|
|
201
378
|
|
|
202
379
|
/**
|
|
203
380
|
* Configuration value type for a given key path
|
|
204
381
|
*/
|
|
205
|
-
export type ConfigValueForKey<TKey extends string> =
|
|
206
|
-
|
|
207
|
-
?
|
|
208
|
-
?
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
382
|
+
export type ConfigValueForKey<TKey extends string> =
|
|
383
|
+
TKey extends `${infer T}.${infer Rest}`
|
|
384
|
+
? T extends keyof BuenoConfig
|
|
385
|
+
? Rest extends string
|
|
386
|
+
? ConfigValueForKey<Rest>
|
|
387
|
+
: BuenoConfig[T]
|
|
388
|
+
: unknown
|
|
389
|
+
: TKey extends keyof BuenoConfig
|
|
390
|
+
? BuenoConfig[TKey]
|
|
391
|
+
: unknown;
|
|
214
392
|
|
|
215
393
|
// ============= Default Configuration =============
|
|
216
394
|
|
|
@@ -233,6 +411,75 @@ export const DEFAULT_CONFIG: Required<BuenoConfig> = {
|
|
|
233
411
|
keyPrefix: "",
|
|
234
412
|
enableMetrics: true,
|
|
235
413
|
},
|
|
414
|
+
jobs: {
|
|
415
|
+
enabled: false,
|
|
416
|
+
driver: "memory",
|
|
417
|
+
url: undefined,
|
|
418
|
+
keyPrefix: "jobs:",
|
|
419
|
+
concurrency: 10,
|
|
420
|
+
maxRetries: 3,
|
|
421
|
+
retryDelay: 1,
|
|
422
|
+
batchSize: 10,
|
|
423
|
+
pollInterval: 1000,
|
|
424
|
+
jobTimeout: 300000,
|
|
425
|
+
enableMetrics: true,
|
|
426
|
+
},
|
|
427
|
+
template: {
|
|
428
|
+
enabled: true,
|
|
429
|
+
basePath: "resources/templates",
|
|
430
|
+
cache: {
|
|
431
|
+
enabled: true,
|
|
432
|
+
ttl: 3600,
|
|
433
|
+
maxSize: 100,
|
|
434
|
+
},
|
|
435
|
+
watch: false,
|
|
436
|
+
defaultFormat: "html",
|
|
437
|
+
channelVariantMap: {
|
|
438
|
+
email: "email",
|
|
439
|
+
sms: "sms",
|
|
440
|
+
push: "push",
|
|
441
|
+
whatsapp: "whatsapp",
|
|
442
|
+
web: "web",
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
notification: {
|
|
446
|
+
enabled: false,
|
|
447
|
+
enableMetrics: true,
|
|
448
|
+
queue: false,
|
|
449
|
+
defaultChannel: "email",
|
|
450
|
+
email: {
|
|
451
|
+
enabled: true,
|
|
452
|
+
driver: "smtp",
|
|
453
|
+
from: "noreply@example.com",
|
|
454
|
+
fromName: "Bueno App",
|
|
455
|
+
dryRun: false,
|
|
456
|
+
},
|
|
457
|
+
sms: {
|
|
458
|
+
enabled: false,
|
|
459
|
+
driver: "twilio",
|
|
460
|
+
dryRun: false,
|
|
461
|
+
},
|
|
462
|
+
whatsapp: {
|
|
463
|
+
enabled: false,
|
|
464
|
+
driver: "twilio",
|
|
465
|
+
dryRun: false,
|
|
466
|
+
},
|
|
467
|
+
push: {
|
|
468
|
+
enabled: false,
|
|
469
|
+
driver: "firebase",
|
|
470
|
+
dryRun: false,
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
i18n: {
|
|
474
|
+
enabled: false,
|
|
475
|
+
defaultLocale: "en",
|
|
476
|
+
supportedLocales: ["en"],
|
|
477
|
+
basePath: "resources/i18n",
|
|
478
|
+
fallbackToDefault: true,
|
|
479
|
+
cookieName: "bueno_locale",
|
|
480
|
+
cookieMaxAge: 31536000,
|
|
481
|
+
watch: false,
|
|
482
|
+
},
|
|
236
483
|
logger: {
|
|
237
484
|
level: "info",
|
|
238
485
|
pretty: true,
|
|
@@ -274,47 +521,341 @@ export interface EnvMapping {
|
|
|
274
521
|
|
|
275
522
|
export const ENV_MAPPINGS: EnvMapping[] = [
|
|
276
523
|
// Server
|
|
277
|
-
{
|
|
524
|
+
{
|
|
525
|
+
envVar: "BUENO_PORT",
|
|
526
|
+
configKey: "server.port",
|
|
527
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
528
|
+
},
|
|
278
529
|
{ envVar: "BUENO_HOST", configKey: "server.host" },
|
|
279
|
-
{
|
|
280
|
-
|
|
530
|
+
{
|
|
531
|
+
envVar: "BUENO_DEV",
|
|
532
|
+
configKey: "server.development",
|
|
533
|
+
transform: (v) => v === "true",
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
envVar: "PORT",
|
|
537
|
+
configKey: "server.port",
|
|
538
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
539
|
+
},
|
|
281
540
|
{ envVar: "HOST", configKey: "server.host" },
|
|
282
541
|
|
|
283
542
|
// Database
|
|
284
543
|
{ envVar: "DATABASE_URL", configKey: "database.url" },
|
|
285
544
|
{ envVar: "BUENO_DATABASE_URL", configKey: "database.url" },
|
|
286
|
-
{
|
|
287
|
-
|
|
288
|
-
|
|
545
|
+
{
|
|
546
|
+
envVar: "BUENO_DB_POOL_SIZE",
|
|
547
|
+
configKey: "database.poolSize",
|
|
548
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
envVar: "BUENO_DB_METRICS",
|
|
552
|
+
configKey: "database.enableMetrics",
|
|
553
|
+
transform: (v) => v === "true",
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
envVar: "BUENO_DB_SLOW_QUERY",
|
|
557
|
+
configKey: "database.slowQueryThreshold",
|
|
558
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
559
|
+
},
|
|
289
560
|
|
|
290
561
|
// Cache
|
|
291
562
|
{ envVar: "REDIS_URL", configKey: "cache.url" },
|
|
292
563
|
{ envVar: "BUENO_REDIS_URL", configKey: "cache.url" },
|
|
293
564
|
{ envVar: "BUENO_CACHE_DRIVER", configKey: "cache.driver" },
|
|
294
|
-
{
|
|
565
|
+
{
|
|
566
|
+
envVar: "BUENO_CACHE_TTL",
|
|
567
|
+
configKey: "cache.ttl",
|
|
568
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
569
|
+
},
|
|
295
570
|
{ envVar: "BUENO_CACHE_PREFIX", configKey: "cache.keyPrefix" },
|
|
296
571
|
|
|
572
|
+
// Jobs
|
|
573
|
+
{
|
|
574
|
+
envVar: "BUENO_JOBS_ENABLED",
|
|
575
|
+
configKey: "jobs.enabled",
|
|
576
|
+
transform: (v) => v === "true",
|
|
577
|
+
},
|
|
578
|
+
{ envVar: "BUENO_JOBS_DRIVER", configKey: "jobs.driver" },
|
|
579
|
+
{ envVar: "BUENO_JOBS_URL", configKey: "jobs.url" },
|
|
580
|
+
{
|
|
581
|
+
envVar: "BUENO_JOBS_CONCURRENCY",
|
|
582
|
+
configKey: "jobs.concurrency",
|
|
583
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
envVar: "BUENO_JOBS_MAX_RETRIES",
|
|
587
|
+
configKey: "jobs.maxRetries",
|
|
588
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
envVar: "BUENO_JOBS_RETRY_DELAY",
|
|
592
|
+
configKey: "jobs.retryDelay",
|
|
593
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
envVar: "BUENO_JOBS_BATCH_SIZE",
|
|
597
|
+
configKey: "jobs.batchSize",
|
|
598
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
envVar: "BUENO_JOBS_POLL_INTERVAL",
|
|
602
|
+
configKey: "jobs.pollInterval",
|
|
603
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
envVar: "BUENO_JOBS_TIMEOUT",
|
|
607
|
+
configKey: "jobs.jobTimeout",
|
|
608
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
609
|
+
},
|
|
610
|
+
|
|
611
|
+
// Template
|
|
612
|
+
{
|
|
613
|
+
envVar: "BUENO_TEMPLATE_ENABLED",
|
|
614
|
+
configKey: "template.enabled",
|
|
615
|
+
transform: (v) => v === "true",
|
|
616
|
+
},
|
|
617
|
+
{ envVar: "BUENO_TEMPLATE_BASE_PATH", configKey: "template.basePath" },
|
|
618
|
+
{
|
|
619
|
+
envVar: "BUENO_TEMPLATE_CACHE_ENABLED",
|
|
620
|
+
configKey: "template.cache.enabled",
|
|
621
|
+
transform: (v) => v === "true",
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
envVar: "BUENO_TEMPLATE_CACHE_TTL",
|
|
625
|
+
configKey: "template.cache.ttl",
|
|
626
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
envVar: "BUENO_TEMPLATE_CACHE_MAX_SIZE",
|
|
630
|
+
configKey: "template.cache.maxSize",
|
|
631
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
envVar: "BUENO_TEMPLATE_WATCH",
|
|
635
|
+
configKey: "template.watch",
|
|
636
|
+
transform: (v) => v === "true",
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
envVar: "BUENO_TEMPLATE_DEFAULT_FORMAT",
|
|
640
|
+
configKey: "template.defaultFormat",
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
// Notification
|
|
644
|
+
{
|
|
645
|
+
envVar: "BUENO_NOTIFICATION_ENABLED",
|
|
646
|
+
configKey: "notification.enabled",
|
|
647
|
+
transform: (v) => v === "true",
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
envVar: "BUENO_NOTIFICATION_METRICS",
|
|
651
|
+
configKey: "notification.enableMetrics",
|
|
652
|
+
transform: (v) => v === "true",
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
envVar: "BUENO_NOTIFICATION_QUEUE",
|
|
656
|
+
configKey: "notification.queue",
|
|
657
|
+
transform: (v) => v === "true",
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
envVar: "BUENO_NOTIFICATION_DEFAULT",
|
|
661
|
+
configKey: "notification.defaultChannel",
|
|
662
|
+
},
|
|
663
|
+
|
|
664
|
+
// Email Channel
|
|
665
|
+
{
|
|
666
|
+
envVar: "BUENO_EMAIL_ENABLED",
|
|
667
|
+
configKey: "notification.email.enabled",
|
|
668
|
+
transform: (v) => v === "true",
|
|
669
|
+
},
|
|
670
|
+
{ envVar: "BUENO_EMAIL_DRIVER", configKey: "notification.email.driver" },
|
|
671
|
+
{ envVar: "BUENO_EMAIL_FROM", configKey: "notification.email.from" },
|
|
672
|
+
{ envVar: "BUENO_EMAIL_FROM_NAME", configKey: "notification.email.fromName" },
|
|
673
|
+
{ envVar: "BUENO_EMAIL_API_KEY", configKey: "notification.email.apiKey" },
|
|
674
|
+
{
|
|
675
|
+
envVar: "BUENO_EMAIL_DRY_RUN",
|
|
676
|
+
configKey: "notification.email.dryRun",
|
|
677
|
+
transform: (v) => v === "true",
|
|
678
|
+
},
|
|
679
|
+
{ envVar: "BUENO_SMTP_HOST", configKey: "notification.email.smtp.host" },
|
|
680
|
+
{
|
|
681
|
+
envVar: "BUENO_SMTP_PORT",
|
|
682
|
+
configKey: "notification.email.smtp.port",
|
|
683
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
684
|
+
},
|
|
685
|
+
{ envVar: "BUENO_SMTP_USER", configKey: "notification.email.smtp.username" },
|
|
686
|
+
{
|
|
687
|
+
envVar: "BUENO_SMTP_PASSWORD",
|
|
688
|
+
configKey: "notification.email.smtp.password",
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
envVar: "BUENO_SMTP_SECURE",
|
|
692
|
+
configKey: "notification.email.smtp.secure",
|
|
693
|
+
transform: (v) => v === "true",
|
|
694
|
+
},
|
|
695
|
+
|
|
696
|
+
// SMS Channel
|
|
697
|
+
{
|
|
698
|
+
envVar: "BUENO_SMS_ENABLED",
|
|
699
|
+
configKey: "notification.sms.enabled",
|
|
700
|
+
transform: (v) => v === "true",
|
|
701
|
+
},
|
|
702
|
+
{ envVar: "BUENO_SMS_DRIVER", configKey: "notification.sms.driver" },
|
|
703
|
+
{
|
|
704
|
+
envVar: "BUENO_SMS_DRY_RUN",
|
|
705
|
+
configKey: "notification.sms.dryRun",
|
|
706
|
+
transform: (v) => v === "true",
|
|
707
|
+
},
|
|
708
|
+
{ envVar: "BUENO_SMS_ACCOUNT_SID", configKey: "notification.sms.accountSid" },
|
|
709
|
+
{ envVar: "BUENO_SMS_AUTH_TOKEN", configKey: "notification.sms.authToken" },
|
|
710
|
+
{ envVar: "BUENO_SMS_FROM_NUMBER", configKey: "notification.sms.fromNumber" },
|
|
711
|
+
|
|
712
|
+
// WhatsApp Channel
|
|
713
|
+
{
|
|
714
|
+
envVar: "BUENO_WHATSAPP_ENABLED",
|
|
715
|
+
configKey: "notification.whatsapp.enabled",
|
|
716
|
+
transform: (v) => v === "true",
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
envVar: "BUENO_WHATSAPP_DRIVER",
|
|
720
|
+
configKey: "notification.whatsapp.driver",
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
envVar: "BUENO_WHATSAPP_DRY_RUN",
|
|
724
|
+
configKey: "notification.whatsapp.dryRun",
|
|
725
|
+
transform: (v) => v === "true",
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
envVar: "BUENO_WHATSAPP_ACCOUNT_SID",
|
|
729
|
+
configKey: "notification.whatsapp.accountSid",
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
envVar: "BUENO_WHATSAPP_AUTH_TOKEN",
|
|
733
|
+
configKey: "notification.whatsapp.authToken",
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
envVar: "BUENO_WHATSAPP_BUSINESS_PHONE",
|
|
737
|
+
configKey: "notification.whatsapp.businessPhoneNumber",
|
|
738
|
+
},
|
|
739
|
+
|
|
740
|
+
// Push Channel
|
|
741
|
+
{
|
|
742
|
+
envVar: "BUENO_PUSH_ENABLED",
|
|
743
|
+
configKey: "notification.push.enabled",
|
|
744
|
+
transform: (v) => v === "true",
|
|
745
|
+
},
|
|
746
|
+
{ envVar: "BUENO_PUSH_DRIVER", configKey: "notification.push.driver" },
|
|
747
|
+
{
|
|
748
|
+
envVar: "BUENO_PUSH_DRY_RUN",
|
|
749
|
+
configKey: "notification.push.dryRun",
|
|
750
|
+
transform: (v) => v === "true",
|
|
751
|
+
},
|
|
752
|
+
{ envVar: "BUENO_PUSH_SERVER_KEY", configKey: "notification.push.serverKey" },
|
|
753
|
+
{
|
|
754
|
+
envVar: "BUENO_PUSH_CERTIFICATE_PATH",
|
|
755
|
+
configKey: "notification.push.certificatePath",
|
|
756
|
+
},
|
|
757
|
+
|
|
758
|
+
// i18n
|
|
759
|
+
{
|
|
760
|
+
envVar: "BUENO_I18N_ENABLED",
|
|
761
|
+
configKey: "i18n.enabled",
|
|
762
|
+
transform: (v) => v === "true",
|
|
763
|
+
},
|
|
764
|
+
{ envVar: "BUENO_I18N_DEFAULT_LOCALE", configKey: "i18n.defaultLocale" },
|
|
765
|
+
{
|
|
766
|
+
envVar: "BUENO_I18N_SUPPORTED_LOCALES",
|
|
767
|
+
configKey: "i18n.supportedLocales",
|
|
768
|
+
transform: (v) => v.split(",").map((s) => s.trim()),
|
|
769
|
+
},
|
|
770
|
+
{ envVar: "BUENO_I18N_BASE_PATH", configKey: "i18n.basePath" },
|
|
771
|
+
{
|
|
772
|
+
envVar: "BUENO_I18N_FALLBACK",
|
|
773
|
+
configKey: "i18n.fallbackToDefault",
|
|
774
|
+
transform: (v) => v === "true",
|
|
775
|
+
},
|
|
776
|
+
{ envVar: "BUENO_I18N_COOKIE_NAME", configKey: "i18n.cookieName" },
|
|
777
|
+
{
|
|
778
|
+
envVar: "BUENO_I18N_COOKIE_MAX_AGE",
|
|
779
|
+
configKey: "i18n.cookieMaxAge",
|
|
780
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
envVar: "BUENO_I18N_WATCH",
|
|
784
|
+
configKey: "i18n.watch",
|
|
785
|
+
transform: (v) => v === "true",
|
|
786
|
+
},
|
|
787
|
+
|
|
297
788
|
// Logger
|
|
298
789
|
{ envVar: "LOG_LEVEL", configKey: "logger.level" },
|
|
299
790
|
{ envVar: "BUENO_LOG_LEVEL", configKey: "logger.level" },
|
|
300
|
-
{
|
|
791
|
+
{
|
|
792
|
+
envVar: "BUENO_LOG_PRETTY",
|
|
793
|
+
configKey: "logger.pretty",
|
|
794
|
+
transform: (v) => v === "true",
|
|
795
|
+
},
|
|
301
796
|
|
|
302
797
|
// Health
|
|
303
|
-
{
|
|
798
|
+
{
|
|
799
|
+
envVar: "BUENO_HEALTH_ENABLED",
|
|
800
|
+
configKey: "health.enabled",
|
|
801
|
+
transform: (v) => v === "true",
|
|
802
|
+
},
|
|
304
803
|
{ envVar: "BUENO_HEALTH_PATH", configKey: "health.healthPath" },
|
|
305
804
|
{ envVar: "BUENO_READY_PATH", configKey: "health.readyPath" },
|
|
306
805
|
|
|
307
806
|
// Metrics
|
|
308
|
-
{
|
|
309
|
-
|
|
807
|
+
{
|
|
808
|
+
envVar: "BUENO_METRICS_ENABLED",
|
|
809
|
+
configKey: "metrics.enabled",
|
|
810
|
+
transform: (v) => v === "true",
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
envVar: "BUENO_METRICS_INTERVAL",
|
|
814
|
+
configKey: "metrics.collectInterval",
|
|
815
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
816
|
+
},
|
|
310
817
|
|
|
311
818
|
// Telemetry
|
|
312
|
-
{
|
|
819
|
+
{
|
|
820
|
+
envVar: "BUENO_TELEMETRY_ENABLED",
|
|
821
|
+
configKey: "telemetry.enabled",
|
|
822
|
+
transform: (v) => v === "true",
|
|
823
|
+
},
|
|
313
824
|
{ envVar: "BUENO_SERVICE_NAME", configKey: "telemetry.serviceName" },
|
|
314
825
|
{ envVar: "BUENO_OTEL_ENDPOINT", configKey: "telemetry.endpoint" },
|
|
315
826
|
{ envVar: "OTEL_EXPORTER_OTLP_ENDPOINT", configKey: "telemetry.endpoint" },
|
|
316
827
|
|
|
828
|
+
// Observability
|
|
829
|
+
{
|
|
830
|
+
envVar: "BUENO_OBSERVABILITY_ENABLED",
|
|
831
|
+
configKey: "observability.enabled",
|
|
832
|
+
transform: (v) => v === "true",
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
envVar: "BUENO_OBSERVABILITY_BREADCRUMBS_SIZE",
|
|
836
|
+
configKey: "observability.breadcrumbsSize",
|
|
837
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
envVar: "BUENO_OBSERVABILITY_IGNORE_STATUS_CODES",
|
|
841
|
+
configKey: "observability.ignoreStatusCodes",
|
|
842
|
+
transform: (v) =>
|
|
843
|
+
v
|
|
844
|
+
.split(",")
|
|
845
|
+
.map((s) => s.trim())
|
|
846
|
+
.filter(Boolean)
|
|
847
|
+
.map((s) => Number.parseInt(s, 10)),
|
|
848
|
+
},
|
|
849
|
+
|
|
317
850
|
// Frontend
|
|
318
|
-
{
|
|
319
|
-
|
|
320
|
-
|
|
851
|
+
{
|
|
852
|
+
envVar: "BUENO_FRONTEND_PORT",
|
|
853
|
+
configKey: "frontend.port",
|
|
854
|
+
transform: (v) => Number.parseInt(v, 10),
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
envVar: "BUENO_HMR",
|
|
858
|
+
configKey: "frontend.hmr",
|
|
859
|
+
transform: (v) => v === "true",
|
|
860
|
+
},
|
|
861
|
+
];
|