wynkjs 1.0.4 → 1.0.7

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 (46) hide show
  1. package/README.md +361 -315
  2. package/dist/cors.d.ts +28 -0
  3. package/dist/cors.d.ts.map +1 -0
  4. package/dist/cors.js +121 -0
  5. package/dist/decorators/exception.decorators.d.ts +1 -0
  6. package/dist/decorators/exception.decorators.d.ts.map +1 -1
  7. package/dist/decorators/exception.decorators.js +20 -3
  8. package/dist/decorators/guard.decorators.d.ts.map +1 -1
  9. package/dist/decorators/guard.decorators.js +11 -5
  10. package/dist/decorators/http.decorators.d.ts +8 -3
  11. package/dist/decorators/http.decorators.d.ts.map +1 -1
  12. package/dist/decorators/http.decorators.js +9 -2
  13. package/dist/decorators/interceptor.advanced.d.ts +9 -9
  14. package/dist/decorators/interceptor.advanced.d.ts.map +1 -1
  15. package/dist/decorators/interceptor.advanced.js +7 -7
  16. package/dist/decorators/interceptor.decorators.d.ts +9 -7
  17. package/dist/decorators/interceptor.decorators.d.ts.map +1 -1
  18. package/dist/decorators/interceptor.decorators.js +29 -18
  19. package/dist/decorators/param.decorators.d.ts +2 -2
  20. package/dist/decorators/param.decorators.js +1 -1
  21. package/dist/decorators/pipe.decorators.d.ts +2 -2
  22. package/dist/decorators/pipe.decorators.js +2 -2
  23. package/dist/factory.d.ts +62 -1
  24. package/dist/factory.d.ts.map +1 -1
  25. package/dist/factory.js +191 -180
  26. package/dist/global-prefix.d.ts +49 -0
  27. package/dist/global-prefix.d.ts.map +1 -0
  28. package/dist/global-prefix.js +155 -0
  29. package/dist/index.d.ts +6 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +4 -0
  32. package/dist/interfaces/interceptor.interface.d.ts +15 -0
  33. package/dist/interfaces/interceptor.interface.d.ts.map +1 -0
  34. package/dist/interfaces/interceptor.interface.js +1 -0
  35. package/dist/optimized-handler.d.ts +31 -0
  36. package/dist/optimized-handler.d.ts.map +1 -0
  37. package/dist/optimized-handler.js +180 -0
  38. package/dist/pipes/validation.pipe.d.ts +10 -10
  39. package/dist/pipes/validation.pipe.js +4 -4
  40. package/dist/plugins/compression.d.ts +75 -0
  41. package/dist/plugins/compression.d.ts.map +1 -0
  42. package/dist/plugins/compression.js +125 -0
  43. package/dist/ultra-optimized-handler.d.ts +51 -0
  44. package/dist/ultra-optimized-handler.d.ts.map +1 -0
  45. package/dist/ultra-optimized-handler.js +302 -0
  46. package/package.json +17 -10
