wynkjs 1.0.3 → 1.0.4

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 (37) hide show
  1. package/README.md +252 -55
  2. package/dist/database.d.ts +1 -1
  3. package/dist/database.js +1 -1
  4. package/dist/decorators/exception.advanced.d.ts +286 -18
  5. package/dist/decorators/exception.advanced.d.ts.map +1 -1
  6. package/dist/decorators/exception.advanced.js +410 -17
  7. package/dist/decorators/exception.decorators.d.ts +92 -2
  8. package/dist/decorators/exception.decorators.d.ts.map +1 -1
  9. package/dist/decorators/exception.decorators.js +120 -5
  10. package/dist/decorators/formatter.decorators.d.ts +93 -0
  11. package/dist/decorators/formatter.decorators.d.ts.map +1 -0
  12. package/dist/decorators/formatter.decorators.js +131 -0
  13. package/dist/decorators/guard.decorators.d.ts +2 -2
  14. package/dist/decorators/http.decorators.d.ts +3 -2
  15. package/dist/decorators/http.decorators.d.ts.map +1 -1
  16. package/dist/decorators/pipe.decorators.d.ts +2 -2
  17. package/dist/decorators/pipe.decorators.d.ts.map +1 -1
  18. package/dist/decorators/pipe.decorators.js +2 -2
  19. package/dist/dto.js +1 -1
  20. package/dist/factory.d.ts +1 -1
  21. package/dist/factory.d.ts.map +1 -1
  22. package/dist/factory.js +55 -6
  23. package/dist/filters/exception.filters.d.ts +124 -0
  24. package/dist/filters/exception.filters.d.ts.map +1 -0
  25. package/dist/filters/exception.filters.js +208 -0
  26. package/dist/index.d.ts +3 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -1
  29. package/dist/pipes/validation.pipe.d.ts +3 -3
  30. package/dist/pipes/validation.pipe.d.ts.map +1 -1
  31. package/dist/pipes/validation.pipe.js +39 -11
  32. package/dist/schema-registry.d.ts +51 -0
  33. package/dist/schema-registry.d.ts.map +1 -0
  34. package/dist/schema-registry.js +134 -0
  35. package/dist/testing/index.d.ts +2 -2
  36. package/dist/testing/index.js +2 -2
  37. package/package.json +8 -3
@@ -13,7 +13,7 @@ import "reflect-metadata";
13
13
  * export class HttpWynkExceptionFilter implements WynkExceptionFilter {}
14
14
  *
15
15
  * @Catch() // Catches all exceptions
16
- * export class AllExceptionsFilter implements WynkExceptionFilter {}
16
+ * export class AllExceptions implements WynkExceptionFilter {}
17
17
  */
