clear-router 2.1.12 → 2.3.0

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 (43) hide show
  1. package/README.md +4 -4
  2. package/dist/core/index.cjs +4 -0
  3. package/dist/core/index.d.cts +2 -0
  4. package/dist/core/index.d.mts +2 -0
  5. package/dist/core/index.mjs +3 -0
  6. package/dist/express/index.cjs +86 -247
  7. package/dist/express/index.d.cts +68 -97
  8. package/dist/express/index.d.mts +68 -97
  9. package/dist/express/index.mjs +86 -247
  10. package/dist/fastify/index.cjs +213 -0
  11. package/dist/fastify/index.d.cts +137 -0
  12. package/dist/fastify/index.d.mts +137 -0
  13. package/dist/fastify/index.mjs +212 -0
  14. package/dist/h3/index.cjs +88 -242
  15. package/dist/h3/index.d.cts +72 -93
  16. package/dist/h3/index.d.mts +72 -93
  17. package/dist/h3/index.mjs +88 -242
  18. package/dist/hono/index.cjs +227 -0
  19. package/dist/hono/index.d.cts +141 -0
  20. package/dist/hono/index.d.mts +141 -0
  21. package/dist/hono/index.mjs +226 -0
  22. package/dist/index.cjs +357 -0
  23. package/dist/index.d.cts +195 -40
  24. package/dist/index.d.mts +195 -40
  25. package/dist/index.mjs +358 -1
  26. package/dist/router-Ba2MVNn-.cjs +412 -0
  27. package/dist/router-Bug2IE_u.mjs +407 -0
  28. package/dist/router-DLmimm_U.d.cts +320 -0
  29. package/dist/router-cWYmcfTX.d.mts +320 -0
  30. package/dist/types/ClearRequest.d.mts +1 -1
  31. package/dist/types/Route.d.mts +5 -5
  32. package/dist/types/basic.d.mts +1 -4
  33. package/dist/types/express.d.mts +1 -1
  34. package/dist/types/fastify.d.mts +19 -0
  35. package/dist/types/fastify.mjs +1 -0
  36. package/dist/types/h3.d.mts +1 -1
  37. package/dist/types/hono.d.mts +18 -0
  38. package/dist/types/hono.mjs +1 -0
  39. package/package.json +26 -2
  40. package/dist/Route-BbPXcDGX.mjs +0 -50
  41. package/dist/Route-DhC4kNPX.cjs +0 -62
  42. package/dist/basic-C_1O6RVq.d.cts +0 -138
  43. package/dist/basic-cLeny2Zk.d.mts +0 -138
@@ -1,294 +1,140 @@
1
- import { n as ClearRequest, t as Route } from "../Route-BbPXcDGX.mjs";
2
- import { AsyncLocalStorage } from "node:async_hooks";
1
+ import { t as CoreRouter } from "../router-Bug2IE_u.mjs";
3
2
 
4
3
  //#region src/express/router.ts
5
4
  /**
6
- * @class clear-router
5
+ * @class clear-router Express Router
7
6
  * @description Laravel-style routing system for Express.js and H3 with support for CommonJS, ESM, and TypeScript
8
7
  * @author Refkinscallv
9
8
  * @author 3m1n3nc3
10
9
  * @repository https://github.com/toneflix/clear-router
11
10
  */