package/dist/cors.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { Elysia } from "elysia";
2
+ /**
3
+ * CORS Configuration Module for WynkJS Framework
4
+ * Separated from factory.ts for better maintainability
5
+ */
6
+ export interface CorsOptions {
7
+ origin?: string | string[] | RegExp | ((origin: string) => boolean | Promise<boolean>);
8
+ methods?: string | string[];
9
+ allowedHeaders?: string | string[];
10
+ exposedHeaders?: string | string[];
11
+ credentials?: boolean;
12
+ maxAge?: number;
13
+ preflight?: boolean;
14
+ }
15
+ /**
16
+ * Setup CORS for Elysia application
17
+ * @param app - Elysia instance
18
+ * @param corsOptions - CORS configuration (true for defaults, or custom config)
19
+ * @throws Error if @elysiajs/cors is not installed
20
+ */
21
+ export declare function setupCors(app: Elysia, corsOptions: boolean | CorsOptions): void;
22
+ /**
23
+ * Validate CORS configuration
24
+ * @param corsOptions - CORS configuration to validate
25
+ * @returns true if valid, throws error if invalid
26
+ */
27
+ export declare function validateCorsOptions(corsOptions: boolean | CorsOptions): boolean;
28
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../core/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EACH,MAAM,GACN,MAAM,EAAE,GACR,MAAM,GACN,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,OAAO,GAAG,WAAW,GACjC,IAAI,CA2EN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,OAAO,GAAG,WAAW,GACjC,OAAO,CA2DT"}
package/dist/cors.js ADDED
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Setup CORS for Elysia application
3
+ * @param app - Elysia instance
4
+ * @param corsOptions - CORS configuration (true for defaults, or custom config)
5
+ * @throws Error if @elysiajs/cors is not installed
6
+ */
7
+ export function setupCors(app, corsOptions) {
8
+ try {
9
+ // Try to import @elysiajs/cors
10
+ const { cors } = require("@elysiajs/cors");
11
+ if (corsOptions === true) {
12
+ // Simple CORS - allow all origins
13
+ app.use(cors());
14
+ console.log("✅ CORS enabled (all origins allowed)");
15
+ }
16
+ else if (typeof corsOptions === "object") {
17
+ // Advanced CORS configuration
18
+ const config = {};
19
+ // Handle origin option (supports function, string, array, RegExp)
20
+ if (typeof corsOptions.origin === "function") {
21
+ // Convert function to Elysia's format
22
+ const originFn = corsOptions.origin;
23
+ config.origin = async (request) => {
24
+ const origin = request.headers.get("origin") || "";
25
+ const allowed = await originFn(origin);
26
+ return allowed ? origin : false;
27
+ };
28
+ }
29
+ else if (corsOptions.origin) {
30
+ config.origin = corsOptions.origin;
31
+ }
32
+ // Methods
33
+ if (corsOptions.methods) {
34
+ config.methods = Array.isArray(corsOptions.methods)
35
+ ? corsOptions.methods.join(",")
36
+ : corsOptions.methods;
37
+ }
38
+ // Allowed headers
39
+ if (corsOptions.allowedHeaders) {
40
+ config.allowedHeaders = Array.isArray(corsOptions.allowedHeaders)
41
+ ? corsOptions.allowedHeaders.join(",")
42
+ : corsOptions.allowedHeaders;
43
+ }
44
+ // Exposed headers
45
+ if (corsOptions.exposedHeaders) {
46
+ config.exposedHeaders = Array.isArray(corsOptions.exposedHeaders)
47
+ ? corsOptions.exposedHeaders.join(",")
48
+ : corsOptions.exposedHeaders;
49
+ }
50
+ // Credentials
51
+ if (corsOptions.credentials !== undefined) {
52
+ config.credentials = corsOptions.credentials;
53
+ }
54
+ // Max age
55
+ if (corsOptions.maxAge !== undefined) {
56
+ config.maxAge = corsOptions.maxAge;
57
+ }
58
+ // Preflight
59
+ if (corsOptions.preflight !== undefined) {
60
+ config.preflight = corsOptions.preflight;
61
+ }
62
+ app.use(cors(config));
63
+ console.log("✅ CORS enabled with custom configuration");
64
+ }
65
+ }
66
+ catch (error) {
67
+ console.error("❌ Failed to enable CORS: @elysiajs/cors package not found");
68
+ console.error(" Install it with: bun add @elysiajs/cors");
69
+ console.error(" Or remove cors option from ApplicationOptions to skip CORS setup");
70
+ throw new Error("CORS configuration failed: @elysiajs/cors package is required");
71
+ }
72
+ }
73
+ /**
74
+ * Validate CORS configuration
75
+ * @param corsOptions - CORS configuration to validate
76
+ * @returns true if valid, throws error if invalid
77
+ */
78
+ export function validateCorsOptions(corsOptions) {
79
+ if (typeof corsOptions === "boolean") {
80
+ return true;
81
+ }
82
+ if (typeof corsOptions === "object") {
83
+ // Validate origin
84
+ if (corsOptions.origin !== undefined) {
85
+ const validOriginTypes = [
86
+ "string",
87
+ "function",
88
+ "object", // array or RegExp
89
+ ];
90
+ const originType = typeof corsOptions.origin;
91
+ if (!validOriginTypes.includes(originType)) {
92
+ throw new Error(`Invalid CORS origin type: ${originType}. Must be string, array, RegExp, or function.`);
93
+ }
94
+ // Validate array of strings
95
+ if (Array.isArray(corsOptions.origin)) {
96
+ if (!corsOptions.origin.every((o) => typeof o === "string")) {
97
+ throw new Error("CORS origin array must contain only strings (URLs)");
98
+ }
99
+ }
100
+ }
101
+ // Validate methods
102
+ if (corsOptions.methods !== undefined) {
103
+ if (typeof corsOptions.methods !== "string" &&
104
+ !Array.isArray(corsOptions.methods)) {
105
+ throw new Error("CORS methods must be string or array of strings");
106
+ }
107
+ }
108
+ // Validate maxAge
109
+ if (corsOptions.maxAge !== undefined &&
110
+ typeof corsOptions.maxAge !== "number") {
111
+ throw new Error("CORS maxAge must be a number");
112
+ }
113
+ // Validate credentials
114
+ if (corsOptions.credentials !== undefined &&
115
+ typeof corsOptions.credentials !== "boolean") {
116
+ throw new Error("CORS credentials must be a boolean");
117
+ }
118
+ return true;
119
+ }
120
+ throw new Error("CORS options must be boolean or CorsOptions object");
121
+ }
@@ -42,6 +42,7 @@ export declare class HttpException extends Error {
42
42
  readonly statusCode: number;
43
43
  readonly error?: string | undefined;
44
44
  constructor(message: string, statusCode: number, error?: string | undefined);
45
+ get status(): number;
45
46
  getStatus(): number;
46
47
  getResponse(): any;
47
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"exception.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/exception.decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,GAAG;IAC1C,KAAK,CAAC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,gBAAgB,GAAG,GAAG,CAAC;CACrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,cAAc,CAK1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CACxB,GAAG,OAAO,EAAE,CAAC,QAAQ,GAAG,mBAAmB,CAAC,EAAE,GAC7C,eAAe,GAAG,cAAc,CAwBlC;AAED;;GAEG;AAEH,qBAAa,aAAc,SAAQ,KAAK;aAEpB,OAAO,EAAE,MAAM;aACf,UAAU,EAAE,MAAM;aAClB,KAAK,CAAC,EAAE,MAAM;gBAFd,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,YAAA;IAMhC,SAAS,IAAI,MAAM;IAInB,WAAW,IAAI,GAAG;CAOnB;AAED,qBAAa,mBAAoB,SAAQ,aAAa;gBACxC,OAAO,GAAE,MAAsB;CAG5C;AAED,qBAAa,qBAAsB,SAAQ,aAAa;gBAC1C,OAAO,GAAE,MAAuB;CAG7C;AAED,qBAAa,kBAAmB,SAAQ,aAAa;gBACvC,OAAO,GAAE,MAAoB;CAG1C;AAED,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,OAAO,GAAE,MAAoB;CAG1C;AAED,qBAAa,yBAA0B,SAAQ,aAAa;gBAC9C,OAAO,GAAE,MAA6B;CAGnD;AAED,qBAAa,sBAAuB,SAAQ,aAAa;gBAC3C,OAAO,GAAE,MAAyB;CAG/C;AAED,qBAAa,uBAAwB,SAAQ,aAAa;gBAC5C,OAAO,GAAE,MAA0B;CAGhD;AAED,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,OAAO,GAAE,MAAmB;CAGzC;AAED,qBAAa,sBAAuB,SAAQ,aAAa;gBAC3C,OAAO,GAAE,MAAkC;CAGxD;AAED,qBAAa,aAAc,SAAQ,aAAa;gBAClC,OAAO,GAAE,MAAe;CAGrC;AAED,qBAAa,wBAAyB,SAAQ,aAAa;gBAC7C,OAAO,GAAE,MAA4B;CAGlD;AAED,qBAAa,6BAA8B,SAAQ,aAAa;gBAClD,OAAO,GAAE,MAAiC;CAGvD;AAED,qBAAa,4BAA6B,SAAQ,aAAa;gBACjD,OAAO,GAAE,MAA+B;CAGrD;AAED,qBAAa,4BAA6B,SAAQ,aAAa;gBACjD,OAAO,GAAE,MAAgC;CAGtD;AAED,qBAAa,uBAAwB,SAAQ,aAAa;gBAC5C,OAAO,GAAE,MAA0B;CAGhD;AAED,qBAAa,mBAAoB,SAAQ,aAAa;gBACxC,OAAO,GAAE,MAAsB;CAG5C;AAED,qBAAa,2BAA4B,SAAQ,aAAa;gBAChD,OAAO,GAAE,MAA8B;CAGpD;AAED,qBAAa,uBAAwB,SAAQ,aAAa;gBAC5C,OAAO,GAAE,MAA0B;CAGhD;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,CAAC,QAAQ,GAAG,mBAAmB,CAAC,EAAE,EAC3C,SAAS,EAAE,GAAG,EACd,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,GAAG,CAAC,CA+Bd;AAED;;GAEG;AAEH;;GAEG;AACH,qBACa,uBACX,YAAW,mBAAmB,CAAC,aAAa,CAAC;IAE7C,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB;CAU1D;AAED;;GAEG;AACH,qBACa,aAAc,YAAW,mBAAmB;IACvD,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;CAoBhD;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,uBACX,YAAW,mBAAmB,CAAC,qBAAqB,CAAC;IAErD,KAAK,CAAC,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAalE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBACX,YAAW,mBAAmB,CAAC,kBAAkB,CAAC;IAElD,KAAK,CAAC,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;CAe/D;AAID;;;;;;GAMG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAC5D,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;;CAmBhD;AAED;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,mBAAmB;IAChE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB;;;;;;;;;CAmBhD"}
1
+ {"version":3,"file":"exception.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/exception.decorators.ts"],"names":[],"mappings":"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"}
@@ -63,6 +63,9 @@ export class HttpException extends Error {
63
63
  this.error = error;
64
64
  this.name = "HttpException";
65
65
  }
