wynkjs 1.0.6 → 1.0.8

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.
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Request Wrapper for WynkJS Framework
3
+ * Provides a clean API for accessing request data and adding custom properties
4
+ */
5
+ /**
6
+ * Request class - wraps Elysia context for request operations
7
+ * Allows middleware to add custom properties that persist through the request lifecycle
8
+ */
9
+ export class Request {
10
+ ctx;
11
+ customData = new Map();
12
+ originalRequest;
13
+ constructor(ctx) {
14
+ this.ctx = ctx;
15
+ // Store reference to original request object before it gets overwritten
16
+ this.originalRequest = ctx.request;
17
+ }
18
+ /**
19
+ * Get request body
20
+ */
21
+ get body() {
22
+ return this.ctx.body;
23
+ }
24
+ /**
25
+ * Get route parameters
26
+ */
27
+ get params() {
28
+ return this.ctx.params;
29
+ }
30
+ /**
31
+ * Get query parameters
32
+ */
33
+ get query() {
34
+ return this.ctx.query;
35
+ }
36
+ /**
37
+ * Get request headers
38
+ */
39
+ get headers() {
40
+ // Get headers from ctx or from the original Elysia request object
41
+ const headers = this.ctx.headers || this.originalRequest?.headers;
42
+ if (!headers)
43
+ return {};
44
+ // If headers is a plain object, wrap it to provide get() method
45
+ if (typeof headers === 'object' && !headers.get) {
46
+ return {
47
+ ...headers,
48
+ get(name) {
49
+ return headers[name] || headers[name.toLowerCase()];
50
+ },
51
+ has(name) {
52
+ return name in headers || name.toLowerCase() in headers;
53
+ }
54
+ };
55
+ }
56
+ return headers;
57
+ }
58
+ /**
59
+ * Get request method (GET, POST, etc.)
60
+ */
61
+ get method() {
62
+ return this.originalRequest?.method || this.ctx.method || "GET";
63
+ }
64
+ /**
65
+ * Get request URL
66
+ */
67
+ get url() {
68
+ return this.originalRequest?.url || this.ctx.url || "";
69
+ }
70
+ /**
71
+ * Get request path
72
+ */
73
+ get path() {
74
+ return this.ctx.path || new URL(this.url).pathname;
75
+ }
76
+ /**
77
+ * Get client IP address
78
+ */
79
+ get ip() {
80
+ return (this.headers.get?.("x-forwarded-for") ||
81
+ this.headers.get?.("x-real-ip") ||
82
+ this.originalRequest?.ip);
83
+ }
84
+ /**
85
+ * Get cookies from request
86
+ */
87
+ get cookies() {
88
+ const cookieHeader = this.headers.get?.("cookie");
89
+ if (!cookieHeader)
90
+ return {};
91
+ const cookies = {};
92
+ cookieHeader.split(";").forEach((cookie) => {
93
+ const [name, ...rest] = cookie.split("=");
94
+ if (name && rest.length > 0) {
95
+ cookies[name.trim()] = rest.join("=").trim();
96
+ }
97
+ });
98
+ return cookies;
99
+ }
100
+ /**
101
+ * Get a specific cookie value
102
+ */
103
+ getCookie(name) {
104
+ return this.cookies[name];
105
+ }
106
+ /**
107
+ * Get user object (set by authentication middleware)
108
+ */
109
+ get user() {
110
+ return this.ctx.user;
111
+ }
112
+ /**
113
+ * Set user object (typically used by authentication middleware)
114
+ */
115
+ set user(value) {
116
+ this.ctx.user = value;
117
+ }
118
+ /**
119
+ * Get the raw Elysia context
120
+ */
121
+ get raw() {
122
+ return this.ctx;
123
+ }
124
+ /**
125
+ * Get the Response wrapper instance
126
+ */
127
+ getResponse() {
128
+ return this.ctx.response;
129
+ }
130
+ /**
131
+ * Set custom data that persists through request lifecycle
132
+ * Useful for middleware to pass data to handlers
133
+ *
134
+ * @example
135
+ * // In middleware
136
+ * request.set('startTime', Date.now());
137
+ *
138
+ * // In handler
139
+ * const startTime = request.get('startTime');
140
+ */
141
+ set(key, value) {
142
+ this.customData.set(key, value);
143
+ // Also set on ctx for backward compatibility
144
+ if (!this.ctx.customData) {
145
+ this.ctx.customData = {};
146
+ }
147
+ this.ctx.customData[key] = value;
148
+ return this;
149
+ }
150
+ /**
151
+ * Get custom data set by middleware
152
+ */
153
+ get(key) {
154
+ return this.customData.get(key) || this.ctx.customData?.[key];
155
+ }
156
+ /**
157
+ * Check if custom data exists
158
+ */
159
+ has(key) {
160
+ return this.customData.has(key) || (this.ctx.customData && key in this.ctx.customData);
161
+ }
162
+ /**
163
+ * Delete custom data
164
+ */
165
+ delete(key) {
166
+ const deleted = this.customData.delete(key);
167
+ if (this.ctx.customData && key in this.ctx.customData) {
168
+ delete this.ctx.customData[key];
169
+ }
170
+ return deleted;
171
+ }
172
+ /**
173
+ * Get all custom data
174
+ */
175
+ getAllCustomData() {
176
+ const data = {};
177
+ this.customData.forEach((value, key) => {
178
+ data[key] = value;
179
+ });
180
+ return { ...data, ...this.ctx.customData };
181
+ }
182
+ /**
183
+ * Check if request accepts a certain content type
184
+ */
185
+ accepts(type) {
186
+ const acceptHeader = this.headers.get?.("accept") || "";
187
+ return acceptHeader.includes(type);
188
+ }
189
+ /**
190
+ * Check if request is JSON
191
+ */
192
+ isJson() {
193
+ const contentType = this.headers.get?.("content-type") || "";
194
+ return contentType.includes("application/json");
195
+ }
196
+ /**
197
+ * Check if request is form data
198
+ */
199
+ isFormData() {
200
+ const contentType = this.headers.get?.("content-type") || "";
201
+ return contentType.includes("multipart/form-data") || contentType.includes("application/x-www-form-urlencoded");
202
+ }
203
+ /**
204
+ * Get bearer token from Authorization header
205
+ */
206
+ getBearerToken() {
207
+ const authHeader = this.headers.get?.("authorization");
208
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
209
+ return undefined;
210
+ }
211
+ return authHeader.substring(7);
212
+ }
213
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Response Wrapper for WynkJS Framework
3
+ * Provides a clean API for setting cookies, headers, status codes, and sending responses
4
+ */
5
+ export interface CookieOptions {
6
+ domain?: string;
7
+ expires?: Date;
8
+ httpOnly?: boolean;
9
+ maxAge?: number;
10
+ path?: string;
11
+ sameSite?: boolean | "lax" | "strict" | "none";
12
+ secure?: boolean;
13
+ priority?: "low" | "medium" | "high";
14
+ partitioned?: boolean;
15
+ }
16
+ /**
17
+ * Response class - wraps Elysia context for response operations
18
+ * Provides methods to set cookies, headers, status codes, and control response behavior
19
+ */
20
+ export declare class Response {
21
+ private ctx;
22
+ private _headers;
23
+ private _cookies;
24
+ private _status?;
25
+ constructor(ctx: any);
26
+ /**
27
+ * Set HTTP status code
28
+ */
29
+ status(code: number): this;
30
+ /**
31
+ * Get current status code
32
+ */
33
+ getStatus(): number;
34
+ /**
35
+ * Set a response header
36
+ */
37
+ header(name: string, value: string): this;
38
+ /**
39
+ * Set multiple headers at once
40
+ */
41
+ headers(headers: Record<string, string>): this;
42
+ /**
43
+ * Get a response header
44
+ */
45
+ getHeader(name: string): string | undefined;
46
+ /**
47
+ * Remove a response header
48
+ */
49
+ removeHeader(name: string): this;
50
+ /**
51
+ * Set a cookie
52
+ *
53
+ * @example
54
+ * response.cookie('sessionId', '12345', {
55
+ * httpOnly: true,
56
+ * secure: true,
57
+ * maxAge: 3600,
58
+ * sameSite: 'strict'
59
+ * });
60
+ */
61
+ cookie(name: string, value: string, options?: CookieOptions): this;
62
+ /**
63
+ * Clear a cookie by setting it to expire immediately
64
+ */
65
+ clearCookie(name: string, options?: Pick<CookieOptions, "domain" | "path">): this;
66
+ /**
67
+ * Get all cookies that have been set
68
+ */
69
+ getCookies(): Map<string, {
70
+ value: string;
71
+ options?: CookieOptions;
72
+ }>;
73
+ /**
74
+ * Send JSON response
75
+ */
76
+ json(data: any): any;
77
+ /**
78
+ * Send HTML response
79
+ */
80
+ html(content: string): string;
81
+ /**
82
+ * Send plain text response
83
+ */
84
+ text(content: string): string;
85
+ /**
86
+ * Redirect to a different URL
87
+ */
88
+ redirect(url: string, statusCode?: number): void;
89
+ /**
90
+ * Set content type
91
+ */
92
+ type(contentType: string): this;
93
+ /**
94
+ * Set cache control
95
+ */
96
+ cache(maxAge: number, options?: {
97
+ private?: boolean;
98
+ noCache?: boolean;
99
+ noStore?: boolean;
100
+ }): this;
101
+ /**
102
+ * Disable caching
103
+ */
104
+ noCache(): this;
105
+ /**
106
+ * Set CORS headers
107
+ */
108
+ cors(options?: {
109
+ origin?: string;
110
+ methods?: string[];
111
+ headers?: string[];
112
+ credentials?: boolean;
113
+ maxAge?: number;
114
+ }): this;
115
+ /**
116
+ * Get the raw Elysia set object
117
+ */
118
+ get raw(): any;
119
+ /**
120
+ * Send a file download
121
+ */
122
+ download(filename: string): this;
123
+ /**
124
+ * Send response with custom status code
125
+ */
126
+ send(data: any, statusCode?: number): any;
127
+ }
128
+ export type WynkResponse = Response;
129
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../core/response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,260 @@
1
+ /**
2
+ * Response Wrapper for WynkJS Framework
3
+ * Provides a clean API for setting cookies, headers, status codes, and sending responses
4
+ */
5
+ /**
6
+ * Response class - wraps Elysia context for response operations
7
+ * Provides methods to set cookies, headers, status codes, and control response behavior
8
+ */
9
+ export class Response {
10
+ ctx;
11
+ _headers = new Map();
12
+ _cookies = new Map();
13
+ _status;
14
+ constructor(ctx) {
15
+ this.ctx = ctx;
16
+ // Initialize Elysia's set object if it doesn't exist
17
+ if (!this.ctx.set) {
18
+ this.ctx.set = {
19
+ headers: {},
20
+ status: 200,
21
+ };
22
+ }
23
+ if (!this.ctx.set.headers) {
24
+ this.ctx.set.headers = {};
25
+ }
26
+ }
27
+ /**
28
+ * Set HTTP status code
29
+ */
30
+ status(code) {
31
+ this._status = code;
32
+ this.ctx.set.status = code;
33
+ return this;
34
+ }
35
+ /**
36
+ * Get current status code
37
+ */
38
+ getStatus() {
39
+ return this._status || this.ctx.set.status || 200;
40
+ }
41
+ /**
42
+ * Set a response header
43
+ */
44
+ header(name, value) {
45
+ this._headers.set(name, value);
46
+ this.ctx.set.headers[name] = value;
47
+ return this;
48
+ }
49
+ /**
50
+ * Set multiple headers at once
51
+ */
52
+ headers(headers) {
53
+ Object.entries(headers).forEach(([name, value]) => {
54
+ this.header(name, value);
55
+ });
56
+ return this;
57
+ }
58
+ /**
59
+ * Get a response header
60
+ */
61
+ getHeader(name) {
62
+ return this._headers.get(name) || this.ctx.set.headers[name];
63
+ }
64
+ /**
65
+ * Remove a response header
66
+ */
67
+ removeHeader(name) {
68
+ this._headers.delete(name);
69
+ delete this.ctx.set.headers[name];
70
+ return this;
71
+ }
72
+ /**
73
+ * Set a cookie
74
+ *
75
+ * @example
76
+ * response.cookie('sessionId', '12345', {
77
+ * httpOnly: true,
78
+ * secure: true,
79
+ * maxAge: 3600,
80
+ * sameSite: 'strict'
81
+ * });
82
+ */
83
+ cookie(name, value, options) {
84
+ this._cookies.set(name, { value, options });
85
+ // Build cookie string
86
+ let cookieString = `${name}=${value}`;
87
+ if (options) {
88
+ if (options.domain) {
89
+ cookieString += `; Domain=${options.domain}`;
90
+ }
91
+ if (options.expires) {
92
+ cookieString += `; Expires=${options.expires.toUTCString()}`;
93
+ }
94
+ if (options.httpOnly) {
95
+ cookieString += "; HttpOnly";
96
+ }
97
+ if (options.maxAge !== undefined) {
98
+ cookieString += `; Max-Age=${options.maxAge}`;
99
+ }
100
+ if (options.path) {
101
+ cookieString += `; Path=${options.path}`;
102
+ }
103
+ else {
104
+ cookieString += "; Path=/"; // Default path
105
+ }
106
+ if (options.sameSite) {
107
+ const sameSiteValue = typeof options.sameSite === "boolean"
108
+ ? "Strict"
109
+ : options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1);
110
+ cookieString += `; SameSite=${sameSiteValue}`;
111
+ }
112
+ if (options.secure) {
113
+ cookieString += "; Secure";
114
+ }
115
+ if (options.priority) {
116
+ cookieString += `; Priority=${options.priority.charAt(0).toUpperCase() + options.priority.slice(1)}`;
117
+ }
118
+ if (options.partitioned) {
119
+ cookieString += "; Partitioned";
120
+ }
121
+ }
122
+ else {
123
+ cookieString += "; Path=/"; // Default path if no options
124
+ }
125
+ // Append to Set-Cookie header (can have multiple)
126
+ const existingSetCookie = this.ctx.set.headers["Set-Cookie"];
127
+ if (existingSetCookie) {
128
+ if (Array.isArray(existingSetCookie)) {
129
+ this.ctx.set.headers["Set-Cookie"] = [...existingSetCookie, cookieString];
130
+ }
131
+ else {
132
+ this.ctx.set.headers["Set-Cookie"] = [existingSetCookie, cookieString];
133
+ }
134
+ }
135
+ else {
136
+ this.ctx.set.headers["Set-Cookie"] = cookieString;
137
+ }
138
+ return this;
139
+ }
140
+ /**
141
+ * Clear a cookie by setting it to expire immediately
142
+ */
143
+ clearCookie(name, options) {
144
+ return this.cookie(name, "", {
145
+ ...options,
146
+ expires: new Date(0),
147
+ maxAge: 0,
148
+ });
149
+ }
150
+ /**
151
+ * Get all cookies that have been set
152
+ */
153
+ getCookies() {
154
+ return this._cookies;
155
+ }
156
+ /**
157
+ * Send JSON response
158
+ */
159
+ json(data) {
160
+ this.header("Content-Type", "application/json");
161
+ return data;
162
+ }
163
+ /**
164
+ * Send HTML response
165
+ */
166
+ html(content) {
167
+ this.header("Content-Type", "text/html");
168
+ return content;
169
+ }
170
+ /**
171
+ * Send plain text response
172
+ */
173
+ text(content) {
174
+ this.header("Content-Type", "text/plain");
175
+ return content;
176
+ }
177
+ /**
178
+ * Redirect to a different URL
179
+ */
180
+ redirect(url, statusCode = 302) {
181
+ this.ctx.set.redirect = url;
182
+ this.ctx.set.status = statusCode;
183
+ }
184
+ /**
185
+ * Set content type
186
+ */
187
+ type(contentType) {
188
+ return this.header("Content-Type", contentType);
189
+ }
190
+ /**
191
+ * Set cache control
192
+ */
193
+ cache(maxAge, options) {
194
+ let cacheControl = "";
195
+ if (options?.private) {
196
+ cacheControl = "private";
197
+ }
198
+ else {
199
+ cacheControl = "public";
200
+ }
201
+ if (options?.noCache) {
202
+ cacheControl += ", no-cache";
203
+ }
204
+ if (options?.noStore) {
205
+ cacheControl += ", no-store";
206
+ }
207
+ if (maxAge > 0) {
208
+ cacheControl += `, max-age=${maxAge}`;
209
+ }
210
+ return this.header("Cache-Control", cacheControl);
211
+ }
212
+ /**
213
+ * Disable caching
214
+ */
215
+ noCache() {
216
+ return this.header("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate")
217
+ .header("Pragma", "no-cache")
218
+ .header("Expires", "0");
219
+ }
220
+ /**
221
+ * Set CORS headers
222
+ */
223
+ cors(options) {
224
+ this.header("Access-Control-Allow-Origin", options?.origin || "*");
225
+ if (options?.methods) {
226
+ this.header("Access-Control-Allow-Methods", options.methods.join(", "));
227
+ }
228
+ if (options?.headers) {
229
+ this.header("Access-Control-Allow-Headers", options.headers.join(", "));
230
+ }
231
+ if (options?.credentials) {
232
+ this.header("Access-Control-Allow-Credentials", "true");
233
+ }
234
+ if (options?.maxAge !== undefined) {
235
+ this.header("Access-Control-Max-Age", options.maxAge.toString());
236
+ }
237
+ return this;
238
+ }
239
+ /**
240
+ * Get the raw Elysia set object
241
+ */
242
+ get raw() {
243
+ return this.ctx.set;
244
+ }
245
+ /**
246
+ * Send a file download
247
+ */
248
+ download(filename) {
249
+ return this.header("Content-Disposition", `attachment; filename="${filename}"`);
250
+ }
251
+ /**
252
+ * Send response with custom status code
253
+ */
254
+ send(data, statusCode) {
255
+ if (statusCode) {
256
+ this.status(statusCode);
257
+ }
258
+ return data;
259
+ }
260
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ultra-optimized-handler.d.ts","sourceRoot":"","sources":["../core/ultra-optimized-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAYH,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,GAAG,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,GAAG,CAAC;IACrB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,SAAS,EAAE,GAAG,EAAE,CAAC;IACjB,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,mBAAmB,GAC3B,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAiU5B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,EACnC,WAAW,EAAE,GAAG,EAAE,GACjB,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAU5B"}
1
+ {"version":3,"file":"ultra-optimized-handler.d.ts","sourceRoot":"","sources":["../core/ultra-optimized-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAcH,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,GAAG,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,GAAG,CAAC;IACrB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,SAAS,EAAE,GAAG,EAAE,CAAC;IACjB,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,mBAAmB,GAC3B,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAgV5B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,EACnC,WAAW,EAAE,GAAG,EAAE,GACjB,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAqB5B"}
@@ -23,6 +23,8 @@
23
23
  import { createExecutionContext, executeGuards, } from "./decorators/guard.decorators";
24
24
  import { executeInterceptors } from "./decorators/interceptor.decorators";
25
25
  import { executePipes } from "./decorators/pipe.decorators";
26
+ import { Request } from "./request";
27
+ import { Response } from "./response";
26
28
  import { executeExceptionFilters, HttpException, } from "./decorators/exception.decorators";
27
29
  /**
28
30
  * Ultra-optimized handler builder
@@ -52,6 +54,11 @@ export function buildUltraOptimizedHandler(options) {
52
54
  !hasResponseModifiers) {
53
55
  // Direct call - zero overhead!
54
56
  return async (ctx) => {
57
+ if (!ctx.__wynk_wrapped__) {
58
+ ctx.request = new Request(ctx);
59
+ ctx.response = new Response(ctx);
60
+ ctx.__wynk_wrapped__ = true;
61
+ }
55
62
  return await instance[methodName](ctx);
56
63
  };
57
64
  }
@@ -62,6 +69,11 @@ export function buildUltraOptimizedHandler(options) {
62
69
  !hasResponseModifiers &&
63
70
  hasParams) {
64
71
  return async (ctx) => {
72
+ if (!ctx.__wynk_wrapped__) {
73
+ ctx.request = new Request(ctx);
74
+ ctx.response = new Response(ctx);
75
+ ctx.__wynk_wrapped__ = true;
76
+ }
65
77
  const args = new Array(params.length);
66
78
  for (const param of params) {
67
79
  let value;
@@ -129,6 +141,11 @@ export function buildUltraOptimizedHandler(options) {
129
141
  // CASE 3: Full-featured handler (has guards/interceptors/filters)
130
142
  // This is where we MUST use try-catch, but still avoid nested async
131
143
  return async (ctx) => {
144
+ if (!ctx.__wynk_wrapped__) {
145
+ ctx.request = new Request(ctx);
146
+ ctx.response = new Response(ctx);
147
+ ctx.__wynk_wrapped__ = true;
148
+ }
132
149
  try {
133
150
  // Guards
134
151
  if (hasGuards) {
@@ -294,9 +311,19 @@ export function buildMiddlewareChain(handler, middlewares) {
294
311
  if (middlewares.length === 0) {
295
312
  return handler;
296
313
  }
297
- return middlewares.reduceRight((next, middleware) => {
314
+ // Build chain without wrapping in each layer
315
+ const chain = middlewares.reduceRight((next, middleware) => {
298
316
  return async (ctx) => {
299
317
  return await middleware(ctx, () => next(ctx));
300
318
  };
301
319
  }, handler);
320
+ // Wrap ONCE at the top level
321
+ return async (ctx) => {
322
+ if (!ctx.__wynk_wrapped__) {
323
+ ctx.request = new Request(ctx);
324
+ ctx.response = new Response(ctx);
325
+ ctx.__wynk_wrapped__ = true;
326
+ }
327
+ return await chain(ctx);
328
+ };
302
329
  }