@buenojs/bueno 0.8.3 → 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} +3036 -1421
  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 +392 -438
  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 +61 -0
  47. package/src/cli/templates/database/mysql.ts +14 -0
  48. package/src/cli/templates/database/none.ts +16 -0
  49. package/src/cli/templates/database/postgresql.ts +14 -0
  50. package/src/cli/templates/database/sqlite.ts +14 -0
  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 +63 -0
  54. package/src/cli/templates/frontend/none.ts +17 -0
  55. package/src/cli/templates/frontend/react.ts +140 -0
  56. package/src/cli/templates/frontend/solid.ts +134 -0
  57. package/src/cli/templates/frontend/svelte.ts +131 -0
  58. package/src/cli/templates/frontend/vue.ts +130 -0
  59. package/src/cli/templates/generators/index.ts +339 -0
  60. package/src/cli/templates/generators/types.ts +56 -0
  61. package/src/cli/templates/index.ts +35 -2
  62. package/src/cli/templates/project/api.ts +81 -0
  63. package/src/cli/templates/project/default.ts +140 -0
  64. package/src/cli/templates/project/fullstack.ts +111 -0
  65. package/src/cli/templates/project/index.ts +95 -0
  66. package/src/cli/templates/project/minimal.ts +45 -0
  67. package/src/cli/templates/project/types.ts +94 -0
  68. package/src/cli/templates/project/website.ts +263 -0
  69. package/src/cli/utils/fs.ts +55 -41
  70. package/src/cli/utils/index.ts +3 -2
  71. package/src/cli/utils/strings.ts +47 -33
  72. package/src/cli/utils/version.ts +47 -0
  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
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Bueno Migrations
3
+ *
4
+ * Database migration runner, builder, and helpers.
5
+ *
6
+ * @example
7
+ * import { createMigration, type MigrationRunner } from '@buenojs/bueno/migrations';
8
+ */
9
+ export * from "../database/migrations";
@@ -11,7 +11,7 @@
11
11
 
12
12
  import type { Context } from "../context";
13
13
  import type { Token } from "../types";
14
- import { BuenoError, ValidationError, NotFoundError } from "../types";
14
+ import { BuenoError, NotFoundError, ValidationError } from "../types";
15
15
 
16
16
  // ============= Types =============
17
17
 
@@ -69,10 +69,7 @@ function setFilterMetadata(
69
69
  filterMetadataStore.get(target)?.set(key, value);
70
70
  }
71
71
 