66
+ get status() {
67
+ return this.statusCode;
68
+ }
66
69
  getStatus() {
67
70
  return this.statusCode;
68
71
  }
@@ -179,13 +182,27 @@ export async function executeExceptionFilters(filters, exception, context) {
179
182
  // Check if filter handles this exception type
180
183
  const catchTypes = Reflect.getMetadata("catch:exceptions", filterInstance.constructor);
181
184
  if (!catchTypes || catchTypes.length === 0) {
182
- // Catches all exceptions
183
- return filterInstance.catch(exception, context);
185
+ // Catches all exceptions - try it
186
+ try {
187
+ return await filterInstance.catch(exception, context);
188
+ }
189
+ catch (err) {
190
+ // Filter didn't handle it, try next filter
191
+ exception = err;
192
+ continue;
193
+ }
184
194
  }
185
195
  // Check if exception matches any of the catch types
186
196
  for (const catchType of catchTypes) {
187
197
  if (exception instanceof catchType) {
188
- return filterInstance.catch(exception, context);
198
+ try {
199
+ return await filterInstance.catch(exception, context);
200
+ }
201
+ catch (err) {
202
+ // Filter didn't handle it, try next filter
203
+ exception = err;
204
+ continue;
205
+ }
189
206
  }
190
207
  }
191
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"guard.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/guard.decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;IACzB,WAAW,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;IAC1B,UAAU,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;IACzB,UAAU,IAAI,QAAQ,CAAC;IACvB,QAAQ,IAAI,GAAG,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,GAAG,MAAM,EAAE,CAAC,QAAQ,GAAG,WAAW,CAAC,EAAE,GACpC,eAAe,GAAG,cAAc,CAwBlC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,QAAQ,EACjB,eAAe,EAAE,GAAG,GACnB,gBAAgB,CAQlB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,CAAC,QAAQ,GAAG,WAAW,CAAC,EAAE,EAClC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,OAAO,CAAC,CAyBlB"}
1
+ {"version":3,"file":"guard.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/guard.decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;IACzB,WAAW,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;IAC1B,UAAU,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;IACzB,UAAU,IAAI,QAAQ,CAAC;IACvB,QAAQ,IAAI,GAAG,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,GAAG,MAAM,EAAE,CAAC,QAAQ,GAAG,WAAW,CAAC,EAAE,GACpC,eAAe,GAAG,cAAc,CAwBlC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,QAAQ,EACjB,eAAe,EAAE,GAAG,GACnB,gBAAgB,CAQlB;AAOD;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,CAAC,QAAQ,GAAG,WAAW,CAAC,EAAE,EAClC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,OAAO,CAAC,CA8BlB"}
@@ -39,6 +39,10 @@ export function createExecutionContext(ctx, handler, controllerClass) {
39
39
  getClass: () => controllerClass,
40
40
  };
