wynkjs 1.0.0 → 1.0.2

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.
@@ -1,27 +1,56 @@
1
1
  import "reflect-metadata";
2
2
  import { WynkExceptionFilter } from "./exception.decorators";
3
3
  import { ExecutionContext } from "./guard.decorators";
4
- import { NotFoundException, BadRequestException, UnauthorizedException, ForbiddenException } from "./exception.decorators";
4
+ import { NotFoundException, UnauthorizedException, ForbiddenException } from "./exception.decorators";
5
5
  /**
6
6
  * Advanced Exception Filters for WynkJS Framework
7
7
  * Specialized filters for different error scenarios
8
8
  */
9
9
  /**
10
- * Validation Exception Filter - Handles validation errors
10
+ * Error Formatter Interface
11
+ * Used by ValidationExceptionFilter to format validation errors
12
+ */
13
+ export interface ErrorFormatter {
14
+ format(validationError: any): any;
15
+ }
16
+ /**
17
+ * FormatErrorFormatter - Formats as { field: [messages] } like NestJS
18
+ */
19
+ export declare class FormatErrorFormatter implements ErrorFormatter {
20
+ format(error: any): any;
21
+ }
22
+ /**
23
+ * SimpleErrorFormatter - Formats as simple array of messages
24
+ */
25
+ export declare class SimpleErrorFormatter implements ErrorFormatter {
26
+ format(error: any): any;
27
+ }
28
+ /**
29
+ * DetailedErrorFormatter - Formats with detailed field info
30
+ */
31
+ export declare class DetailedErrorFormatter implements ErrorFormatter {
32
+ format(error: any): any;
33
+ }
34
+ /**
35
+ * Validation Exception Filter - Handles validation errors with customizable formatting
11
36
  * @example
12
- * @UseFilters(ValidationExceptionFilter)
13
- * @Post()
14
- * async create(@Body() data: any) {}
37
+ * // With FormatErrorFormatter (NestJS-style)
38
+ * app.useGlobalFilters(new ValidationExceptionFilter(new FormatErrorFormatter()));
39
+ *
40
+ * // With SimpleErrorFormatter
41
+ * app.useGlobalFilters(new ValidationExceptionFilter(new SimpleErrorFormatter()));
42
+ *
43
+ * // With DetailedErrorFormatter
44
+ * app.useGlobalFilters(new ValidationExceptionFilter(new DetailedErrorFormatter()));
45
+ *
46
+ * // Without formatter (default detailed format)
47
+ * app.useGlobalFilters(new ValidationExceptionFilter());
15
48
  */