18
18
  export function Catch(...exceptions) {
19
19
  return (target) => {
@@ -216,7 +216,7 @@ export { HttpWynkExceptionFilter };
216
216
  /**
217
217
  * All exceptions filter - catches everything
218
218
  */
219
- let AllExceptionsFilter = class AllExceptionsFilter {
219
+ let AllExceptions = class AllExceptions {
220
220
  catch(exception, context) {
221
221
  const response = context.getResponse();
222
222
  if (exception instanceof HttpException) {
@@ -236,7 +236,122 @@ let AllExceptionsFilter = class AllExceptionsFilter {
236
236
  };
237
237
  }
238
238
  };
239
- AllExceptionsFilter = __decorate([
239
+ AllExceptions = __decorate([
240
240
  Catch()
241
- ], AllExceptionsFilter);
242
- export { AllExceptionsFilter };
241
+ ], AllExceptions);
242
+ export { AllExceptions };
243
+ /**
244
+ * Authentication Exception Filter - Handles auth errors
245
+ *
246
+ * ⚠️ IMPORTANT: This catches ALL UnauthorizedException instances!
247
+ * Use on specific routes/controllers, not globally.
248
+ *
249
+ * @example
250
+ * // ✅ GOOD: Use on auth-protected controller
251
+ * @UseFilters(AuthenticationExceptionFilter)
252
+ * @Controller('/auth')
253
+ * export class AuthController {
254
+ * @Post('/login')
255
+ * async login() {
256
+ * throw new UnauthorizedException('Invalid credentials');
257
+ * }
258
+ * }
259
+ */
260
+ export class AuthenticationException {
261
+ catch(exception, context) {
262
+ const response = context.getResponse();
263
+ const request = context.getRequest();
264
+ return {
265
+ statusCode: exception.statusCode,
266
+ error: "Authentication Failed",
267
+ message: exception.message || "Invalid credentials",
268
+ timestamp: new Date().toISOString(),
269
+ path: request.url,
270
+ hint: "Please check your authentication token or credentials",
271
+ };
272
+ }
273
+ }
274
+ /**
275
+ * Authorization Exception Filter - Handles permission errors
276
+ *
277
+ * ⚠️ IMPORTANT: This catches ALL ForbiddenException instances!
278
+ * Use on specific routes/controllers, not globally.
279
+ *
280
+ * @example
281
+ * // ✅ GOOD: Use on admin-only controller
282
+ * @UseFilters(AuthorizationExceptionFilter)
283
+ * @Controller('/admin')
284
+ * export class AdminController {
285
+ * @Get('/users')
286
+ * async getAllUsers() {
287
+ * throw new ForbiddenException('Admin access required');
288
+ * }
289
+ * }
290
+ */
291
+ export class AuthorizationException {
292
+ catch(exception, context) {
293
+ const response = context.getResponse();
294
+ const request = context.getRequest();
295
+ return {
296
+ statusCode: exception.statusCode,
297
+ error: "Authorization Failed",
298
+ message: exception.message ||
299
+ "You don't have permission to access this resource",
300
+ timestamp: new Date().toISOString(),
301
+ path: request.url,
302
+ requiredPermissions: exception.requiredPermissions || [],
303
+ };
304
+ }
305
+ }
306
+ /**
307
+ * Rate Limit Exception Filter - Handles rate limit errors
308
+ * @example
309
+ * @UseFilters(RateLimitExceptionFilter)
310
+ * @Post()
311
+ * async create() {}
312
+ */
313
+ export class RateLimitException {
314
+ catch(exception, context) {
315
+ const response = context.getResponse();
316
+ const request = context.getRequest();
317
+ // Don't catch HttpException or its subclasses
318
+ if (exception instanceof HttpException) {
319
+ throw exception;
320
+ }
321
+ return {
322
+ statusCode: 429,
323
+ error: "Too Many Requests",
324
+ message: exception.message || "Rate limit exceeded",
325
+ timestamp: new Date().toISOString(),
326
+ path: request.url,
327
+ retryAfter: exception.retryAfter || 60,
328
+ hint: "Please wait before making another request",
329
+ };
330
+ }
331
+ }
332
+ /**
333
+ * Business Logic Exception Filter - Handles business rule violations
334
+ * @example
335
+ * @UseFilters(BusinessLogicExceptionFilter)
336
+ * @Post('/transfer')
337
+ * async transfer(@Body() data: any) {}
338
+ */
339
+ export class BusinessLogicException {
340
+ catch(exception, context) {
341
+ const response = context.getResponse();
342
+ const request = context.getRequest();
343
+ // Don't catch HttpException or its subclasses
344
+ if (exception instanceof HttpException) {
345
+ throw exception;
346
+ }
347
+ return {
348
+ statusCode: exception.statusCode || 422,
349
+ error: "Business Rule Violation",
350
+ message: exception.message || "Business logic constraint violated",
351
+ timestamp: new Date().toISOString(),
352
+ path: request.url,
353
+ rule: exception.rule || "unknown",
354
+ details: exception.details || {},
355
+ };
356
+ }
357
+ }
@@ -0,0 +1,93 @@
1
+ import "reflect-metadata";
2
+ /**
3
+ * Error Formatter Interface
4
+ * Used by WynkFactory to format validation errors
5
+ *
6
+ * IMPORTANT: These formatters are passed to WynkFactory.create(), NOT to useGlobalFilters()!
7
+ *
8
+ * @example
9
+ * // CORRECT usage:
10
+ * const app = WynkFactory.create({
11
+ * controllers: [UserController],
12
+ * validationErrorFormatter: new FormatErrorFormatter(), // ✅ Pass here
13
+ * });
14
+ *
15
+ * // WRONG usage:
16
+ * app.useGlobalFilters(
17
+ * new FormatErrorFormatter() // ❌ This is not a filter!
18
+ * );
19
+ */
20
+ export interface ErrorFormatter {
21
+ format(validationError: any): any;
22
+ }
23
+ /**
24
+ * FormatErrorFormatter - Formats as { field: [messages] } object structure
25
+ *
26
+ * Output example:
27
+ * {
28
+ * "statusCode": 400,
29
+ * "message": "Validation failed",
30
+ * "errors": {
31
+ * "email": ["Invalid email address"],
32
+ * "age": ["Must be at least 18"]
33
+ * }
34
+ * }
35
+ *
36
+ * @example
37
+ * const app = WynkFactory.create({
38
+ * controllers: [UserController],
39
+ * validationErrorFormatter: new FormatErrorFormatter(),
40
+ * });
41
+ */
42
+ export declare class FormatErrorFormatter implements ErrorFormatter {
43
+ format(error: any): any;
44
+ }
45
+ /**
46
+ * SimpleErrorFormatter - Formats as simple array of messages
47
+ *
48
+ * Output example:
49
+ * {
50
+ * "statusCode": 400,
51
+ * "message": "Validation failed",
52
+ * "errors": [
53
+ * "Invalid email address",
54
+ * "Must be at least 18"
55
+ * ]
56
+ * }
57
+ *
58
+ * @example
59
+ * const app = WynkFactory.create({
60
+ * controllers: [UserController],
61
+ * validationErrorFormatter: new SimpleErrorFormatter(),
62
+ * });
63
+ */
64
+ export declare class SimpleErrorFormatter implements ErrorFormatter {
65
+ format(error: any): any;
66
+ }
67
+ /**
68
+ * DetailedErrorFormatter - Formats with detailed field info
69
+ *
70
+ * Output example:
71
+ * {
72
+ * "statusCode": 400,
73
+ * "message": "Validation failed",
74
+ * "errors": [
75
+ * {
76
+ * "field": "email",
77
+ * "message": "Invalid email address",
78
+ * "value": "invalid-email",
79
+ * "expected": {...schema...}
80
+ * }
81
+ * ]
82
+ * }
83
+ *
84
+ * @example
85
+ * const app = WynkFactory.create({
86
+ * controllers: [UserController],
87
+ * validationErrorFormatter: new DetailedErrorFormatter(),
88
+ * });
89
+ */
90
+ export declare class DetailedErrorFormatter implements ErrorFormatter {
91
+ format(error: any): any;
92
+ }
93
+ //# sourceMappingURL=formatter.decorators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/formatter.decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,eAAe,EAAE,GAAG,GAAG,GAAG,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;CAsBxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;CAiBxB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;CAgCxB"}
@@ -0,0 +1,131 @@
1
+ import "reflect-metadata";
2
+ /**
3
+ * FormatErrorFormatter - Formats as { field: [messages] } object structure
4
+ *
5
+ * Output example:
6
+ * {
7
+ * "statusCode": 400,
8
+ * "message": "Validation failed",
9
+ * "errors": {
10
+ * "email": ["Invalid email address"],
11
+ * "age": ["Must be at least 18"]
12
+ * }
13
+ * }
14
+ *
15
+ * @example
16
+ * const app = WynkFactory.create({
17
+ * controllers: [UserController],
18
+ * validationErrorFormatter: new FormatErrorFormatter(),
19
+ * });
20
+ */
21
+ export class FormatErrorFormatter {
22
+ format(error) {
23
+ const formattedErrors = {};
24
+ if (error.errors && error.errors.length > 0) {
25
+ error.errors.forEach((err) => {
26
+ const field = err.path?.replace(/^\//, "") || "unknown";
27
+ if (!formattedErrors[field]) {
28
+ formattedErrors[field] = [];
29
+ }
30
+ formattedErrors[field].push(err.summary || err.message);
31
+ });
32
+ }
33
+ else {
34
+ const field = error.property?.replace(/^\//, "") || "unknown";
35
+ formattedErrors[field] = [error.summary || error.message];
36
+ }
37
+ return {
38
+ statusCode: 400,
39
+ message: "Validation failed",
40
+ errors: formattedErrors,
41
+ };
42
+ }
43
+ }
44
+ /**
45
+ * SimpleErrorFormatter - Formats as simple array of messages
46
+ *
47
+ * Output example:
48
+ * {
49
+ * "statusCode": 400,
50
+ * "message": "Validation failed",
51
+ * "errors": [
52
+ * "Invalid email address",
53
+ * "Must be at least 18"
54
+ * ]
55
+ * }
56
+ *
57
+ * @example
58
+ * const app = WynkFactory.create({
59
+ * controllers: [UserController],
60
+ * validationErrorFormatter: new SimpleErrorFormatter(),
61
+ * });
62
+ */
63
+ export class SimpleErrorFormatter {
64
+ format(error) {
65
+ const messages = [];
66
+ if (error.errors && error.errors.length > 0) {
67
+ error.errors.forEach((err) => {
68
+ messages.push(err.summary || err.message);
69
+ });
70
+ }
71
+ else {
72
+ messages.push(error.summary || error.message);
73
+ }
74
+ return {
75
+ statusCode: 400,
76
+ message: "Validation failed",
77
+ errors: messages,
78
+ };
79
+ }
80
+ }
81
+ /**
82
+ * DetailedErrorFormatter - Formats with detailed field info
83
+ *
84
+ * Output example:
85
+ * {
86
+ * "statusCode": 400,
87
+ * "message": "Validation failed",
88
+ * "errors": [
89
+ * {
90
+ * "field": "email",
91
+ * "message": "Invalid email address",
92
+ * "value": "invalid-email",
93
+ * "expected": {...schema...}
94
+ * }
95
+ * ]
96
+ * }
97
+ *
98
+ * @example
99
+ * const app = WynkFactory.create({
100
+ * controllers: [UserController],
101
+ * validationErrorFormatter: new DetailedErrorFormatter(),
102
+ * });
103
+ */
104
+ export class DetailedErrorFormatter {
105
+ format(error) {
106
+ const errors = [];
107
+ if (error.errors && error.errors.length > 0) {
108
+ error.errors.forEach((err) => {
109
+ errors.push({
110
+ field: err.path?.replace(/^\//, "") || "unknown",
111
+ message: err.summary || err.message,
112
+ value: err.value,
113
+ expected: err.schema,
114
+ });
115
+ });
116
+ }
117
+ else {
118
+ errors.push({
119
+ field: error.property?.replace(/^\//, "") || "unknown",
120
+ message: error.summary || error.message,
121
+ value: error.found,
122
+ expected: error.expected,
123
+ });
124
+ }
125
+ return {
126
+ statusCode: 400,
127
+ message: "Validation failed",
128
+ errors,
129
+ };
130
+ }
131
+ }
@@ -1,7 +1,7 @@
1
1
  import "reflect-metadata";
2
2
  /**
3
- * Guard Decorators and Interfaces for ElysiaJS Framework
4
- * Similar to NestJS guards for route protection
3
+ * Guard Decorators and Interfaces for WynkJS Framework
4
+ * Guards for route protection and authorization
5
5
  */
6
6
  /**
7
7
  * Execution context interface - provides access to request details
@@ -1,7 +1,8 @@
1
1
  import "reflect-metadata";
2
2
  /**
3
- * HTTP Method Decorators for ElysiaJS Framework
4
- * Inspired by NestJS but optimized for Elysia's performance
3
+ * HTTP Method Decorators for WynkJS Framework
4
+ * RESTful route handlers with TypeScript decorators
5
+ * Optimized for Elysia's performance on Bun runtime
5
6
  */
6
7
  export interface RouteOptions {
7
8
  path?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"http.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/http.decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAW,GAAG,cAAc,CAK5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,GAAG,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,GAAG,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM7E;AAED;;;GAGG;AACH,wBAAgB,OAAO,CACrB,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GACpC,eAAe,CAMjB;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM3E;AAmDD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAStD;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAYnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAAY,GACvB,eAAe,CAcjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,EAAE,GAAG,cAAc,GAAG,eAAe,CAuB3E"}
1
+ {"version":3,"file":"http.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/http.decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAW,GAAG,cAAc,CAK5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,GAAG,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,GAAG,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM7E;AAED;;;GAGG;AACH,wBAAgB,OAAO,CACrB,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GACpC,eAAe,CAMjB;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,CAM3E;AAmDD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAStD;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAYnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAAY,GACvB,eAAe,CAcjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,EAAE,GAAG,cAAc,GAAG,eAAe,CAuB3E"}
@@ -47,7 +47,7 @@ export declare function executePipes(pipes: (Function | WynkPipeTransform)[], va
47
47
  * create(@Body() dto: CreateDto) {}
48
48
  *
49
49
  * @example
50
- * // Custom formatting (like NestJS)
50
+ * // Custom formatting with detailed errors
51
51
  * const customPipe = new ValidationPipe({
52
52
  * exceptionFactory: (errors) => ({
53
53
  * statusCode: 400,
@@ -161,7 +161,7 @@ export declare class TrimPipe implements WynkPipeTransform<string, string> {
161
161
  }
162
162
  /**
163
163
  * FormatErrorPipe - Formats validation errors as { [field]: [messages] }
164
- * Like NestJS format with field names as keys
164
+ * Object format with field names as keys
165
165
  *
166
166
  * @example
167
167
  * // In index.ts or controller
@@ -1 +1 @@
1
- {"version":3,"file":"pipe.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/pipe.decorators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pipe.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/pipe.decorators.ts"],"names":[],"mappings":"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"}
@@ -60,7 +60,7 @@ export async function executePipes(pipes, value, metadata) {
60
60
  * create(@Body() dto: CreateDto) {}
61
61
  *
62
62
  * @example
63
- * // Custom formatting (like NestJS)
63
+ * // Custom formatting with detailed errors
64
64
  * const customPipe = new ValidationPipe({
65
65
  * exceptionFactory: (errors) => ({
66
66
  * statusCode: 400,
@@ -288,7 +288,7 @@ export class TrimPipe {
288
288
  }
289
289
  /**
290
290
  * FormatErrorPipe - Formats validation errors as { [field]: [messages] }
291
- * Like NestJS format with field names as keys
291
+ * Object format with field names as keys
292
292
  *
293
293
  * @example
294
294
  * // In index.ts or controller
package/dist/dto.js CHANGED
@@ -92,7 +92,7 @@ export const CommonDTO = {
92
92
  */
93
93
  PhoneIN: (options = {}) => t.String({
94
94
  pattern: "^[6-9]{1}[0-9]{9}$",
95
- errorMessage: "Invalid mobile number",
95
+ error: "Invalid mobile number",
96
96
  ...options,
97
97
  }),
98
98
  /**
package/dist/factory.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Elysia } from "elysia";
2
2
  import "reflect-metadata";
3
- import { ErrorFormatter } from "./decorators/exception.advanced";
3
+ import { ErrorFormatter } from "./decorators/formatter.decorators";
4
4
  /**
5
5
  * Application Factory for WynkJS Framework
6
6
  * Creates and configures Elysia app with all decorators support
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../core/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,kBAAkB,CAAC;AAc1B,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,GAAG,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wBAAwB,CAAC,EAAE,cAAc,CAAC;CAC3C;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,mBAAmB,CAAC,CAAiB;gBAEjC,OAAO,GAAE,kBAAuB;IAmH5C;;OAEG;IACH,MAAM,CAAC,MAAM,CACX,OAAO,GAAE,kBAAkB,GAAG;QAAE,WAAW,CAAC,EAAE,GAAG,EAAE,CAAA;KAAO,GACzD,aAAa;IAQhB;;OAEG;IACH,mBAAmB,CAAC,GAAG,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI;IAKhD;;OAEG;IACH,eAAe,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI;IAKvC;;OAEG;IACH,qBAAqB,CAAC,GAAG,YAAY,EAAE,GAAG,EAAE,GAAG,IAAI;IAKnD;;OAEG;IACH,cAAc,CAAC,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI;IAKrC;;OAEG;IACH,gBAAgB,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI;IAKzC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAkD9B;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzC;;OAEG;IACH,MAAM,IAAI,MAAM;IAIhB;;OAEG;YACW,kBAAkB;CAuVjC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CAEzE;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,MAAM,CAAC,MAAM,CACX,OAAO,GAAE,kBAAkB,GAAG;QAAE,WAAW,CAAC,EAAE,GAAG,EAAE,CAAA;KAAO,GACzD,aAAa;CASjB;AAGD,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../core/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,kBAAkB,CAAC;AAc1B,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAGnE;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,GAAG,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wBAAwB,CAAC,EAAE,cAAc,CAAC;CAC3C;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,mBAAmB,CAAC,CAAiB;gBAEjC,OAAO,GAAE,kBAAuB;IAgL5C;;OAEG;IACH,MAAM,CAAC,MAAM,CACX,OAAO,GAAE,kBAAkB,GAAG;QAAE,WAAW,CAAC,EAAE,GAAG,EAAE,CAAA;KAAO,GACzD,aAAa;IAQhB;;OAEG;IACH,mBAAmB,CAAC,GAAG,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI;IAKhD;;OAEG;IACH,eAAe,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI;IAKvC;;OAEG;IACH,qBAAqB,CAAC,GAAG,YAAY,EAAE,GAAG,EAAE,GAAG,IAAI;IAKnD;;OAEG;IACH,cAAc,CAAC,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI;IAKrC;;OAEG;IACH,gBAAgB,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI;IAKzC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAkD9B;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzC;;OAEG;IACH,MAAM,IAAI,MAAM;IAIhB;;OAEG;YACW,kBAAkB;CAuWjC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CAEzE;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,MAAM,CAAC,MAAM,CACX,OAAO,GAAE,kBAAkB,GAAG;QAAE,WAAW,CAAC,EAAE,GAAG,EAAE,CAAA;KAAO,GACzD,aAAa;CASjB;AAGD,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,CAAC"}
package/dist/factory.js CHANGED
@@ -6,6 +6,7 @@ import { createExecutionContext, executeGuards, } from "./decorators/guard.decor
6
6
  import { executeInterceptors } from "./decorators/interceptor.decorators";
7
7
  import { executePipes } from "./decorators/pipe.decorators";
8
8
  import { executeExceptionFilters, HttpException, } from "./decorators/exception.decorators";
9
+ import { schemaRegistry } from "./schema-registry";
9
10
  export class WynkFramework {
10
11
  app;
11
12
  controllers = [];
@@ -18,12 +19,18 @@ export class WynkFramework {
18
19
  this.app = new Elysia();
19
20
  this.validationFormatter = options.validationErrorFormatter;
20
21
  // Configure Elysia's error handling for validation errors
21
- this.app.onError(({ code, error, set }) => {
22
+ this.app.onError(({ code, error, set, request }) => {
22
23
  // Handle ValidationError from Elysia
23
24
  if (code === "VALIDATION" ||
24
25
  error?.constructor?.name === "ValidationError") {
25
26
  const validationError = error;
26
27
  set.status = 400;
28
+ // Get the validation type (body, query, params)
29
+ const validationType = validationError.on || "body";
30
+ // Try to find the schema key for this route
31
+ const method = request.method;
32
+ const path = new URL(request.url).pathname;
33
+ const schemaKey = schemaRegistry.getSchemaKeyForRoute(method, path, validationType);
27
34
  // Try to collect all validation errors using TypeBox
28
35
  const allErrors = {};
29
36
  // Check if we have the validator and value to collect all errors
@@ -38,7 +45,15 @@ export class WynkFramework {
38
45
  if (!allErrors[field]) {
39
46
  allErrors[field] = [];
40
47
  }
41
- allErrors[field].push(err.message || "Validation failed");
48
+ // Try to get custom error message from schema registry
49
+ let message = err.message || "Validation failed";
50
+ if (schemaKey) {
51
+ const customMessage = schemaRegistry.getErrorMessage(schemaKey, field);
52
+ if (customMessage) {
53
+ message = customMessage;
54
+ }
55
+ }
56
+ allErrors[field].push(message);
42
57
  });
43
58
  }
44
59
  else {
@@ -46,9 +61,16 @@ export class WynkFramework {
46
61
  const field = validationError.valueError?.path?.replace(/^\//, "") ||
47
62
  validationError.on ||
48
63
  "body";
49
- const message = validationError.customError ||
64
+ let message = validationError.customError ||
50
65
  validationError.valueError?.message ||
51
66
  "Validation failed";
67
+ // Try to get custom error message
68
+ if (schemaKey) {
69
+ const customMessage = schemaRegistry.getErrorMessage(schemaKey, field);
70
+ if (customMessage) {
71
+ message = customMessage;
72
+ }
73
+ }
52
74
  allErrors[field] = [message];
53
75
  }
54
76
  }
@@ -57,9 +79,16 @@ export class WynkFramework {
57
79
  const field = validationError.valueError?.path?.replace(/^\//, "") ||
58
80
  validationError.on ||
59
81
  "body";
60
- const message = validationError.customError ||
82
+ let message = validationError.customError ||
61
83
  validationError.valueError?.message ||
62
84
  "Validation failed";
85
+ // Try to get custom error message
86
+ if (schemaKey) {
87
+ const customMessage = schemaRegistry.getErrorMessage(schemaKey, field);
88
+ if (customMessage) {
89
+ message = customMessage;
90
+ }
91
+ }
63
92
  allErrors[field] = [message];
64
93
  }
65
94
  }
@@ -68,9 +97,16 @@ export class WynkFramework {
68
97
  const field = validationError.valueError?.path?.replace(/^\//, "") ||
69
98
  validationError.on ||
70
99
  "body";
71
- const message = validationError.customError ||
100
+ let message = validationError.customError ||
72
101
  validationError.valueError?.message ||
73
102
  "Validation failed";
103
+ // Try to get custom error message
104
+ if (schemaKey) {
105
+ const customMessage = schemaRegistry.getErrorMessage(schemaKey, field);
106
+ if (customMessage) {
107
+ message = customMessage;
108
+ }
109
+ }
74
110
  allErrors[field] = [message];
75
111
  }
76
112
  // If a custom formatter is provided, use it
@@ -454,13 +490,26 @@ export class WynkFramework {
454
490
  // Register route with Elysia
455
491
  const elysiaOptions = {};
456
492
  if (routeOptions.body || bodySchema) {
457
- elysiaOptions.body = routeOptions.body || bodySchema;
493
+ const schema = routeOptions.body || bodySchema;
494
+ elysiaOptions.body = schema;
495
+ // Register schema with custom error messages
496
+ const schemaKey = `${ControllerClass.name}.${methodName}.body`;
497
+ schemaRegistry.registerSchema(schemaKey, schema);
498
+ schemaRegistry.registerRoute(method, fullPath, schemaKey, "body");
458
499
  }
459
500
  if (routeOptions.query) {
460
501
  elysiaOptions.query = routeOptions.query;
502
+ // Register query schema
503
+ const schemaKey = `${ControllerClass.name}.${methodName}.query`;
504
+ schemaRegistry.registerSchema(schemaKey, routeOptions.query);
505
+ schemaRegistry.registerRoute(method, fullPath, schemaKey, "query");
461
506
  }
462
507
  if (routeOptions.params) {
463
508
  elysiaOptions.params = routeOptions.params;
509
+ // Register params schema
510
+ const schemaKey = `${ControllerClass.name}.${methodName}.params`;
511
+ schemaRegistry.registerSchema(schemaKey, routeOptions.params);
512
+ schemaRegistry.registerRoute(method, fullPath, schemaKey, "params");
464
513
  }
465
514
  if (routeOptions.headers) {
466
515
  elysiaOptions.headers = routeOptions.headers;