41
41
  }
42
+ /**
43
+ * Guard instance cache for singleton pattern
44
+ */
45
+ const guardInstanceCache = new Map();
42
46
  /**
43
47
  * Helper function to execute guards
44
48
  */
@@ -46,14 +50,16 @@ export async function executeGuards(guards, context) {
46
50
  for (const guard of guards) {
47
51
  let result;
48
52
  if (typeof guard === "function") {
49
- // Guard is a class, instantiate it
50
- const guardInstance = new guard();
51
- if (guardInstance.canActivate) {
52
- result = await guardInstance.canActivate(context);
53
+ // Guard is a class, get or create singleton instance
54
+ let guardInstance = guardInstanceCache.get(guard);
55
+ if (!guardInstance) {
56
+ guardInstance = new guard();
57
+ guardInstanceCache.set(guard, guardInstance);
53
58
  }
54
- else {
59
+ if (!guardInstance.canActivate) {
55
60
  throw new Error(`Guard ${guard.name} must implement CanActivate interface`);
56
61
  }
62
+ result = await guardInstance.canActivate(context);
57
63
  }
58
64
  else {
59
65
  // Guard is already an instance
@@ -2,7 +2,7 @@ import "reflect-metadata";
2
2
  /**
3
3
  * HTTP Method Decorators for WynkJS Framework
4
4
  * RESTful route handlers with TypeScript decorators
5
- * Optimized for Elysia's performance on Bun runtime
5
+ * Optimized for WynkJS's performance on Bun runtime
6
6
  */
7
7
  export interface RouteOptions {
8
8
  path?: string;
@@ -14,12 +14,17 @@ export interface RouteOptions {
14
14
  }
15
15
  /**
16
16
  * Controller decorator - Defines a controller with a base path
17
- * @param path Base path for all routes in this controller
17
+ * @param pathOrOptions Base path string or options object with path
18
18
  * @example
19
19
  * @Controller('/users')
20
20
  * export class UserController {}
21
+ *
22
+ * @Controller({ path: '/users' })
23
+ * export class UserController {}
21
24
  */
22
- export declare function Controller(path?: string): ClassDecorator;
25
+ export declare function Controller(pathOrOptions?: string | {
26
+ path?: string;
27
+ }): ClassDecorator;
23
28
  /**
24
29
  * HTTP GET decorator
25
30
  * @param pathOrOptions Route path or options with DTO
@@ -1 +1 @@
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"}
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;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,aAAa,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,cAAc,CAWhB;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,13 +1,20 @@
1
1
  import "reflect-metadata";
2
2
  /**
3
3
  * Controller decorator - Defines a controller with a base path
4
- * @param path Base path for all routes in this controller
4
+ * @param pathOrOptions Base path string or options object with path
5
5
  * @example
6
6
  * @Controller('/users')
7
7
  * export class UserController {}
8
+ *
9
+ * @Controller({ path: '/users' })
10
+ * export class UserController {}
8
11
  */
9
- export function Controller(path = "") {
12
+ export function Controller(pathOrOptions) {
10
13
  return (target) => {
14
+ // Handle both string and object formats
15
+ const path = typeof pathOrOptions === "string"
16
+ ? pathOrOptions
17
+ : pathOrOptions?.path || "";
11
18
  Reflect.defineMetadata("basePath", path, target);
12
19
  Reflect.defineMetadata("routes", [], target);
13
20
  };
@@ -1,6 +1,6 @@
1
1
  import "reflect-metadata";
2
- import { WynkInterceptor, CallHandler } from "./interceptor.decorators";
3
- import { ExecutionContext } from "./guard.decorators";
2
+ import { WynkInterceptor } from "./interceptor.decorators";
3
+ import { InterceptorContext } from "../interfaces/interceptor.interface";
4
4
  /**
5
5
  * Advanced Interceptors for WynkJS Framework
6
6
  * Additional interceptors for common use cases
@@ -13,7 +13,7 @@ import { ExecutionContext } from "./guard.decorators";
13
13
  * export class ApiController {}
14
14
  */
15
15
  export declare class ResponseInterceptor implements WynkInterceptor {
16
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
16
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
17
17
  }
18
18
  /**
19
19
  * Error Handling Interceptor - Catches and transforms errors
@@ -23,7 +23,7 @@ export declare class ResponseInterceptor implements WynkInterceptor {
23
23
  * async getData() {}
24
24
  */
25
25
  export declare class ErrorHandlingInterceptor implements WynkInterceptor {
26
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
26
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
27
27
  }
28
28
  /**
29
29
  * Compression Interceptor - Simulates response compression metadata
@@ -35,7 +35,7 @@ export declare class ErrorHandlingInterceptor implements WynkInterceptor {
35
35
  export declare class CompressionInterceptor implements WynkInterceptor {
36
36
  private threshold;
37
37
  constructor(threshold?: number);
38
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
38
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
39
39
  }
40
40
  /**
41
41
  * Rate Limit Interceptor - Basic rate limiting
@@ -49,7 +49,7 @@ export declare class RateLimitInterceptor implements WynkInterceptor {
49
49
  private windowMs;
50
50
  private requests;
51
51
  constructor(maxRequests?: number, windowMs?: number);
52
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
52
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
53
53
  }
54
54
  /**
55
55
  * CORS Interceptor - Add CORS headers to responses
@@ -65,7 +65,7 @@ export declare class CorsInterceptor implements WynkInterceptor {
65
65
  methods?: string[];
66
66
  credentials?: boolean;
67
67
  });
68
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
68
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
69
69
  }
70
70
  /**
71
71
  * Sanitize Interceptor - Sanitizes response data
@@ -77,7 +77,7 @@ export declare class CorsInterceptor implements WynkInterceptor {
77
77
  export declare class SanitizeInterceptor implements WynkInterceptor {
78
78
  private fieldsToRemove;
79
79
  constructor(fieldsToRemove?: string[]);
80
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
80
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
81
81
  private sanitize;
82
82
  }
83
83
  /**
@@ -88,6 +88,6 @@ export declare class SanitizeInterceptor implements WynkInterceptor {
88
88
  * async getUsers(@Query('page') page: number, @Query('limit') limit: number) {}
89
89
  */
90
90
  export declare class PaginationInterceptor implements WynkInterceptor {
91
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
91
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
92
92
  }
93
93
  //# sourceMappingURL=interceptor.advanced.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interceptor.advanced.d.ts","sourceRoot":"","sources":["../../core/decorators/interceptor.advanced.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AAEH;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACnD,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAsC5E;AAED;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,eAAe;IACxD,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAkB5E;AAED;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAChD,OAAO,CAAC,SAAS;gBAAT,SAAS,GAAE,MAAa;IAEtC,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAa5E;AAED;;;;;;GAMG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAIxD,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ;IAJlB,OAAO,CAAC,QAAQ,CAAoC;gBAG1C,WAAW,GAAE,MAAY,EACzB,QAAQ,GAAE,MAAc;IAG5B,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CA0B5E;AAED;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,eAAe;IAEnD,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE;QACf,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,WAAW,CAAC,EAAE,OAAO,CAAC;KAClB;IAGF,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CA8B5E;AAED;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,cAAc,CAAW;gBAErB,cAAc,GAAE,MAAM,EAAoC;IAIhE,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAK3E,OAAO,CAAC,QAAQ;CAmBjB;AAED;;;;;;GAMG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IACrD,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CA2B5E"}
1
+ {"version":3,"file":"interceptor.advanced.d.ts","sourceRoot":"","sources":["../../core/decorators/interceptor.advanced.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE;;;GAGG;AAEH;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACnD,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CAsChB;AAED;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,eAAe;IACxD,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CAoBhB;AAED;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAChD,OAAO,CAAC,SAAS;gBAAT,SAAS,GAAE,MAAa;IAEtC,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CAahB;AAED;;;;;;GAMG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAIxD,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ;IAJlB,OAAO,CAAC,QAAQ,CAAoC;gBAG1C,WAAW,GAAE,MAAY,EACzB,QAAQ,GAAE,MAAc;IAG5B,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CA0BhB;AAED;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,eAAe;IAEnD,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE;QACf,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,WAAW,CAAC,EAAE,OAAO,CAAC;KAClB;IAGF,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CA8BhB;AAED;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,cAAc,CAAW;gBAErB,cAAc,GAAE,MAAM,EAAoC;IAIhE,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;IAKf,OAAO,CAAC,QAAQ;CAmBjB;AAED;;;;;;GAMG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IACrD,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CA2BhB"}
@@ -15,7 +15,7 @@ export class ResponseInterceptor {
15
15
  const request = context.getRequest();
16
16
  const startTime = Date.now();
17
17
  try {
18
- const data = await next.handle();
18
+ const data = await next();
19
19
  const duration = Date.now() - startTime;
20
20
  return {
21
21
  success: true,
@@ -58,7 +58,7 @@ export class ResponseInterceptor {
58
58
  export class ErrorHandlingInterceptor {
59
59
  async intercept(context, next) {
60
60
  try {
61
- return await next.handle();
61
+ return await next();
62
62
  }
63
63
  catch (error) {
64
64
  console.error(`❌ Error in ${context.getRequest().method} ${context.getRequest().url}:`, error);
@@ -85,7 +85,7 @@ export class CompressionInterceptor {
85
85
  this.threshold = threshold;
86
86
  }
87
87
  async intercept(context, next) {
88
- const data = await next.handle();
88
+ const data = await next();
89
89
  const dataSize = JSON.stringify(data).length;
90
90
  if (dataSize > this.threshold) {
91
91
  // In a real implementation, you'd compress the data here
@@ -128,7 +128,7 @@ export class RateLimitInterceptor {
128
128
  // Add current request
129
129
  history.push(now);
130
130
  this.requests.set(clientIp, history);
131
- return next.handle();
131
+ return next();
132
132
  }
133
133
  }
134
134
  /**
@@ -162,7 +162,7 @@ export class CorsInterceptor {
162
162
  response.headers.set("Access-Control-Allow-Credentials", "true");
163
163
  }
164
164
  }
165
- return next.handle();
165
+ return next();
166
166
  }
167
167
  }
168
168
  /**
@@ -178,7 +178,7 @@ export class SanitizeInterceptor {
178
178
  this.fieldsToRemove = fieldsToRemove;
179
179
  }
180
180
  async intercept(context, next) {
181
- const data = await next.handle();
181
+ const data = await next();
182
182
  return this.sanitize(data);
183
183
  }
184
184
  sanitize(data) {
@@ -210,7 +210,7 @@ export class PaginationInterceptor {
210
210
  const url = new URL(request.url, `http://${request.headers?.get?.("host")}`);
211
211
  const page = parseInt(url.searchParams.get("page") || "1");
212
212
  const limit = parseInt(url.searchParams.get("limit") || "10");
213
- const data = await next.handle();
213
+ const data = await next();
214
214
  // If data is an array, add pagination
215
215
  if (Array.isArray(data)) {
216
216
  return {
@@ -1,5 +1,6 @@
1
1
  import "reflect-metadata";
2
- import { ExecutionContext } from "./guard.decorators";
2
+ import { InterceptorContext } from "../interfaces/interceptor.interface";
3
+ type ExecutionContext = InterceptorContext;
3
4
  /**
4
5
  * Interceptor Decorators and Interfaces for WynkJS Framework
5
6
  * Interceptors for request/response transformation
@@ -14,7 +15,7 @@ export interface CallHandler<T = any> {
14
15
  * WynkInterceptor interface - All interceptors must implement this
15
16
  */
16
17
  export interface WynkInterceptor {
17
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
18
+ intercept(context: ExecutionContext, next: () => Promise<any>): Promise<any>;
18
19
  }
19
20
  /**
20
21
  * @UseInterceptors decorator - Apply interceptors to routes or controllers
@@ -32,7 +33,7 @@ export declare function UseInterceptors(...interceptors: (Function | WynkInterce
32
33
  /**
33
34
  * Helper function to execute interceptors
34
35
  */
35
- export declare function executeInterceptors(interceptors: (Function | WynkInterceptor)[], context: ExecutionContext, handler: () => Promise<any>): Promise<any>;
36
+ export declare function executeInterceptors(interceptors: (Function | WynkInterceptor)[], context: InterceptorContext, handler: () => Promise<any>): Promise<any>;
36
37
  /**
37
38
  * Common interceptor utilities
38
39
  */
@@ -50,7 +51,7 @@ export declare function executeInterceptors(interceptors: (Function | WynkInterc
50
51
  export declare class TransformInterceptor implements WynkInterceptor {
51
52
  private transformFn?;
52
53
  constructor(transformFn?: ((data: any) => any) | undefined);
53
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
54
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
54
55
  }
55
56
  /**
56
57
  * Timeout interceptor - Adds timeout to requests
@@ -63,7 +64,7 @@ export declare class TransformInterceptor implements WynkInterceptor {
63
64
  export declare class TimeoutInterceptor implements WynkInterceptor {
64
65
  private timeout;
65
66
  constructor(timeout?: number);
66
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
67
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
67
68
  }
68
69
  /**
69
70
  * Cache interceptor - Caches responses
@@ -76,7 +77,7 @@ export declare class CacheInterceptor implements WynkInterceptor {
76
77
  private cache;
77
78
  private ttl;
78
79
  constructor(ttl?: number);
79
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
80
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
80
81
  }
81
82
  /**
82
83
  * Logging interceptor - Logs requests and responses
@@ -86,6 +87,7 @@ export declare class CacheInterceptor implements WynkInterceptor {
86
87
  * export class AppController {}
87
88
  */
88
89
  export declare class LoggingInterceptor implements WynkInterceptor {
89
- intercept(context: ExecutionContext, next: CallHandler): Promise<any>;
90
+ intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
90
91
  }
92
+ export {};
91
93
  //# sourceMappingURL=interceptor.decorators.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interceptor.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/interceptor.decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,GAAG,YAAY,EAAE,CAAC,QAAQ,GAAG,eAAe,CAAC,EAAE,GAC9C,eAAe,GAAG,cAAc,CA4BlC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,CAAC,QAAQ,GAAG,eAAe,CAAC,EAAE,EAC5C,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GAC1B,OAAO,CAAC,GAAG,CAAC,CA+Bd;AAED;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAC9C,OAAO,CAAC,WAAW,CAAC;gBAAZ,WAAW,CAAC,GAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,aAAA;IAE9C,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAa5E;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IAC5C,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE,MAAa;IAEpC,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAQ5E;AAED;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,KAAK,CAAuD;IACpE,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,GAAE,MAAc;IAIzB,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAgB5E;AAED;;;;;;GAMG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IAClD,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAqB5E"}
1
+ {"version":3,"file":"interceptor.decorators.d.ts","sourceRoot":"","sources":["../../core/decorators/interceptor.decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAIzE,KAAK,gBAAgB,GAAG,kBAAkB,CAAC;AAK3C;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC9E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,GAAG,YAAY,EAAE,CAAC,QAAQ,GAAG,eAAe,CAAC,EAAE,GAC9C,eAAe,GAAG,cAAc,CA4BlC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,CAAC,QAAQ,GAAG,eAAe,CAAC,EAAE,EAC5C,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GAC1B,OAAO,CAAC,GAAG,CAAC,CAyCd;AAED;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAC9C,OAAO,CAAC,WAAW,CAAC;gBAAZ,WAAW,CAAC,GAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,aAAA;IAE9C,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CAahB;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IAC5C,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE,MAAa;IAEpC,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CAQhB;AAED;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,KAAK,CAAuD;IACpE,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,GAAE,MAAc;IAIzB,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CAgBhB;AAED;;;;;;GAMG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IAClD,SAAS,CACb,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,GAAG,CAAC;CAqBhB"}
@@ -1,4 +1,7 @@
1
1
  import "reflect-metadata";
2
+ import { container } from "tsyringe";
3
+ // Store singleton interceptor instances
4
+ const interceptorInstances = new Map();
2
5
  /**
3
6
  * @UseInterceptors decorator - Apply interceptors to routes or controllers
4
7
  * @param interceptors Interceptor classes to apply
@@ -31,17 +34,27 @@ export function UseInterceptors(...interceptors) {
31
34
  * Helper function to execute interceptors
32
35
  */
33
36
  export async function executeInterceptors(interceptors, context, handler) {
34
- // Build interceptor chain from last to first
35
- let next = {
36
- handle: async () => handler(),
37
- };
38
- // Apply interceptors in reverse order
39
- for (let i = interceptors.length - 1; i >= 0; i--) {
37
+ // Build interceptor chain
38
+ // First interceptor in array is innermost (transforms first, closest to handler)
39
+ // Last interceptor in array is outermost (transforms last, farthest from handler)
40
+ let next = handler;
41
+ // Apply interceptors in FORWARD order
42
+ // First wraps handler, second wraps first, etc.
43
+ for (let i = 0; i < interceptors.length; i++) {
40
44
  const interceptor = interceptors[i];
41
- const currentNext = next;
45
+ const currentNext = next; // Capture current next in closure
42
46
  let interceptorInstance;
43
47
  if (typeof interceptor === "function") {
44
- interceptorInstance = new interceptor();
48
+ // Always use singleton pattern - cache all interceptor instances by class
49
+ if (!interceptorInstances.has(interceptor)) {
50
+ try {
51
+ interceptorInstances.set(interceptor, container.resolve(interceptor));
52
+ }
53
+ catch {
54
+ interceptorInstances.set(interceptor, new interceptor());
55
+ }
56
+ }
57
+ interceptorInstance = interceptorInstances.get(interceptor);
45
58
  }
46
59
  else {
47
60
  interceptorInstance = interceptor;
@@ -49,14 +62,12 @@ export async function executeInterceptors(interceptors, context, handler) {
49
62
  if (!interceptorInstance.intercept) {
50
63
  throw new Error(`Interceptor must implement WynkInterceptor interface`);
51
64
  }
52
- // Create new call handler that wraps the previous one
53
- next = {
54
- handle: async () => {
55
- return interceptorInstance.intercept(context, currentNext);
56
- },
65
+ // Wrap in a function that calls the interceptor
66
+ next = async () => {
67
+ return interceptorInstance.intercept(context, currentNext);
57
68
  };
58
69
  }
59
- return next.handle();
70
+ return next();
60
71
  }
61
72
  /**
62
73
  * Common interceptor utilities
@@ -78,7 +89,7 @@ export class TransformInterceptor {
78
89
  this.transformFn = transformFn;
79
90
  }
80
91
  async intercept(context, next) {
81
- const data = await next.handle();
92
+ const data = await next();
82
93
  if (this.transformFn) {
83
94
  return this.transformFn(data);
84
95
  }
@@ -104,7 +115,7 @@ export class TimeoutInterceptor {
104
115
  }
105
116
  async intercept(context, next) {
106
117
  return Promise.race([
107
- next.handle(),
118
+ next(),
108
119
  new Promise((_, reject) => setTimeout(() => reject(new Error("Request timeout")), this.timeout)),
109
120
  ]);
110
121
  }
@@ -131,7 +142,7 @@ export class CacheInterceptor {
131
142
  return cached.data;
132
143
  }
133
144
  // Execute handler and cache result
134
- const data = await next.handle();
145
+ const data = await next();
135
146
  this.cache.set(cacheKey, { data, timestamp: Date.now() });
136
147
  return data;
137
148
  }
@@ -149,7 +160,7 @@ export class LoggingInterceptor {
149
160
  const startTime = Date.now();
150
161
  console.log(`📥 ${request.method} ${request.url} - Started`);
151
162
  try {
152
- const data = await next.handle();
163
+ const data = await next();
153
164
  const duration = Date.now() - startTime;
154
165
  console.log(`📤 ${request.method} ${request.url} - Completed in ${duration}ms`);
155
166
  return data;