16
- export declare class ValidationExceptionFilter implements WynkExceptionFilter<BadRequestException> {
17
- catch(exception: BadRequestException, context: ExecutionContext): {
18
- statusCode: number;
19
- error: string;
20
- message: string;
21
- errors: any;
22
- timestamp: string;
23
- path: any;
24
- };
49
+ export declare class ValidationExceptionFilter implements WynkExceptionFilter {
50
+ private formatter;
51
+ constructor(formatter?: ErrorFormatter);
52
+ catch(exception: any, context: ExecutionContext): any;
53
+ private isValidationError;
25
54
  }
26
55
  /**
27
56
  * Database Exception Filter - Handles database errors
@@ -1 +1 @@
1
- {"version":3,"file":"exception.advanced.d.ts","sourceRoot":"","sources":["../../core/decorators/exception.advanced.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAEL,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;AAEhC;;;GAGG;AAEH;;;;;;GAMG;AACH,qBAAa,yBACX,YAAW,mBAAmB,CAAC,mBAAmB,CAAC;IAEnD,KAAK,CAAC,SAAS,EAAE,mBAAmB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAahE;AAED;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;CAiChD;AAED;;;;;;GAMG;AACH,qBAAa,6BACX,YAAW,mBAAmB,CAAC,qBAAqB,CAAC;IAErD,KAAK,CAAC,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAalE;AAED;;;;;;GAMG;AACH,qBAAa,4BACX,YAAW,mBAAmB,CAAC,kBAAkB,CAAC;IAElD,KAAK,CAAC,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAe/D;AAED;;;;;;GAMG;AACH,qBAAa,uBACX,YAAW,mBAAmB,CAAC,iBAAiB,CAAC;IAEjD,KAAK,CAAC,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAa9D;AAED;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,mBAAmB;IAClE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;;CAchD;AAED;;;;;;GAMG;AACH,qBAAa,4BAA6B,YAAW,mBAAmB;IACtE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;;CAchD;AAED;;;;;;GAMG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;IACnE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;CAsBhD;AAED;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,mBAAmB;IAC/D,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CA2BhD"}
1
+ {"version":3,"file":"exception.advanced.d.ts","sourceRoot":"","sources":["../../core/decorators/exception.advanced.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAEL,iBAAiB,EAEjB,qBAAqB,EACrB,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;AAEhC;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,eAAe,EAAE,GAAG,GAAG,GAAG,CAAC;CACnC;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;CAsBxB;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;CAiBxB;AAED;;GAEG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;CAgCxB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;IACnE,OAAO,CAAC,SAAS,CAA+B;gBAEpC,SAAS,CAAC,EAAE,cAAc;IAItC,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;IAgC/C,OAAO,CAAC,iBAAiB;CAiB1B;AAED;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;CAiChD;AAED;;;;;;GAMG;AACH,qBAAa,6BACX,YAAW,mBAAmB,CAAC,qBAAqB,CAAC;IAErD,KAAK,CAAC,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAalE;AAED;;;;;;GAMG;AACH,qBAAa,4BACX,YAAW,mBAAmB,CAAC,kBAAkB,CAAC;IAElD,KAAK,CAAC,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAe/D;AAED;;;;;;GAMG;AACH,qBAAa,uBACX,YAAW,mBAAmB,CAAC,iBAAiB,CAAC;IAEjD,KAAK,CAAC,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAa9D;AAED;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,mBAAmB;IAClE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;;CAchD;AAED;;;;;;GAMG;AACH,qBAAa,4BAA6B,YAAW,mBAAmB;IACtE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;;CAchD;AAED;;;;;;GAMG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;IACnE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;CAsBhD;AAED;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,mBAAmB;IAC/D,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CA2BhD"}
@@ -1,27 +1,144 @@
1
1
  import "reflect-metadata";
2
2
  /**
3
- * Advanced Exception Filters for WynkJS Framework
4
- * Specialized filters for different error scenarios
3
+ * FormatErrorFormatter - Formats as { field: [messages] } like NestJS
5
4
  */
5
+ export class FormatErrorFormatter {
6
+ format(error) {
7
+ const formattedErrors = {};
8
+ if (error.errors && error.errors.length > 0) {
9
+ error.errors.forEach((err) => {
10
+ const field = err.path?.replace(/^\//, "") || "unknown";
11
+ if (!formattedErrors[field]) {
12
+ formattedErrors[field] = [];
13
+ }
14
+ formattedErrors[field].push(err.summary || err.message);
15
+ });
16
+ }
17
+ else {
18
+ const field = error.property?.replace(/^\//, "") || "unknown";
19
+ formattedErrors[field] = [error.summary || error.message];
20
+ }
21
+ return {
22
+ statusCode: 400,
23
+ message: "Validation failed",
24
+ errors: formattedErrors,
25
+ };
26
+ }
27
+ }
28
+ /**
29
+ * SimpleErrorFormatter - Formats as simple array of messages
30
+ */
31
+ export class SimpleErrorFormatter {
32
+ format(error) {
33
+ const messages = [];
34
+ if (error.errors && error.errors.length > 0) {
35
+ error.errors.forEach((err) => {
36
+ messages.push(err.summary || err.message);
37
+ });
38
+ }
39
+ else {
40
+ messages.push(error.summary || error.message);
41
+ }
42
+ return {
43
+ statusCode: 400,
44
+ message: "Validation failed",
45
+ errors: messages,
46
+ };
47
+ }
48
+ }
6
49
  /**
7
- * Validation Exception Filter - Handles validation errors
50
+ * DetailedErrorFormatter - Formats with detailed field info
51
+ */
52
+ export class DetailedErrorFormatter {
53
+ format(error) {
54
+ const errors = [];
55
+ if (error.errors && error.errors.length > 0) {
56
+ error.errors.forEach((err) => {
57
+ errors.push({
58
+ field: err.path?.replace(/^\//, "") || "unknown",
59
+ message: err.summary || err.message,
60
+ value: err.value,
61
+ expected: err.schema,
62
+ });
63
+ });
64
+ }
65
+ else {
66
+ errors.push({
67
+ field: error.property?.replace(/^\//, "") || "unknown",
68
+ message: error.summary || error.message,
69
+ value: error.found,
70
+ expected: error.expected,
71
+ });
72
+ }
73
+ return {
74
+ statusCode: 400,
75
+ message: "Validation failed",
76
+ errors,
77
+ };
78
+ }
79
+ }
80
+ /**
81
+ * Validation Exception Filter - Handles validation errors with customizable formatting
8
82
  * @example
9
- * @UseFilters(ValidationExceptionFilter)
10
- * @Post()
11
- * async create(@Body() data: any) {}
83
+ * // With FormatErrorFormatter (NestJS-style)
84
+ * app.useGlobalFilters(new ValidationExceptionFilter(new FormatErrorFormatter()));
85
+ *
86
+ * // With SimpleErrorFormatter
87
+ * app.useGlobalFilters(new ValidationExceptionFilter(new SimpleErrorFormatter()));
88
+ *
89
+ * // With DetailedErrorFormatter
90
+ * app.useGlobalFilters(new ValidationExceptionFilter(new DetailedErrorFormatter()));
91
+ *
92
+ * // Without formatter (default detailed format)
93
+ * app.useGlobalFilters(new ValidationExceptionFilter());
12
94
  */
13
95
  export class ValidationExceptionFilter {
96
+ formatter = null;
97
+ constructor(formatter) {
98
+ this.formatter = formatter || null;
99
+ }
14
100
  catch(exception, context) {
15
- const response = context.getResponse();
16
101
  const request = context.getRequest();
17
- return {
18
- statusCode: exception.statusCode,
19
- error: "Validation Error",
20
- message: exception.message,
21
- errors: exception.errors || [],
22
- timestamp: new Date().toISOString(),
23
- path: request.url,
24
- };
102
+ // Check if this is a validation error from Elysia
103
+ const isValidationError = this.isValidationError(exception);
104
+ if (!isValidationError) {
105
+ // Not a validation error, re-throw to let other filters handle it
106
+ throw exception;
107
+ }
108
+ // Parse the validation error
109
+ let validationError;
110
+ if (typeof exception.message === "string") {
111
+ try {
112
+ validationError = JSON.parse(exception.message);
113
+ }
114
+ catch {
115
+ validationError = { message: exception.message };
116
+ }
117
+ }
118
+ else {
119
+ validationError = exception;
120
+ }
121
+ // Format the error using the provided formatter
122
+ if (this.formatter) {
123
+ return this.formatter.format(validationError);
124
+ }
125
+ // Default format (detailed)
126
+ return new DetailedErrorFormatter().format(validationError);
127
+ }
128
+ isValidationError(exception) {
129
+ if (!exception)
130
+ return false;
131
+ // Check if it's a validation error by looking at the error structure
132
+ if (exception.message && typeof exception.message === "string") {
133
+ try {
134
+ const parsed = JSON.parse(exception.message);
135
+ return parsed.type === "validation";
136
+ }
137
+ catch {
138
+ return false;
139
+ }
140
+ }
141
+ return (exception.type === "validation" || exception.code === "VALIDATION_ERROR");
25
142
  }
26
143
  }
27
144
  /**
@@ -21,13 +21,15 @@ export interface RouteOptions {
21
21
  export declare function Controller(path?: string): ClassDecorator;
22
22
  /**
23
23
  * HTTP GET decorator
24
- * @param path Route path
25
- * @param options Route configuration options
24
+ * @param pathOrOptions Route path or options with DTO
26
25
  * @example
27
26
  * @Get('/profile')
28
27
  * async getProfile() {}
28
+ *
29
+ * @Get({ path: '/:id', params: UserIdDTO, query: QueryDTO })
30
+ * async findOne(@Param('id') id: string, @Query() query: any) {}
29
31
  */
30
- export declare function Get(path?: string, options?: RouteOptions): MethodDecorator;
32
+ export declare function Get(pathOrOptions?: string | RouteOptions): MethodDecorator;
31
33
  /**
32
34
  * @Post decorator - Define a POST route
33
35
  * @param pathOrOptions Optional route path or options with DTO
@@ -66,25 +68,25 @@ export declare function Put(pathOrOptions?: string | RouteOptions): MethodDecora
66
68
  export declare function Patch(pathOrOptions?: string | RouteOptions): MethodDecorator;
67
69
  /**
68
70
  * HTTP DELETE decorator
69
- * @param path Route path
70
- * @param options Route configuration options
71
+ * @param pathOrOptions Route path or options with DTO
71
72
  * @example
72
73
  * @Delete('/:id')
73
74
  * async remove(@Param('id') id: string) {}
75
+ *
76
+ * @Delete({ path: '/:id', params: UserIdDTO })
77
+ * async remove(@Param('id') id: string) {}
74
78
  */
75
- export declare function Delete(path?: string, options?: RouteOptions): MethodDecorator;
79
+ export declare function Delete(pathOrOptions?: string | RouteOptions): MethodDecorator;
76
80
  /**
77
81
  * HTTP OPTIONS decorator
78
- * @param path Route path
79
- * @param options Route configuration options
82
+ * @param pathOrOptions Route path or options with DTO
80
83
  */
81
- export declare function Options(path?: string, options?: RouteOptions): MethodDecorator;
84
+ export declare function Options(pathOrOptions?: string | RouteOptions): MethodDecorator;
82
85
  /**
83
86
  * HTTP HEAD decorator
84
- * @param path Route path
85
- * @param options Route configuration options
87
+ * @param pathOrOptions Route path or options with DTO
86
88
  */
87
- export declare function Head(path?: string, options?: RouteOptions): MethodDecorator;
89
+ export declare function Head(pathOrOptions?: string | RouteOptions): MethodDecorator;
88
90
  /**
89
91
  * Set custom HTTP status code for a route
90
92
  * @param code HTTP status code
@@ -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;;;;;;;GAOG;AACH,wBAAgB,GAAG,CACjB,IAAI,GAAE,MAAW,EACjB,OAAO,CAAC,EAAE,YAAY,GACrB,eAAe,CAEjB;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;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACpB,IAAI,GAAE,MAAW,EACjB,OAAO,CAAC,EAAE,YAAY,GACrB,eAAe,CAEjB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,IAAI,GAAE,MAAW,EACjB,OAAO,CAAC,EAAE,YAAY,GACrB,eAAe,CAEjB;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAClB,IAAI,GAAE,MAAW,EACjB,OAAO,CAAC,EAAE,YAAY,GACrB,eAAe,CAEjB;AAiDD;;;;;;;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;;;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"}
@@ -14,14 +14,20 @@ export function Controller(path = "") {
14
14
  }
15
15
  /**
16
16
  * HTTP GET decorator
17
- * @param path Route path
18
- * @param options Route configuration options
17
+ * @param pathOrOptions Route path or options with DTO
19
18
  * @example
20
19
  * @Get('/profile')
21
20
  * async getProfile() {}
21
+ *
22
+ * @Get({ path: '/:id', params: UserIdDTO, query: QueryDTO })
23
+ * async findOne(@Param('id') id: string, @Query() query: any) {}
22
24
  */
23
- export function Get(path = "", options) {
24
- return createRouteDecorator("GET", path, options);
25
+ export function Get(pathOrOptions) {
26
+ if (typeof pathOrOptions === "string") {
27
+ return createRouteDecorator("GET", pathOrOptions);
28
+ }
29
+ const options = pathOrOptions || {};
30
+ return createRouteDecorator("GET", options.path || "", options);
25
31
  }
26
32
  /**
27
33
  * @Post decorator - Define a POST route
@@ -79,30 +85,42 @@ export function Patch(pathOrOptions) {
79
85
  }
80
86
  /**
81
87
  * HTTP DELETE decorator
82
- * @param path Route path
83
- * @param options Route configuration options
88
+ * @param pathOrOptions Route path or options with DTO
84
89
  * @example
85
90
  * @Delete('/:id')
86
91
  * async remove(@Param('id') id: string) {}
92
+ *
93
+ * @Delete({ path: '/:id', params: UserIdDTO })
94
+ * async remove(@Param('id') id: string) {}
87
95
  */
88
- export function Delete(path = "", options) {
89
- return createRouteDecorator("DELETE", path, options);
96
+ export function Delete(pathOrOptions) {
97
+ if (typeof pathOrOptions === "string") {
98
+ return createRouteDecorator("DELETE", pathOrOptions);
99
+ }
100
+ const options = pathOrOptions || {};
101
+ return createRouteDecorator("DELETE", options.path || "", options);
90
102
  }
91
103
  /**
92
104
  * HTTP OPTIONS decorator
93
- * @param path Route path
94
- * @param options Route configuration options
105
+ * @param pathOrOptions Route path or options with DTO
95
106
  */
96
- export function Options(path = "", options) {
97
- return createRouteDecorator("OPTIONS", path, options);
107
+ export function Options(pathOrOptions) {
108
+ if (typeof pathOrOptions === "string") {
109
+ return createRouteDecorator("OPTIONS", pathOrOptions);
110
+ }
111
+ const options = pathOrOptions || {};
112
+ return createRouteDecorator("OPTIONS", options.path || "", options);
98
113
  }
99
114
  /**
100
115
  * HTTP HEAD decorator
101
- * @param path Route path
102
- * @param options Route configuration options
116
+ * @param pathOrOptions Route path or options with DTO
103
117
  */
104
- export function Head(path = "", options) {
105
- return createRouteDecorator("HEAD", path, options);
118
+ export function Head(pathOrOptions) {
119
+ if (typeof pathOrOptions === "string") {
120
+ return createRouteDecorator("HEAD", pathOrOptions);
121
+ }
122
+ const options = pathOrOptions || {};
123
+ return createRouteDecorator("HEAD", options.path || "", options);
106
124
  }
107
125
  /**
108
126
  * Helper function to create route decorators
package/dist/dto.d.ts CHANGED
@@ -2,12 +2,14 @@
2
2
  * DTO Utilities for WynkJS Framework
3
3
  * Re-exports Elysia's TypeBox for DTO validation
4
4
  */
5
+ import { t, type TSchema } from "elysia";
5
6
  /**
6
- * Export Elysia's TypeBox as DTO builder
7
- * This provides runtime validation for request bodies, queries, params, etc.
7
+ * DTO Builder - Full TypeBox support with IntelliSense
8
+ *
9
+ * Provides runtime validation for request bodies, queries, params, etc.
8
10
  *
9
11
  * @example
10
- * import { DTO } from '@wynkjs/framework';
12
+ * import { DTO } from 'wynkjs';
11
13
  *
12
14
  * export const CreateUserDTO = DTO.Object({
13
15
  * name: DTO.String({ minLength: 2, maxLength: 50 }),
@@ -24,7 +26,14 @@
24
26
  * }
25
27
  * }
26
28
  */
27
- export declare const DTO: any;
29
+ export declare const DTO: typeof t & {
30
+ /**
31
+ * Create a strict object schema that strips additional properties
32
+ * @param properties - Object properties schema
33
+ * @param options - Additional schema options
34
+ */
35
+ Strict: (properties: Record<string, TSchema>, options?: Record<string, any>) => TSchema;
36
+ };
28
37
  /**
29
38
  * Common DTO patterns for quick use
30
39
  */
@@ -35,8 +44,9 @@ export declare const CommonDTO: {
35
44
  Name: (options?: {}) => import("@sinclair/typebox").TString;
36
45
  /**
37
46
  * Email validation
47
+ * Uses format: email which validates basic email structure
38
48
  */
39
- Email: (options?: {}) => import("@sinclair/typebox").TString;
49
+ Email: (options?: any) => import("@sinclair/typebox").TString;
40
50
  /**
41
51
  * Password validation (min 6 characters)
42
52
  */
package/dist/dto.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dto.d.ts","sourceRoot":"","sources":["../core/dto.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,eAAO,MAAM,GAAG,EAAE,GAAO,CAAC;AAE1B;;GAEG;AACH,eAAO,MAAM,SAAS;IACpB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAQH;;OAEG;;IAGH;;OAEG;;;;;IAOH;;OAEG;mBACY,MAAM,EAAE;;;;CAKxB,CAAC;AAEF;;GAEG;AACH,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"dto.d.ts","sourceRoot":"","sources":["../core/dto.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,GAAG,EAAQ,OAAO,CAAC,GAAG;IACjC;;;;OAIG;IACH,MAAM,EAAE,CACN,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAC1B,OAAO,CAAC;CACd,CAAC;AAiCF;;GAEG;AACH,eAAO,MAAM,SAAS;IACpB;;OAEG;;IAGH;;;OAGG;sBACc,GAAG;IAOpB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAQH;;OAEG;;IAGH;;OAEG;;;;;IAOH;;OAEG;mBACY,MAAM,EAAE;;;;CAKxB,CAAC;AAEF;;GAEG;AACH,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC"}
package/dist/dto.js CHANGED
@@ -4,11 +4,12 @@
4
4
  */
5
5
  import { t } from "elysia";
6
6
  /**
7
- * Export Elysia's TypeBox as DTO builder
8
- * This provides runtime validation for request bodies, queries, params, etc.
7
+ * DTO Builder - Full TypeBox support with IntelliSense
8
+ *
9
+ * Provides runtime validation for request bodies, queries, params, etc.
9
10
  *
10
11
  * @example
11
- * import { DTO } from '@wynkjs/framework';
12
+ * import { DTO } from 'wynkjs';
12
13
  *
13
14
  * export const CreateUserDTO = DTO.Object({
14
15
  * name: DTO.String({ minLength: 2, maxLength: 50 }),
@@ -25,12 +26,34 @@ import { t } from "elysia";
25
26
  * }
26
27
  * }
27
28
  */
28
- // Note: Elysia's type builder exposes internal option types that TypeScript
29
- // cannot emit in d.ts files (TS4023). To keep declaration generation clean
30
- // while preserving runtime behavior, we export DTO with an `any` type.
31
- // Consumers still get runtime validation; for static typing, prefer using
32
- // `Static<TSchema>` from Elysia which we re-export below.
33
29
  export const DTO = t;
30
+ /**
31
+ * Helper to attach strict validation to a DTO Object schema
32
+ * Sets additionalProperties to false which makes Elysia strip unknown fields
33
+ *
34
+ * NOTE: Elysia's default behavior is to STRIP additional properties, not throw errors.
35
+ * This is secure by default. If you need to throw errors on unknown properties,
36
+ * use the approach documented in STRICT_VALIDATION.md
37
+ *
38
+ * @param properties - Object properties schema
39
+ * @param options - Additional schema options
40
+ * @returns TypeBox schema with additionalProperties: false
41
+ *
42
+ * @example
43
+ * export const UserDTO = DTO.Strict({
44
+ * email: DTO.String(),
45
+ * age: DTO.Number()
46
+ * });
47
+ *
48
+ * // Request: { email: "test@test.com", age: 25, extra: "field" }
49
+ * // Result: { email: "test@test.com", age: 25 } ← extra stripped (secure)
50
+ */
51
+ DTO.Strict = (properties, options = {}) => {
52
+ return t.Object(properties, {
53
+ ...options,
54
+ additionalProperties: false,
55
+ });
56
+ };
34
57
  /**
35
58
  * Common DTO patterns for quick use
36
59
  */
@@ -41,8 +64,13 @@ export const CommonDTO = {
41
64
  Name: (options = {}) => t.String({ minLength: 2, maxLength: 50, ...options }),
42
65
  /**
43
66
  * Email validation
67
+ * Uses format: email which validates basic email structure
44
68
  */
45
- Email: (options = {}) => t.String({ format: "email", ...options }),
69
+ Email: (options = {}) => t.String({
70
+ format: "email",
71
+ error: "Invalid email address",
72
+ ...options,
73
+ }),
46
74
  /**
47
75
  * Password validation (min 6 characters)
48
76
  */
package/dist/factory.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Elysia } from "elysia";
2
2
  import "reflect-metadata";
3
+ import { ErrorFormatter } from "./decorators/exception.advanced";
3
4
  /**
4
5
  * Application Factory for WynkJS Framework
5
6
  * Creates and configures Elysia app with all decorators support
@@ -8,6 +9,7 @@ export interface ApplicationOptions {
8
9
  cors?: boolean | any;
9
10
  globalPrefix?: string;
10
11
  logger?: boolean;
12
+ validationErrorFormatter?: ErrorFormatter;
11
13
  }
12
14
  export declare class WynkFramework {
13
15
  private app;
@@ -16,6 +18,7 @@ export declare class WynkFramework {
16
18
  private globalInterceptors;
17
19
  private globalPipes;
18
20
  private globalFilters;
21
+ private validationFormatter?;
19
22
  constructor(options?: ApplicationOptions);
20
23
  /**
21
24
  * Static convenience creator to align with documentation examples
@@ -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;;;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;CAClB;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;gBAEtB,OAAO,GAAE,kBAAuB;IAgB5C;;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,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"}
package/dist/factory.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Elysia } from "elysia";
2
2
  import "reflect-metadata";
3
3
  import { container } from "tsyringe";
4
+ import { Value } from "@sinclair/typebox/value";
4
5
  import { createExecutionContext, executeGuards, } from "./decorators/guard.decorators";
5
6
  import { executeInterceptors } from "./decorators/interceptor.decorators";
6
7
  import { executePipes } from "./decorators/pipe.decorators";
@@ -12,8 +13,94 @@ export class WynkFramework {
12
13
  globalInterceptors = [];
13
14
  globalPipes = [];
14
15
  globalFilters = [];
16
+ validationFormatter;
15
17
  constructor(options = {}) {
16
18
  this.app = new Elysia();
19
+ this.validationFormatter = options.validationErrorFormatter;
20
+ // Configure Elysia's error handling for validation errors
21
+ this.app.onError(({ code, error, set }) => {
22
+ // Handle ValidationError from Elysia
23
+ if (code === "VALIDATION" ||
24
+ error?.constructor?.name === "ValidationError") {
25
+ const validationError = error;
26
+ set.status = 400;
27
+ // Try to collect all validation errors using TypeBox
28
+ const allErrors = {};
29
+ // Check if we have the validator and value to collect all errors
30
+ if (validationError.validator && validationError.value) {
31
+ const schema = validationError.validator.schema || validationError.validator;
32
+ // Use TypeBox's Errors iterator to collect ALL validation errors
33
+ try {
34
+ const errors = [...Value.Errors(schema, validationError.value)];
35
+ if (errors.length > 0) {
36
+ errors.forEach((err) => {
37
+ const field = err.path?.replace(/^\//, "") || "unknown";
38
+ if (!allErrors[field]) {
39
+ allErrors[field] = [];
40
+ }
41
+ allErrors[field].push(err.message || "Validation failed");
42
+ });
43
+ }
44
+ else {
45
+ // Fallback to single error
46
+ const field = validationError.valueError?.path?.replace(/^\//, "") ||
47
+ validationError.on ||
48
+ "body";
49
+ const message = validationError.customError ||
50
+ validationError.valueError?.message ||
51
+ "Validation failed";
52
+ allErrors[field] = [message];
53
+ }
54
+ }
55
+ catch (e) {
56
+ // Fallback to single error if TypeBox iteration fails
57
+ const field = validationError.valueError?.path?.replace(/^\//, "") ||
58
+ validationError.on ||
59
+ "body";
60
+ const message = validationError.customError ||
61
+ validationError.valueError?.message ||
62
+ "Validation failed";
63
+ allErrors[field] = [message];
64
+ }
65
+ }
66
+ else {
67
+ // Fallback to single error
68
+ const field = validationError.valueError?.path?.replace(/^\//, "") ||
69
+ validationError.on ||
70
+ "body";
71
+ const message = validationError.customError ||
72
+ validationError.valueError?.message ||
73
+ "Validation failed";
74
+ allErrors[field] = [message];
75
+ }
76
+ // If a custom formatter is provided, use it
77
+ if (this.validationFormatter) {
78
+ // Convert allErrors to the format expected by formatters
79
+ const formattedError = {
80
+ errors: Object.entries(allErrors).map(([field, messages]) => ({
81
+ path: `/${field}`,
82
+ summary: messages[0],
83
+ message: messages.join(", "),
84
+ })),
85
+ };
86
+ return this.validationFormatter.format(formattedError);
87
+ }
88
+ // Default format: { statusCode, message, errors: { field: [messages] } }
89
+ return {
90
+ statusCode: 400,
91
+ message: "Validation failed",
92
+ errors: allErrors,
93
+ };
94
+ }
95
+ // Default error handling
96
+ const err = error;
97
+ set.status = err.status || 500;
98
+ return {
99
+ statusCode: err.status || 500,
100
+ message: err.message || "Internal server error",
101
+ error: err.name || "Error",
102
+ };
103
+ });
17
104
  // Apply CORS if enabled
18
105
  if (options.cors) {
19
106
  // CORS configuration would go here
package/dist/index.d.ts CHANGED
@@ -5,6 +5,10 @@
5
5
  * @author WynkJS Team
6
6
  * @license MIT
7
7
  */
8
+ import "reflect-metadata";
9
+ export { injectable, inject, singleton, autoInjectable, registry, container, } from "tsyringe";
10
+ export type { DependencyContainer } from "tsyringe";
11
+ export { injectable as Injectable, inject as Inject, singleton as Singleton, autoInjectable as AutoInjectable, registry as Registry, container as Container, } from "tsyringe";
8
12
  export * from "./decorators/http.decorators";
9
13
  export * from "./decorators/param.decorators";
10
14
  export * from "./decorators/guard.decorators";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,cAAc,8BAA8B,CAAC;AAG7C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAI3C,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAIhD,cAAc,kCAAkC,CAAC;AASjD,cAAc,OAAO,CAAC;AAGtB,cAAc,WAAW,CAAC;AAE1B;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,kBAAkB,CAAC;AAI1B,OAAO,EACL,UAAU,EACV,MAAM,EACN,SAAS,EACT,cAAc,EACd,QAAQ,EACR,SAAS,GACV,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpD,OAAO,EACL,UAAU,IAAI,UAAU,EACxB,MAAM,IAAI,MAAM,EAChB,SAAS,IAAI,SAAS,EACtB,cAAc,IAAI,cAAc,EAChC,QAAQ,IAAI,QAAQ,EACpB,SAAS,IAAI,SAAS,GACvB,MAAM,UAAU,CAAC;AAGlB,cAAc,8BAA8B,CAAC;AAG7C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAI3C,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAIhD,cAAc,kCAAkC,CAAC;AASjD,cAAc,OAAO,CAAC;AAGtB,cAAc,WAAW,CAAC;AAE1B;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC"}