@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.
Files changed (218) hide show
  1. package/README.md +136 -16
  2. package/dist/cli/{index.js → bin.js} +412 -331
  3. package/dist/container/index.js +250 -0
  4. package/dist/context/index.js +219 -0
  5. package/dist/database/index.js +493 -0
  6. package/dist/frontend/index.js +7697 -0
  7. package/dist/health/index.js +364 -0
  8. package/dist/i18n/index.js +345 -0
  9. package/dist/index.js +11043 -6482
  10. package/dist/jobs/index.js +819 -0
  11. package/dist/lock/index.js +367 -0
  12. package/dist/logger/index.js +281 -0
  13. package/dist/metrics/index.js +289 -0
  14. package/dist/middleware/index.js +77 -0
  15. package/dist/migrations/index.js +571 -0
  16. package/dist/modules/index.js +3346 -0
  17. package/dist/notification/index.js +484 -0
  18. package/dist/observability/index.js +331 -0
  19. package/dist/openapi/index.js +776 -0
  20. package/dist/orm/index.js +1356 -0
  21. package/dist/router/index.js +886 -0
  22. package/dist/rpc/index.js +691 -0
  23. package/dist/schema/index.js +400 -0
  24. package/dist/telemetry/index.js +595 -0
  25. package/dist/template/index.js +640 -0
  26. package/dist/templates/index.js +640 -0
  27. package/dist/testing/index.js +1111 -0
  28. package/dist/types/index.js +60 -0
  29. package/package.json +121 -27
  30. package/src/cache/index.ts +2 -1
  31. package/src/cli/bin.ts +2 -2
  32. package/src/cli/commands/build.ts +183 -165
  33. package/src/cli/commands/dev.ts +96 -89
  34. package/src/cli/commands/generate.ts +142 -111
  35. package/src/cli/commands/help.ts +20 -16
  36. package/src/cli/commands/index.ts +3 -6
  37. package/src/cli/commands/migration.ts +124 -105
  38. package/src/cli/commands/new.ts +294 -232
  39. package/src/cli/commands/start.ts +81 -79
  40. package/src/cli/core/args.ts +68 -50
  41. package/src/cli/core/console.ts +89 -95
  42. package/src/cli/core/index.ts +4 -4
  43. package/src/cli/core/prompt.ts +65 -62
  44. package/src/cli/core/spinner.ts +23 -20
  45. package/src/cli/index.ts +46 -38
  46. package/src/cli/templates/database/index.ts +37 -18
  47. package/src/cli/templates/database/mysql.ts +3 -3
  48. package/src/cli/templates/database/none.ts +2 -2
  49. package/src/cli/templates/database/postgresql.ts +3 -3
  50. package/src/cli/templates/database/sqlite.ts +3 -3
  51. package/src/cli/templates/deploy.ts +29 -26
  52. package/src/cli/templates/docker.ts +41 -30
  53. package/src/cli/templates/frontend/index.ts +33 -15
  54. package/src/cli/templates/frontend/none.ts +2 -2
  55. package/src/cli/templates/frontend/react.ts +18 -18
  56. package/src/cli/templates/frontend/solid.ts +15 -15
  57. package/src/cli/templates/frontend/svelte.ts +17 -17
  58. package/src/cli/templates/frontend/vue.ts +15 -15
  59. package/src/cli/templates/generators/index.ts +29 -29
  60. package/src/cli/templates/generators/types.ts +21 -21
  61. package/src/cli/templates/index.ts +6 -6
  62. package/src/cli/templates/project/api.ts +37 -36
  63. package/src/cli/templates/project/default.ts +25 -25
  64. package/src/cli/templates/project/fullstack.ts +28 -26
  65. package/src/cli/templates/project/index.ts +55 -16
  66. package/src/cli/templates/project/minimal.ts +17 -12
  67. package/src/cli/templates/project/types.ts +10 -5
  68. package/src/cli/templates/project/website.ts +14 -14
  69. package/src/cli/utils/fs.ts +55 -41
  70. package/src/cli/utils/index.ts +3 -3
  71. package/src/cli/utils/strings.ts +47 -33
  72. package/src/cli/utils/version.ts +14 -8
  73. package/src/config/env-validation.ts +100 -0
  74. package/src/config/env.ts +169 -41
  75. package/src/config/index.ts +28 -20
  76. package/src/config/loader.ts +25 -16
  77. package/src/config/merge.ts +21 -10
  78. package/src/config/types.ts +545 -25
  79. package/src/config/validation.ts +215 -7
  80. package/src/container/forward-ref.ts +22 -22
  81. package/src/container/index.ts +34 -12
  82. package/src/context/index.ts +11 -1
  83. package/src/database/index.ts +7 -190
  84. package/src/database/orm/builder.ts +457 -0
  85. package/src/database/orm/casts/index.ts +130 -0
  86. package/src/database/orm/casts/types.ts +25 -0
  87. package/src/database/orm/compiler.ts +304 -0
  88. package/src/database/orm/hooks/index.ts +114 -0
  89. package/src/database/orm/index.ts +61 -0
  90. package/src/database/orm/model-registry.ts +59 -0
  91. package/src/database/orm/model.ts +821 -0
  92. package/src/database/orm/relationships/base.ts +146 -0
  93. package/src/database/orm/relationships/belongs-to-many.ts +179 -0
  94. package/src/database/orm/relationships/belongs-to.ts +56 -0
  95. package/src/database/orm/relationships/has-many.ts +45 -0
  96. package/src/database/orm/relationships/has-one.ts +41 -0
  97. package/src/database/orm/relationships/index.ts +11 -0
  98. package/src/database/orm/scopes/index.ts +55 -0
  99. package/src/events/__tests__/event-system.test.ts +235 -0
  100. package/src/events/config.ts +238 -0
  101. package/src/events/example-usage.ts +185 -0
  102. package/src/events/index.ts +278 -0
  103. package/src/events/manager.ts +385 -0
  104. package/src/events/registry.ts +182 -0
  105. package/src/events/types.ts +124 -0
  106. package/src/frontend/api-routes.ts +65 -23
  107. package/src/frontend/bundler.ts +76 -34
  108. package/src/frontend/console-client.ts +2 -2
  109. package/src/frontend/console-stream.ts +94 -38
  110. package/src/frontend/dev-server.ts +94 -46
  111. package/src/frontend/file-router.ts +61 -19
  112. package/src/frontend/frameworks/index.ts +37 -10
  113. package/src/frontend/frameworks/react.ts +10 -8
  114. package/src/frontend/frameworks/solid.ts +11 -9
  115. package/src/frontend/frameworks/svelte.ts +15 -9
  116. package/src/frontend/frameworks/vue.ts +13 -11
  117. package/src/frontend/hmr-client.ts +12 -10
  118. package/src/frontend/hmr.ts +146 -103
  119. package/src/frontend/index.ts +14 -5
  120. package/src/frontend/islands.ts +41 -22
  121. package/src/frontend/isr.ts +59 -37
  122. package/src/frontend/layout.ts +36 -21
  123. package/src/frontend/ssr/react.ts +74 -27
  124. package/src/frontend/ssr/solid.ts +54 -20
  125. package/src/frontend/ssr/svelte.ts +48 -14
  126. package/src/frontend/ssr/vue.ts +50 -18
  127. package/src/frontend/ssr.ts +83 -39
  128. package/src/frontend/types.ts +91 -56
  129. package/src/health/index.ts +21 -9
  130. package/src/i18n/engine.ts +305 -0
  131. package/src/i18n/index.ts +38 -0
  132. package/src/i18n/loader.ts +218 -0
  133. package/src/i18n/middleware.ts +164 -0
  134. package/src/i18n/negotiator.ts +162 -0
  135. package/src/i18n/types.ts +158 -0
  136. package/src/index.ts +179 -27
  137. package/src/jobs/drivers/memory.ts +315 -0
  138. package/src/jobs/drivers/redis.ts +459 -0
  139. package/src/jobs/index.ts +30 -0
  140. package/src/jobs/queue.ts +281 -0
  141. package/src/jobs/types.ts +295 -0
  142. package/src/jobs/worker.ts +380 -0
  143. package/src/logger/index.ts +1 -3
  144. package/src/logger/transports/index.ts +62 -22
  145. package/src/metrics/index.ts +25 -16
  146. package/src/migrations/index.ts +9 -0
  147. package/src/modules/filters.ts +13 -17
  148. package/src/modules/guards.ts +49 -26
  149. package/src/modules/index.ts +409 -298
  150. package/src/modules/interceptors.ts +58 -20
  151. package/src/modules/lazy.ts +11 -19
  152. package/src/modules/lifecycle.ts +15 -7
  153. package/src/modules/metadata.ts +15 -5
  154. package/src/modules/pipes.ts +94 -72
  155. package/src/notification/channels/base.ts +68 -0
  156. package/src/notification/channels/email.ts +105 -0
  157. package/src/notification/channels/push.ts +104 -0
  158. package/src/notification/channels/sms.ts +105 -0
  159. package/src/notification/channels/whatsapp.ts +104 -0
  160. package/src/notification/index.ts +48 -0
  161. package/src/notification/service.ts +354 -0
  162. package/src/notification/types.ts +344 -0
  163. package/src/observability/__tests__/observability.test.ts +483 -0
  164. package/src/observability/breadcrumbs.ts +114 -0
  165. package/src/observability/index.ts +136 -0
  166. package/src/observability/interceptor.ts +85 -0
  167. package/src/observability/service.ts +303 -0
  168. package/src/observability/trace.ts +37 -0
  169. package/src/observability/types.ts +196 -0
  170. package/src/openapi/__tests__/decorators.test.ts +335 -0
  171. package/src/openapi/__tests__/document-builder.test.ts +285 -0
  172. package/src/openapi/__tests__/route-scanner.test.ts +334 -0
  173. package/src/openapi/__tests__/schema-generator.test.ts +275 -0
  174. package/src/openapi/decorators.ts +328 -0
  175. package/src/openapi/document-builder.ts +274 -0
  176. package/src/openapi/index.ts +112 -0
  177. package/src/openapi/metadata.ts +112 -0
  178. package/src/openapi/route-scanner.ts +289 -0
  179. package/src/openapi/schema-generator.ts +256 -0
  180. package/src/openapi/swagger-module.ts +166 -0
  181. package/src/openapi/types.ts +398 -0
  182. package/src/orm/index.ts +10 -0
  183. package/src/rpc/index.ts +3 -1
  184. package/src/schema/index.ts +9 -0
  185. package/src/security/index.ts +15 -6
  186. package/src/ssg/index.ts +9 -8
  187. package/src/telemetry/index.ts +76 -22
  188. package/src/template/index.ts +7 -0
  189. package/src/templates/engine.ts +224 -0
  190. package/src/templates/index.ts +9 -0
  191. package/src/templates/loader.ts +331 -0
  192. package/src/templates/renderers/markdown.ts +212 -0
  193. package/src/templates/renderers/simple.ts +269 -0
  194. package/src/templates/types.ts +154 -0
  195. package/src/testing/index.ts +100 -27
  196. package/src/types/optional-deps.d.ts +347 -187
  197. package/src/validation/index.ts +92 -2
  198. package/src/validation/schemas.ts +536 -0
  199. package/tests/integration/fullstack.test.ts +4 -4
  200. package/tests/unit/database.test.ts +2 -72
  201. package/tests/unit/env-validation.test.ts +166 -0
  202. package/tests/unit/events.test.ts +910 -0
  203. package/tests/unit/i18n.test.ts +455 -0
  204. package/tests/unit/jobs.test.ts +493 -0
  205. package/tests/unit/notification.test.ts +988 -0
  206. package/tests/unit/observability.test.ts +453 -0
  207. package/tests/unit/orm/builder.test.ts +323 -0
  208. package/tests/unit/orm/casts.test.ts +179 -0
  209. package/tests/unit/orm/compiler.test.ts +220 -0
  210. package/tests/unit/orm/eager-loading.test.ts +285 -0
  211. package/tests/unit/orm/hooks.test.ts +191 -0
  212. package/tests/unit/orm/model.test.ts +373 -0
  213. package/tests/unit/orm/relationships.test.ts +303 -0
  214. package/tests/unit/orm/scopes.test.ts +74 -0
  215. package/tests/unit/templates-simple.test.ts +53 -0
  216. package/tests/unit/templates.test.ts +454 -0
  217. package/tests/unit/validation.test.ts +18 -24
  218. package/tsconfig.json +11 -3