72
- function getFilterMetadata<T>(
73
- target: Constructor,
74
- key: string,
75
- ): T | undefined {
72
+ function getFilterMetadata<T>(target: Constructor, key: string): T | undefined {
76
73
  return filterMetadataStore.get(target)?.get(key) as T | undefined;
77
74
  }
78
75
 
@@ -114,7 +111,9 @@ function getFilterPrototypeMetadata<T>(
114
111
  * }
115
112
  * ```
116
113
  */
117
- export function UseFilters(...filters: Filter[]): MethodDecorator & ClassDecorator {
114
+ export function UseFilters(
115
+ ...filters: Filter[]
116
+ ): MethodDecorator & ClassDecorator {
118
117
  const decorator = (
119
118
  target: unknown,
120
119
  propertyKey?: string | symbol,
@@ -168,7 +167,11 @@ export function Catch<T extends Error>(
168
167
  exceptionType: new (...args: never[]) => T,
169
168
  ): ClassDecorator {
170
169
  const decorator = (target: Constructor): void => {
171
- catchMetadataStore.set(target, { exceptionType: exceptionType as unknown as new (...args: unknown[]) => Error });
170
+ catchMetadataStore.set(target, {
171
+ exceptionType: exceptionType as unknown as new (
172
+ ...args: unknown[]
173
+ ) => Error,
174
+ });
172
175
  };
173
176
  return decorator as ClassDecorator;
174
177
  }
@@ -224,10 +227,7 @@ export function getCatchType(
224
227
  /**
225
228
  * Check if a filter can handle a specific exception
226
229
  */
227
- export function canHandleException(
228
- filter: Filter,
229
- exception: Error,
230
- ): boolean {
230
+ export function canHandleException(filter: Filter, exception: Error): boolean {
231
231
  const catchType = getCatchType(filter);
232
232
  if (!catchType) {
233
233
  // No specific catch type means it handles all exceptions
@@ -327,11 +327,7 @@ export async function findAndExecuteFilter(
327
327
  const { globalFilters, classFilters, methodFilters, resolveFilter } = options;
328
328
 
329
329
  // Combine all filters in execution order (method first, then class, then global)
330
- const allFilters = [
331
- ...methodFilters,
332
- ...classFilters,
333
- ...globalFilters,
334
- ];
330
+ const allFilters = [...methodFilters, ...classFilters, ...globalFilters];
335
331
 
336
332
  // Find the first filter that can handle this exception type
337
333
  for (const filter of allFilters) {
@@ -455,4 +451,4 @@ export function createInternalErrorResponse(exception: Error): Response {
455
451
  },
456
452
  },
457
453
  );
458
- }
454
+ }
@@ -3,21 +3,21 @@
3
3
  *
4
4
  * Guards determine whether a request should be allowed to proceed to the handler.
5
5
  * They run before interceptors and pipes in the request pipeline.
6
- *
6
+ *
7
7
  * Execution Order:
8
8
  * Incoming Request → Guards → Interceptors → Pipes → Handler
9
- *
9
+ *
10
10
  * If any guard returns false, the request is rejected with 403 Forbidden.
11
11
  */
12
12
 
13
- import type { Context } from "../context";
14
13
  import type { Token } from "../container";
14
+ import type { Context } from "../context";
15
15
 
16
16
  // ============= Types =============
17
17
 
18
18
  /**
19
19
  * Guard interface for authorization checks
20
- *
20
+ *
21
21
  * @example
22
22
  * ```typescript
23
23
  * @Injectable()
@@ -34,7 +34,7 @@ export interface CanActivate {
34
34
 
35
35
  /**
36
36
  * Guard function type (for functional guards)
37
- *
37
+ *
38
38
  * @example
39
39
  * ```typescript
40
40
  * const authGuard: GuardFn = (context) => {
@@ -66,7 +66,10 @@ type Constructor = new (...args: unknown[]) => unknown;
66
66
  const guardsClassMetadata = new WeakMap<Constructor, Guard[]>();
67
67
 
68
68
  // WeakMap for storing guards metadata on method prototypes
69
- const guardsMethodMetadata = new WeakMap<object, Map<string | symbol, Guard[]>>();
69
+ const guardsMethodMetadata = new WeakMap<
70
+ object,
71
+ Map<string | symbol, Guard[]>
72
+ >();
70
73
 
71
74
  /**
72
75
  * Set guards on a class constructor
@@ -130,7 +133,9 @@ export function getMethodGuards(
130
133
  * }
131
134
  * ```
132
135
  */
133
- export function UseGuards(...guards: Guard[]): MethodDecorator & ClassDecorator {
136
+ export function UseGuards(
137
+ ...guards: Guard[]
138
+ ): MethodDecorator & ClassDecorator {
134
139
  const decorator = (
135
140
  target: unknown,
136
141
  propertyKey?: string | symbol,
@@ -183,7 +188,10 @@ export class AuthGuard implements CanActivate {
183
188
  const ROLES_METADATA_KEY = "roles";
184
189
 
185
190
  // WeakMap for storing roles metadata on method prototypes
186
- const rolesMethodMetadata = new WeakMap<object, Map<string | symbol, string[]>>();
191
+ const rolesMethodMetadata = new WeakMap<
192
+ object,
193
+ Map<string | symbol, string[]>
194
+ >();
187
195
 
188
196
  /**
189
197
  * Set required roles on a method
@@ -212,10 +220,10 @@ export function getMethodRoles(
212
220
  /**
213
221
  * Decorator to specify required roles for a route
214
222
  * Must be used in conjunction with RolesGuard
215
- *
223
+ *
216
224
  * @param roles - Required roles
217
225
  * @returns MethodDecorator
218
- *
226
+ *
219
227
  * @example
220
228
  * ```typescript
221
229
  * @Controller('admin')
@@ -281,7 +289,8 @@ declare module "../context" {
281
289
  export class RolesGuard implements CanActivate {
282
290
  canActivate(context: Context): boolean {
283
291
  // Get required roles from context (set by the framework during route matching)
284
- const requiredRoles = (context as unknown as { requiredRoles?: string[] }).requiredRoles;
292
+ const requiredRoles = (context as unknown as { requiredRoles?: string[] })
293
+ .requiredRoles;
285
294
 
286
295
  // If no roles are required, allow access
287
296
  if (!requiredRoles || requiredRoles.length === 0) {
@@ -316,7 +325,7 @@ export interface GuardExecutorOptions {
316
325
 
317
326
  /**
318
327
  * Execute guards in order and return whether the request should proceed
319
- *
328
+ *
320
329
  * @param context - Request context
321
330
  * @param options - Guard executor options
322
331
  * @returns true if all guards pass, false otherwise
@@ -325,7 +334,12 @@ export async function executeGuards(
325
334
  context: Context,
326
335
  options: GuardExecutorOptions,
327
336
  ): Promise<boolean> {
328
- const { globalGuards = [], classGuards = [], methodGuards = [], resolveGuard } = options;
337
+ const {
338
+ globalGuards = [],
339
+ classGuards = [],
340
+ methodGuards = [],
341
+ resolveGuard,
342
+ } = options;
329
343
 
330
344
  // Combine all guards in execution order
331
345
  const allGuards = [...globalGuards, ...classGuards, ...methodGuards];
@@ -338,8 +352,11 @@ export async function executeGuards(
338
352
  if (typeof guard === "function") {
339
353
  // Check if it's a guard function or a class constructor
340
354
  const funcGuard = guard as { prototype?: unknown; canActivate?: unknown };
341
- if (funcGuard.prototype && typeof funcGuard.prototype === "object" &&
342
- "canActivate" in (funcGuard.prototype as object)) {
355
+ if (
356
+ funcGuard.prototype &&
357
+ typeof funcGuard.prototype === "object" &&
358
+ "canActivate" in (funcGuard.prototype as object)
359
+ ) {
343
360
  // It's a class constructor - try to resolve from container or create instance
344
361
  guardInstance = resolveGuard ? resolveGuard(guard) : null;
345
362
  if (!guardInstance) {
@@ -355,7 +372,10 @@ export async function executeGuards(
355
372
  } else if (typeof guard === "object" && guard !== null) {
356
373
  // It's a token or already an instance
357
374
  const objGuard = guard as { canActivate?: unknown };
358
- if ("canActivate" in objGuard && typeof objGuard.canActivate === "function") {
375
+ if (
376
+ "canActivate" in objGuard &&
377
+ typeof objGuard.canActivate === "function"
378
+ ) {
359
379
  // It's already a CanActivate instance
360
380
  guardInstance = guard as CanActivate;
361
381
  } else {
@@ -392,14 +412,17 @@ export async function executeGuards(
392
412
  * Create a 403 Forbidden response
393
413
  */
394
414
  export function createForbiddenResponse(): Response {
395
- return new Response(JSON.stringify({
396
- statusCode: 403,
397
- error: "Forbidden",
398
- message: "Access denied",
399
- }), {
400
- status: 403,
401
- headers: {
402
- "Content-Type": "application/json",
415
+ return new Response(
416
+ JSON.stringify({
417
+ statusCode: 403,
418
+ error: "Forbidden",
419
+ message: "Access denied",
420
+ }),
421
+ {
422
+ status: 403,
423
+ headers: {
424
+ "Content-Type": "application/json",
425
+ },
403
426
  },
404
- });
405
- }
427
+ );
428
+ }