12
- var Router = class Router {
13
- static config = { methodOverride: {
14
- enabled: true,
15
- bodyKeys: ["_method"],
16
- headerKeys: ["x-http-method"]
17
- } };
18
- static groupContext = new AsyncLocalStorage();
19
- /**
20
- * All registered routes
21
- */
22
- static routes = [];
23
- /**
24
- * Mapping of routes by path and method for quick lookup.
25
- */
26
- static routesByPathMethod = {};
27
- /**
28
- * Mapping of routes by method for quick lookup.
29
- */
30
- static routesByMethod = {};
31
- /**
32
- * Current route prefix
33
- */
34
- static prefix = "";
35
- /**
36
- * Group-level middlewares
37
- */
38
- static groupMiddlewares = [];
39
- /**
40
- * Global-level middlewares
41
- */
42
- static globalMiddlewares = [];
43
- /**
44
- * Normalize path by removing duplicate slashes and ensuring leading slash
45
- * @param path - Path to normalize
46
- * @returns Normalized path
47
- */
48
- static normalizePath(path) {
49
- return "/" + path.split("/").filter(Boolean).join("/");
50
- }
51
- /**
52
- * Configure router settings to modify behavior.
53
- *
54
- * @param options - Configuration options for the router
55
- * @returns
56
- */
57
- static configure(options) {
58
- if (!this.config.methodOverride) this.config.methodOverride = {
59
- enabled: true,
60
- bodyKeys: ["_method"],
61
- headerKeys: ["x-http-method"]
62
- };
63
- const override = options?.methodOverride;
64
- if (!override) return;
65
- if (typeof override.enabled === "boolean") this.config.methodOverride.enabled = override.enabled;
66
- const bodyKeys = override.bodyKeys;
67
- if (typeof bodyKeys !== "undefined") this.config.methodOverride.bodyKeys = (Array.isArray(bodyKeys) ? bodyKeys : [bodyKeys]).map((e) => String(e).trim()).filter(Boolean);
68
- const headerKeys = override.headerKeys;
69
- if (typeof headerKeys !== "undefined") this.config.methodOverride.headerKeys = (Array.isArray(headerKeys) ? headerKeys : [headerKeys]).map((e) => String(e).trim().toLowerCase()).filter(Boolean);
70
- }
11
+ var Router = class Router extends CoreRouter {
71
12
  static ensureRequestBodyAccessor(req) {
72
13
  if (typeof req.getBody !== "function") req.getBody = () => req.body ?? {};
73
14
  }
74
- static resolveMethodOverride(method, headers, body) {
75
- if (!this.config.methodOverride?.enabled || method.toLowerCase() !== "post") return null;
76
- let override;
77
- for (const key of this.config.methodOverride?.headerKeys || []) {
78
- const value = headers?.[key];
79
- if (Array.isArray(value) ? value[0] : value) {
80
- override = Array.isArray(value) ? value[0] : value;
81
- break;
82
- }
83
- }
84
- if (!override && body && typeof body === "object") for (const key of this.config.methodOverride?.bodyKeys || []) {
85
- const value = body[key];
86
- if (typeof value !== "undefined" && value !== null && value !== "") {
87
- override = value;
88
- break;
89
- }
90
- }
91
- const normalized = String(override || "").trim().toLowerCase();
92
- if (!normalized) return null;
93
- if ([
94
- "put",
95
- "patch",
96
- "delete",
97
- "post"
98
- ].includes(normalized)) return normalized;
99
- return null;
100
- }
101
15
  /**
102
- * Add a route with specified HTTP methods, path, handler, and middlewares
103
- * @param methods - HTTP method(s) for the route
104
- * @param path - Route path
105
- * @param handler - Route handler function or controller reference
106
- * @param middlewares - Array of middleware functions
16
+ * Adds a new route to the router with the specified HTTP methods, path, handler, and optional middlewares.
17
+ *
18
+ * @param methods
19
+ * @param path
20
+ * @param handler
21
+ * @param middlewares
107
22
  */
108
23
  static add(methods, path, handler, middlewares) {
109
- const context = this.groupContext.getStore();
110
- const activePrefix = context?.prefix ?? this.prefix;
111
- const activeGroupMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
112
- methods = Array.isArray(methods) ? methods : [methods];
113
- middlewares = middlewares ? Array.isArray(middlewares) ? middlewares : [middlewares] : void 0;
114
- const fullPath = this.normalizePath(`${activePrefix}/${path}`);
115
- const route = new Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, [
116
- ...this.globalMiddlewares,
117
- ...activeGroupMiddlewares,
118
- ...middlewares || []
119
- ]);
120
- if (!methods.includes("options") && !this.routesByPathMethod[`OPTIONS ${fullPath}`]) this.options(path, ({ res }) => {
121
- res.set("Allow", "GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD");
122
- res.sendStatus(204);
123
- });
124
- this.routes.push(route);
125
- for (const method of methods.map((m) => m.toUpperCase())) {
126
- this.routesByPathMethod[`${method.toUpperCase()} ${fullPath}`] = route;
127
- if (!this.routesByMethod[method]) this.routesByMethod[method] = [];
128
- this.routesByMethod[method].push(route);
129
- }
24
+ super.add(methods, path, handler, middlewares);
130
25
  }
131
26
  /**
132
- * Register RESTful API resource routes for a controller with optional action filtering
27
+ * Adds a new API resource route to the router for the specified base path and controller, with
28
+ * optional configuration for included/excluded actions and middlewares.
133
29
  *
134
- * @param basePath - Base path for the resource
135
- * @param controller - Controller object containing action methods
136
- * @param options - Optional filtering options for actions
30
+ * @param basePath
31
+ * @param controller
32
+ * @param options
137
33
  */
138
34
  static apiResource(basePath, controller, options) {
139
- const actions = {
140
- index: {
141
- method: "get",
142
- path: "/"
143
- },
144
- show: {
145
- method: "get",
146
- path: "/:id"
147
- },
148
- create: {
149
- method: "post",
150
- path: "/"
151
- },
152
- update: {
153
- method: "put",
154
- path: "/:id"
155
- },
156
- destroy: {
157
- method: "delete",
158
- path: "/:id"
159
- }
160
- };
161
- const only = options?.only || Object.keys(actions);
162
- const except = options?.except || [];
163
- const preController = typeof controller === "function" ? new controller() : controller;
164
- for (const action of only) {
165
- if (except.includes(action)) continue;
166
- if (typeof preController[action] === "function") {
167
- const { method, path } = actions[action];
168
- const actionMiddlewares = typeof options?.middlewares === "object" && !Array.isArray(options.middlewares) ? options.middlewares[action] : options?.middlewares;
169
- this.add(method, `${basePath}${path}`, [controller, action], Array.isArray(actionMiddlewares) ? actionMiddlewares : actionMiddlewares ? [actionMiddlewares] : void 0);
170
- }
171
- }
35
+ super.apiResource(basePath, controller, options);
172
36
  }
173
37
  /**
174
- * Register a GET route
175
- * @param path - Route path
176
- * @param handler - Route handler
177
- * @param middlewares - Middleware functions
38
+ * Adds a new GET route to the router with the specified path, handler, and optional middlewares.
39
+ *
40
+ * @param path
41
+ * @param handler
42
+ * @param middlewares
178
43
  */
179
44
  static get(path, handler, middlewares) {
180
- this.add("get", path, handler, middlewares);
45
+ super.get(path, handler, middlewares);
181
46
  }
182
47
  /**
183
- * Register a POST route
184
- * @param path - Route path
185
- * @param handler - Route handler
186
- * @param middlewares - Middleware functions
48
+ * Adds a new POST route to the router with the specified path, handler, and optional middlewares.
49
+ *
50
+ * @param path
51
+ * @param handler
52
+ * @param middlewares
187
53
  */
188
54
  static post(path, handler, middlewares) {
189
- this.add("post", path, handler, middlewares);
55
+ super.post(path, handler, middlewares);
190
56
  }
191
57
  /**
192
- * Register a PUT route
193
- * @param path - Route path
194
- * @param handler - Route handler
195
- * @param middlewares - Middleware functions
58
+ * Adds a new PUT route to the router with the specified path, handler, and optional middlewares.
59
+ *
60
+ * @param path
61
+ * @param handler
62
+ * @param middlewares
196
63
  */
197
64
  static put(path, handler, middlewares) {
198
- this.add("put", path, handler, middlewares);
65
+ super.put(path, handler, middlewares);
199
66
  }
200
67
  /**
201
- * Register a DELETE route
202
- * @param path - Route path
203
- * @param handler - Route handler
204
- * @param middlewares - Middleware functions
68
+ * Adds a new DELETE route to the router with the specified path, handler, and optional middlewares.
69
+ *
70
+ * @param path
71
+ * @param handler
72
+ * @param middlewares
205
73
  */
206
74
  static delete(path, handler, middlewares) {
207
- this.add("delete", path, handler, middlewares);
75
+ super.delete(path, handler, middlewares);
208
76
  }
209
77
  /**
210
- * Register a PATCH route
211
- * @param path - Route path
212
- * @param handler - Route handler
213
- * @param middlewares - Middleware functions
78
+ * Adds a new PATCH route to the router with the specified path, handler, and optional middlewares.
79
+ *
80
+ * @param path
81
+ * @param handler
82
+ * @param middlewares
214
83
  */
215
84
  static patch(path, handler, middlewares) {
216
- this.add("patch", path, handler, middlewares);
85
+ super.patch(path, handler, middlewares);
217
86
  }
218
87
  /**
219
- * Register an OPTIONS route
220
- * @param path - Route path
221
- * @param handler - Route handler
222
- * @param middlewares - Middleware functions
88
+ * Adds a new OPTIONS route to the router with the specified path, handler, and optional middlewares.
89
+ *
90
+ * @param path
91
+ * @param handler
92
+ * @param middlewares
223
93
  */
224
94
  static options(path, handler, middlewares) {
225
- this.add("options", path, handler, middlewares);
95
+ super.options(path, handler, middlewares);
226
96
  }
227
97
  /**
228
- * Register a HEAD route
229
- * @param path - Route path
230
- * @param handler - Route handler
231
- * @param middlewares - Middleware functions
98
+ * Adds a new HEAD route to the router with the specified path, handler, and optional middlewares.
99
+ *
100
+ * @param path
101
+ * @param handler
102
+ * @param middlewares
232
103
  */
233
104
  static head(path, handler, middlewares) {
234
- this.add("head", path, handler, middlewares);
105
+ super.head(path, handler, middlewares);
235
106
  }
236
107
  /**
237
- * Group routes with a common prefix and middlewares
238
- * @param prefix - URL prefix for grouped routes
239
- * @param callback - Function containing route definitions
240
- * @param middlewares - Middleware functions applied to all routes in group
108
+ * Defines a group of routes with a common prefix and optional middlewares, allowing for better
109
+ * organization and reuse of route configurations.
110
+ *
111
+ * @param prefix
112
+ * @param callback
113
+ * @param middlewares
241
114
  */
242
115
  static async group(prefix, callback, middlewares) {
243
- const context = this.groupContext.getStore();
244
- const previousPrefix = context?.prefix ?? this.prefix;
245
- const previousMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
246
- const fullPrefix = [previousPrefix, prefix].filter(Boolean).join("/");
247
- const nextContext = {
248
- prefix: this.normalizePath(fullPrefix),
249
- groupMiddlewares: [...previousMiddlewares, ...middlewares || []]
250
- };
251
- await this.groupContext.run(nextContext, async () => {
252
- await Promise.resolve(callback());
253
- });
116
+ await super.group(prefix, callback, middlewares);
254
117
  }
255
118
  /**
256
- * Apply global middlewares for the duration of the callback
257
- * @param middlewares - Middleware functions
258
- * @param callback - Function containing route definitions
119
+ * Adds global middlewares to the router, which will be applied to all routes.
120
+ *
121
+ * @param middlewares
122
+ * @param callback
259
123
  */
260
124
  static middleware(middlewares, callback) {
261
- const prevMiddlewares = this.globalMiddlewares;
262
- this.globalMiddlewares = [...prevMiddlewares, ...middlewares || []];
263
- callback();
264
- this.globalMiddlewares = prevMiddlewares;
125
+ super.middleware(middlewares, callback);
265
126
  }
266
127
  static allRoutes(type) {
267
- if (type === "method") return this.routesByMethod;
268
- if (type === "path") return this.routesByPathMethod;
269
- return this.routes.filter((e) => e.methods.length > 1 || e.methods[0] !== "options");
128
+ return super.allRoutes(type);
270
129
  }
271
130
  static async apply(router) {
272
131
  for (const route of this.routes) {
273
132
  let handlerFunction = null;
274
133
  let instance = null;
275
134
  try {
276
- if (typeof route.handler === "function")
277
- /**
278
- * Since we do not have a controller instance, we will call the handler function directly and the route instance will be the this argument. This allows for both controller-based and function-based handlers to work seamlessly.
279
- */
280
- handlerFunction = route.handler.bind(route);
281
- else if (Array.isArray(route.handler) && route.handler.length === 2) {
282
- const [Controller, method] = route.handler;
283
- if (["function", "object"].includes(typeof Controller) && typeof Controller[method] === "function") {
284
- instance = Controller;
285
- handlerFunction = Controller[method].bind(Controller);
286
- } else if (typeof Controller === "function") {
287
- instance = new Controller();
288
- if (typeof instance[method] === "function") handlerFunction = instance[method].bind(instance);
289
- else throw new Error(`Method "${method}" not found in controller instance "${Controller.name}"`);
290
- } else throw new Error(`Invalid controller type for route: ${route.path}`);
291
- } else throw new Error(`Invalid handler format for route: ${route.path}`);
135
+ const resolved = this.resolveHandler(route);
136
+ handlerFunction = resolved.handlerFunction;
137
+ instance = resolved.instance;
292
138
  } catch (error) {
293
139
  console.error(`[ROUTES] Error setting up route ${route.path}:`, error.message);
294
140
  throw error;
@@ -310,7 +156,7 @@ var Router = class Router {
310
156
  console.error("[ROUTES]", error.message);
311
157
  throw error;
312
158
  }
313
- router[method](route.path, (req, res, next) => {
159
+ router[method](route.path, (req, _res, next) => {
314
160
  Router.ensureRequestBodyAccessor(req);
315
161
  const override = Router.resolveMethodOverride(req.method, req.headers, req.body);
316
162
  if (method === "post" && override && override !== "post") return next("route");
@@ -324,7 +170,11 @@ var Router = class Router {
324
170
  next
325
171
  };
326
172
  const inst = instance ?? route;
327
- await Router.bindRequestToInstance(ctx, inst, route);
173
+ Router.bindRequestToInstance(ctx, inst, route, {
174
+ body: ctx.req.getBody(),
175
+ query: ctx.req.query,
176
+ params: ctx.req.params
177
+ });
328
178
  const result = handlerFunction(ctx, inst.clearRequest);
329
179
  await Promise.resolve(result);
330
180
  } catch (error) {
@@ -335,7 +185,7 @@ var Router = class Router {
335
185
  "put",
336
186
  "patch",
337
187
  "delete"
338
- ].includes(method)) router.post(route.path, (req, res, next) => {
188
+ ].includes(method)) router.post(route.path, (req, _res, next) => {
339
189
  Router.ensureRequestBodyAccessor(req);
340
190
  if (Router.resolveMethodOverride(req.method, req.headers, req.body) !== method) return next("route");
341
191
  req.method = method.toUpperCase();
@@ -349,7 +199,11 @@ var Router = class Router {
349
199
  next
350
200
  };
351
201
  const inst = instance ?? route;
352
- await Router.bindRequestToInstance(ctx, inst, route);
202
+ Router.bindRequestToInstance(ctx, inst, route, {
203
+ body: ctx.req.getBody(),
204
+ query: ctx.req.query,
205
+ params: ctx.req.params
206
+ });
353
207
  const result = handlerFunction(ctx, inst.clearRequest);
354
208
  await Promise.resolve(result);
355
209
  } catch (error) {
@@ -359,21 +213,6 @@ var Router = class Router {
359
213
  }
360
214
  }
361
215
  }
362
- static async bindRequestToInstance(ctx, instance, route) {
363
- if (!instance) return;
364
- Router.ensureRequestBodyAccessor(ctx.req);
365
- instance.ctx = ctx;
366
- instance.body = ctx.req.getBody();
367
- instance.query = ctx.req.query;
368
- instance.params = ctx.req.params;
369
- instance.clearRequest = new ClearRequest({
370
- ctx,
371
- route,
372
- body: instance.body,
373
- query: instance.query,
374
- params: instance.params
375
- });
376
- }
377
216
  };
378
217
 
379
218
  //#endregion
@@ -0,0 +1,213 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_router = require('../router-Ba2MVNn-.cjs');
3
+
4
+ //#region src/fastify/router.ts
5
+ /**
6
+ * @class clear-router Fastify Router
7
+ * @description Laravel-style routing system for Fastify using shared clear-router core
8
+ * @author 3m1n3nc3
9
+ * @repository https://github.com/toneflix/clear-router
10
+ */
11
+ var Router = class Router extends require_router.CoreRouter {
12
+ static ensureRequestBodyAccessor(req) {
13
+ if (typeof req.getBody !== "function") req.getBody = () => req.body ?? {};
14
+ }
15
+ /**
16
+ * Add a route to the router
17
+ *
18
+ * @param methods HTTP methods for the route
19
+ * @param path Route path
20
+ * @param handler Route handler function
21
+ * @param middlewares Optional middlewares for the route
22
+ */
23
+ static add(methods, path, handler, middlewares) {
24
+ super.add(methods, path, handler, middlewares);
25
+ }
26
+ /**
27
+ * Define a resourceful API controller with standard CRUD routes
28
+ *
29
+ * @param basePath Base path for the resource
30
+ * @param controller Controller class or instance
31
+ * @param options Optional configuration for the resource
32
+ */
33
+ static apiResource(basePath, controller, options) {
34
+ super.apiResource(basePath, controller, options);
35
+ }
36
+ /**
37
+ * Define a GET route
38
+ *
39
+ * @param path
40
+ * @param handler
41
+ * @param middlewares
42
+ */
43
+ static get(path, handler, middlewares) {
44
+ super.get(path, handler, middlewares);
45
+ }
46
+ /**
47
+ * Define a POST route
48
+ *
49
+ * @param path
50
+ * @param handler
51
+ * @param middlewares
52
+ */
53
+ static post(path, handler, middlewares) {
54
+ super.post(path, handler, middlewares);
55
+ }
56
+ /**
57
+ * Define a PUT route
58
+ *
59
+ * @param path
60
+ * @param handler
61
+ * @param middlewares
62
+ */
63
+ static put(path, handler, middlewares) {
64
+ super.put(path, handler, middlewares);
65
+ }
66
+ /**
67
+ * Define a DELETE route
68
+ *
69
+ * @param path
70
+ * @param handler
71
+ * @param middlewares
72
+ */
73
+ static delete(path, handler, middlewares) {
74
+ super.delete(path, handler, middlewares);
75
+ }
76
+ /**
77
+ * Define a PATCH route
78
+ *
79
+ * @param path
80
+ * @param handler
81
+ * @param middlewares
82
+ */
83
+ static patch(path, handler, middlewares) {
84
+ super.patch(path, handler, middlewares);
85
+ }
86
+ /**
87
+ * Define an OPTIONS route
88
+ *
89
+ * @param path
90
+ * @param handler
91
+ * @param middlewares
92
+ */
93
+ static options(path, handler, middlewares) {
94
+ super.options(path, handler, middlewares);
95
+ }
96
+ /**
97
+ * Define a HEAD route
98
+ *
99
+ * @param path
100
+ * @param handler
101
+ * @param middlewares
102
+ */
103
+ static head(path, handler, middlewares) {
104
+ super.head(path, handler, middlewares);
105
+ }
106
+ /**
107
+ * Define a group of routes with a common prefix and optional middlewares
108
+ *
109
+ * @param prefix
110
+ * @param callback
111
+ * @param middlewares
112
+ */
113
+ static async group(prefix, callback, middlewares) {
114
+ await super.group(prefix, callback, middlewares);
115
+ }
116
+ /**
117
+ * Apply middlewares to a group of routes defined within the callback
118
+ *
119
+ * @param middlewares
120
+ * @param callback
121
+ */
122
+ static middleware(middlewares, callback) {
123
+ super.middleware(middlewares, callback);
124
+ }
125
+ static allRoutes(type) {
126
+ return super.allRoutes(type);
127
+ }
128
+ /**
129
+ * Apply the defined routes to a Fastify application instance
130
+ *
131
+ * @param app - The Fastify application instance
132
+ * @returns The Fastify application instance with the applied routes
133
+ */
134
+ static apply(app) {
135
+ for (const route of this.routes) {
136
+ let handlerFunction = null;
137
+ let instance = null;
138
+ try {
139
+ const resolved = this.resolveHandler(route);
140
+ handlerFunction = resolved.handlerFunction;
141
+ instance = resolved.instance;
142
+ } catch (error) {
143
+ console.error(`[ROUTES] Error setting up route ${route.path}:`, error.message);
144
+ throw error;
145
+ }
146
+ if (!handlerFunction) continue;
147
+ for (const method of route.methods) {
148
+ const allowedMethods = [
149
+ "get",
150
+ "post",
151
+ "put",
152
+ "delete",
153
+ "patch",
154
+ "options",
155
+ "head"
156
+ ];
157
+ if (method === "options" && route.methods.length > 1) continue;
158
+ if (!allowedMethods.includes(method)) throw new Error(`Invalid HTTP method: ${method} for route: ${route.path}`);
159
+ app.route({
160
+ method: method.toUpperCase(),
161
+ url: route.path,
162
+ preHandler: route.middlewares,
163
+ handler: async (req, reply) => {
164
+ Router.ensureRequestBodyAccessor(req);
165
+ const override = Router.resolveMethodOverride(req.method, req.headers, req.body);
166
+ if (method === "post" && override && override !== "post") return reply.code(404).send();
167
+ const ctx = {
168
+ req,
169
+ reply
170
+ };
171
+ const inst = instance ?? route;
172
+ Router.bindRequestToInstance(ctx, inst, route, {
173
+ body: ctx.req.getBody(),
174
+ query: ctx.req.query ?? {},
175
+ params: ctx.req.params ?? {}
176
+ });
177
+ const result = handlerFunction(ctx, inst.clearRequest);
178
+ return await Promise.resolve(result);
179
+ }
180
+ });
181
+ if ([
182
+ "put",
183
+ "patch",
184
+ "delete"
185
+ ].includes(method)) app.route({
186
+ method: "POST",
187
+ url: route.path,
188
+ preHandler: route.middlewares,
189
+ handler: async (req, reply) => {
190
+ Router.ensureRequestBodyAccessor(req);
191
+ if (Router.resolveMethodOverride(req.method, req.headers, req.body) !== method) return reply.code(404).send();
192
+ const ctx = {
193
+ req,
194
+ reply
195
+ };
196
+ const inst = instance ?? route;
197
+ Router.bindRequestToInstance(ctx, inst, route, {
198
+ body: ctx.req.getBody(),
199
+ query: ctx.req.query ?? {},
200
+ params: ctx.req.params ?? {}
201
+ });
202
+ const result = handlerFunction(ctx, inst.clearRequest);
203
+ return await Promise.resolve(result);
204
+ }
205
+ });
206
+ }
207
+ }
208
+ return app;
209
+ }
210
+ };
211
+
212
+ //#endregion
213
+ exports.Router = Router;