@@ -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> = (env: string) => UserConfig<T> | Promise<UserConfig<T>>;
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> = TKey extends `${infer T}.${infer Rest}`
206
- ? T extends keyof BuenoConfig
207
- ? Rest extends string
208
- ? ConfigValueForKey<Rest>
209
- : BuenoConfig[T]
210
- : unknown
211
- : TKey extends keyof BuenoConfig
212
- ? BuenoConfig[TKey]
213
- : unknown;
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
- { envVar: "BUENO_PORT", configKey: "server.port", transform: (v) => parseInt(v, 10) },
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
- { envVar: "BUENO_DEV", configKey: "server.development", transform: (v) => v === "true" },
280
- { envVar: "PORT", configKey: "server.port", transform: (v) => parseInt(v, 10) },
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
- { envVar: "BUENO_DB_POOL_SIZE", configKey: "database.poolSize", transform: (v) => parseInt(v, 10) },
287
- { envVar: "BUENO_DB_METRICS", configKey: "database.enableMetrics", transform: (v) => v === "true" },
288
- { envVar: "BUENO_DB_SLOW_QUERY", configKey: "database.slowQueryThreshold", transform: (v) => parseInt(v, 10) },
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
- { envVar: "BUENO_CACHE_TTL", configKey: "cache.ttl", transform: (v) => parseInt(v, 10) },
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
- { envVar: "BUENO_LOG_PRETTY", configKey: "logger.pretty", transform: (v) => v === "true" },
770
+ {
771
+ envVar: "BUENO_LOG_PRETTY",
772
+ configKey: "logger.pretty",
773
+ transform: (v) => v === "true",
774
+ },
301
775
 
302
776
  // Health
303
- { envVar: "BUENO_HEALTH_ENABLED", configKey: "health.enabled", transform: (v) => v === "true" },
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
- { envVar: "BUENO_METRICS_ENABLED", configKey: "metrics.enabled", transform: (v) => v === "true" },
309
- { envVar: "BUENO_METRICS_INTERVAL", configKey: "metrics.collectInterval", transform: (v) => parseInt(v, 10) },
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
- { envVar: "BUENO_TELEMETRY_ENABLED", configKey: "telemetry.enabled", transform: (v) => v === "true" },
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
- { envVar: "BUENO_FRONTEND_PORT", configKey: "frontend.port", transform: (v) => parseInt(v, 10) },
319
- { envVar: "BUENO_HMR", configKey: "frontend.hmr", transform: (v) => v === "true" },
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
+ ];