clear-router 2.7.7 → 2.8.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 (52) hide show
  1. package/dist/{Request-BhTJDR_5.d.mts → Request-Ci0UQ-Vl.d.mts} +27 -0
  2. package/dist/ResourceRouteSelection.cjs +26 -0
  3. package/dist/ResourceRouteSelection.d.cts +20 -0
  4. package/dist/ResourceRouteSelection.d.mts +20 -0
  5. package/dist/ResourceRouteSelection.mjs +25 -0
  6. package/dist/ResourceRoutes.cjs +60 -0
  7. package/dist/ResourceRoutes.d.cts +37 -0
  8. package/dist/ResourceRoutes.d.mts +37 -0
  9. package/dist/ResourceRoutes.mjs +60 -0
  10. package/dist/Route.cjs +32 -0
  11. package/dist/Route.d.cts +27 -0
  12. package/dist/Route.d.mts +27 -0
  13. package/dist/Route.mjs +32 -0
  14. package/dist/core/index.cjs +6 -0
  15. package/dist/core/router.cjs +57 -4
  16. package/dist/core/router.d.cts +13 -1
  17. package/dist/core/router.d.mts +13 -1
  18. package/dist/core/router.mjs +57 -4
  19. package/dist/decorators/setup.d.mts +0 -1
  20. package/dist/express/router.cjs +2 -2
  21. package/dist/express/router.d.cts +2 -1
  22. package/dist/express/router.d.mts +2 -1
  23. package/dist/express/router.mjs +2 -2
  24. package/dist/fastify/router.cjs +2 -2
  25. package/dist/fastify/router.d.cts +2 -1
  26. package/dist/fastify/router.d.mts +2 -1
  27. package/dist/fastify/router.mjs +2 -2
  28. package/dist/h3/router.cjs +2 -2
  29. package/dist/h3/router.d.cts +19 -18
  30. package/dist/h3/router.d.mts +19 -18
  31. package/dist/h3/router.mjs +2 -2
  32. package/dist/hono/router.cjs +2 -2
  33. package/dist/hono/router.d.cts +2 -1
  34. package/dist/hono/router.d.mts +2 -1
  35. package/dist/hono/router.mjs +2 -2
  36. package/dist/koa/router.cjs +2 -2
  37. package/dist/koa/router.d.cts +2 -1
  38. package/dist/koa/router.d.mts +2 -1
  39. package/dist/koa/router.mjs +2 -2
  40. package/dist/types/basic.d.cts +11 -1
  41. package/dist/types/basic.d.mts +11 -1
  42. package/dist/types/express.d.cts +6 -2
  43. package/dist/types/express.d.mts +6 -2
  44. package/dist/types/fastify.d.cts +3 -2
  45. package/dist/types/fastify.d.mts +3 -2
  46. package/dist/types/h3.d.cts +7 -2
  47. package/dist/types/h3.d.mts +7 -2
  48. package/dist/types/hono.d.cts +4 -3
  49. package/dist/types/hono.d.mts +4 -3
  50. package/dist/types/koa.d.cts +3 -2
  51. package/dist/types/koa.d.mts +3 -2
  52. package/package.json +1 -1
@@ -40,6 +40,12 @@ declare class Response {
40
40
  }
41
41
  //#endregion
42
42
  //#region src/Route.d.ts
43
+ /**
44
+ * @class clear-router Route
45
+ * @description A route describes a single enpoint on clear-router
46
+ * @author 3m1n3nc3
47
+ * @repository https://github.com/arkstack-tmp/clear-router
48
+ */
43
49
  declare class Route<X = any, M = Middleware$1 | Middleware$4, H = any> {
44
50
  ctx: X;
45
51
  body: RequestData;
@@ -61,9 +67,30 @@ declare class Route<X = any, M = Middleware$1 | Middleware$4, H = any> {
61
67
  registrationPaths?: string[];
62
68
  parameters?: RouteParameter[];
63
69
  onName?: (name: string, route: Route<X, M, H>, previousName?: string) => void;
70
+ normalizeMiddleware?: (middleware: M) => M;
64
71
  });
65
72
  private onName?;
73
+ private normalizeMiddleware?;
74
+ /**
75
+ * Set the route name
76
+ *
77
+ * @param name
78
+ * @returns
79
+ */
66
80
  name(name: string): this;
81
+ /**
82
+ * Register one or more middleware that will be executed before the route.
83
+ *
84
+ * @param middlewares
85
+ * @returns
86
+ */
87
+ middleware(middlewares: M[] | M): this;
88
+ /**
89
+ * Get the path generated and accessible by this route
90
+ *
91
+ * @param params
92
+ * @returns
93
+ */
67
94
  toPath(params?: RequestData): string;
68
95
  }
69
96
  //#endregion
@@ -0,0 +1,26 @@
1
+
2
+ //#region src/ResourceRouteSelection.ts
3
+ var ResourceRouteSelection = class {
4
+ constructor(routes) {
5
+ this.routes = routes;
6
+ }
7
+ /**
8
+ * Register one or more middleware that will be executed before the route.
9
+ *
10
+ * @param middlewares
11
+ * @returns
12
+ */
13
+ middleware(middlewares) {
14
+ for (const route of this.routes) route.middleware(middlewares);
15
+ return this;
16
+ }
17
+ all() {
18
+ return this.routes;
19
+ }
20
+ first() {
21
+ return this.routes[0];
22
+ }
23
+ };
24
+
25
+ //#endregion
26
+ exports.ResourceRouteSelection = ResourceRouteSelection;
@@ -0,0 +1,20 @@
1
+ import { Middleware } from "./types/express.cjs";
2
+ import { Middleware as Middleware$1 } from "./types/h3.cjs";
3
+ import { Route } from "./Route.cjs";
4
+
5
+ //#region src/ResourceRouteSelection.d.ts
6
+ declare class ResourceRouteSelection<X = any, M = Middleware$1 | Middleware, H = any> {
7
+ readonly routes: Array<Route<X, M, H>>;
8
+ constructor(routes: Array<Route<X, M, H>>);
9
+ /**
10
+ * Register one or more middleware that will be executed before the route.
11
+ *
12
+ * @param middlewares
13
+ * @returns
14
+ */
15
+ middleware(middlewares: M[] | M): this;
16
+ all(): Array<Route<X, M, H>>;
17
+ first(): Route<X, M, H> | undefined;
18
+ }
19
+ //#endregion
20
+ export { ResourceRouteSelection };
@@ -0,0 +1,20 @@
1
+ import { Middleware } from "./types/express.mjs";
2
+ import { Middleware as Middleware$1 } from "./types/h3.mjs";
3
+ import { Route } from "./Route.mjs";
4
+
5
+ //#region src/ResourceRouteSelection.d.ts
6
+ declare class ResourceRouteSelection<X = any, M = Middleware$1 | Middleware, H = any> {
7
+ readonly routes: Array<Route<X, M, H>>;
8
+ constructor(routes: Array<Route<X, M, H>>);
9
+ /**
10
+ * Register one or more middleware that will be executed before the route.
11
+ *
12
+ * @param middlewares
13
+ * @returns
14
+ */
15
+ middleware(middlewares: M[] | M): this;
16
+ all(): Array<Route<X, M, H>>;
17
+ first(): Route<X, M, H> | undefined;
18
+ }
19
+ //#endregion
20
+ export { ResourceRouteSelection };
@@ -0,0 +1,25 @@
1
+ //#region src/ResourceRouteSelection.ts
2
+ var ResourceRouteSelection = class {
3
+ constructor(routes) {
4
+ this.routes = routes;
5
+ }
6
+ /**
7
+ * Register one or more middleware that will be executed before the route.
8
+ *
9
+ * @param middlewares
10
+ * @returns
11
+ */
12
+ middleware(middlewares) {
13
+ for (const route of this.routes) route.middleware(middlewares);
14
+ return this;
15
+ }
16
+ all() {
17
+ return this.routes;
18
+ }
19
+ first() {
20
+ return this.routes[0];
21
+ }
22
+ };
23
+
24
+ //#endregion
25
+ export { ResourceRouteSelection };
@@ -0,0 +1,60 @@
1
+ const require_ResourceRouteSelection = require('./ResourceRouteSelection.cjs');
2
+
3
+ //#region src/ResourceRoutes.ts
4
+ /**
5
+ * @class clear-router ResourceRoutes
6
+ * @description A ResourceRoutes creates a collection of resourceful routes in a single call
7
+ * @author 3m1n3nc3
8
+ * @repository https://github.com/arkstack-tmp/clear-router
9
+ */
10
+ var ResourceRoutes = class {
11
+ constructor(routes) {
12
+ this.routes = routes;
13
+ }
14
+ /**
15
+ * Register one or more middleware that will be executed before the route.
16
+ *
17
+ * @param middlewares
18
+ * @returns
19
+ */
20
+ middleware(middlewares) {
21
+ for (const route of Object.values(this.routes)) route?.middleware(middlewares);
22
+ return this;
23
+ }
24
+ action(action) {
25
+ return this.routes[action];
26
+ }
27
+ index() {
28
+ return this.routes.index;
29
+ }
30
+ show() {
31
+ return this.routes.show;
32
+ }
33
+ create() {
34
+ return this.routes.create;
35
+ }
36
+ update() {
37
+ return this.routes.update;
38
+ }
39
+ destroy() {
40
+ return this.routes.destroy;
41
+ }
42
+ get() {
43
+ return this.byMethod("get");
44
+ }
45
+ post() {
46
+ return this.byMethod("post");
47
+ }
48
+ put() {
49
+ return this.byMethod("put");
50
+ }
51
+ delete() {
52
+ return this.byMethod("delete");
53
+ }
54
+ byMethod(method) {
55
+ return new require_ResourceRouteSelection.ResourceRouteSelection(Object.values(this.routes).filter((route) => Boolean(route?.methods.includes(method))));
56
+ }
57
+ };
58
+
59
+ //#endregion
60
+ exports.ResourceRoutes = ResourceRoutes;
@@ -0,0 +1,37 @@
1
+ import { HttpMethod, ResourceAction } from "./types/basic.cjs";
2
+ import { Middleware } from "./types/express.cjs";
3
+ import { Middleware as Middleware$1 } from "./types/h3.cjs";
4
+ import { Route } from "./Route.cjs";
5
+ import { ResourceRouteSelection } from "./ResourceRouteSelection.cjs";
6
+
7
+ //#region src/ResourceRoutes.d.ts
8
+ /**
9
+ * @class clear-router ResourceRoutes
10
+ * @description A ResourceRoutes creates a collection of resourceful routes in a single call
11
+ * @author 3m1n3nc3
12
+ * @repository https://github.com/arkstack-tmp/clear-router
13
+ */
14
+ declare class ResourceRoutes<X = any, M = Middleware$1 | Middleware, H = any> {
15
+ readonly routes: Partial<Record<ResourceAction, Route<X, M, H>>>;
16
+ constructor(routes: Partial<Record<ResourceAction, Route<X, M, H>>>);
17
+ /**
18
+ * Register one or more middleware that will be executed before the route.
19
+ *
20
+ * @param middlewares
21
+ * @returns
22
+ */
23
+ middleware(middlewares: M[] | M): this;
24
+ action(action: ResourceAction): Route<X, M, H> | undefined;
25
+ index(): Route<X, M, H> | undefined;
26
+ show(): Route<X, M, H> | undefined;
27
+ create(): Route<X, M, H> | undefined;
28
+ update(): Route<X, M, H> | undefined;
29
+ destroy(): Route<X, M, H> | undefined;
30
+ get(): ResourceRouteSelection<X, M, H>;
31
+ post(): ResourceRouteSelection<X, M, H>;
32
+ put(): ResourceRouteSelection<X, M, H>;
33
+ delete(): ResourceRouteSelection<X, M, H>;
34
+ protected byMethod(method: HttpMethod): ResourceRouteSelection<X, M, H>;
35
+ }
36
+ //#endregion
37
+ export { ResourceRoutes };
@@ -0,0 +1,37 @@
1
+ import { HttpMethod, ResourceAction } from "./types/basic.mjs";
2
+ import { Middleware } from "./types/express.mjs";
3
+ import { Middleware as Middleware$1 } from "./types/h3.mjs";
4
+ import { Route } from "./Route.mjs";
5
+ import { ResourceRouteSelection } from "./ResourceRouteSelection.mjs";
6
+
7
+ //#region src/ResourceRoutes.d.ts
8
+ /**
9
+ * @class clear-router ResourceRoutes
10
+ * @description A ResourceRoutes creates a collection of resourceful routes in a single call
11
+ * @author 3m1n3nc3
12
+ * @repository https://github.com/arkstack-tmp/clear-router
13
+ */
14
+ declare class ResourceRoutes<X = any, M = Middleware$1 | Middleware, H = any> {
15
+ readonly routes: Partial<Record<ResourceAction, Route<X, M, H>>>;
16
+ constructor(routes: Partial<Record<ResourceAction, Route<X, M, H>>>);
17
+ /**
18
+ * Register one or more middleware that will be executed before the route.
19
+ *
20
+ * @param middlewares
21
+ * @returns
22
+ */
23
+ middleware(middlewares: M[] | M): this;
24
+ action(action: ResourceAction): Route<X, M, H> | undefined;
25
+ index(): Route<X, M, H> | undefined;
26
+ show(): Route<X, M, H> | undefined;
27
+ create(): Route<X, M, H> | undefined;
28
+ update(): Route<X, M, H> | undefined;
29
+ destroy(): Route<X, M, H> | undefined;
30
+ get(): ResourceRouteSelection<X, M, H>;
31
+ post(): ResourceRouteSelection<X, M, H>;
32
+ put(): ResourceRouteSelection<X, M, H>;
33
+ delete(): ResourceRouteSelection<X, M, H>;
34
+ protected byMethod(method: HttpMethod): ResourceRouteSelection<X, M, H>;
35
+ }
36
+ //#endregion
37
+ export { ResourceRoutes };
@@ -0,0 +1,60 @@
1
+ import { ResourceRouteSelection } from "./ResourceRouteSelection.mjs";
2
+
3
+ //#region src/ResourceRoutes.ts
4
+ /**
5
+ * @class clear-router ResourceRoutes
6
+ * @description A ResourceRoutes creates a collection of resourceful routes in a single call
7
+ * @author 3m1n3nc3
8
+ * @repository https://github.com/arkstack-tmp/clear-router
9
+ */
10
+ var ResourceRoutes = class {
11
+ constructor(routes) {
12
+ this.routes = routes;
13
+ }
14
+ /**
15
+ * Register one or more middleware that will be executed before the route.
16
+ *
17
+ * @param middlewares
18
+ * @returns
19
+ */
20
+ middleware(middlewares) {
21
+ for (const route of Object.values(this.routes)) route?.middleware(middlewares);
22
+ return this;
23
+ }
24
+ action(action) {
25
+ return this.routes[action];
26
+ }
27
+ index() {
28
+ return this.routes.index;
29
+ }
30
+ show() {
31
+ return this.routes.show;
32
+ }
33
+ create() {
34
+ return this.routes.create;
35
+ }
36
+ update() {
37
+ return this.routes.update;
38
+ }
39
+ destroy() {
40
+ return this.routes.destroy;
41
+ }
42
+ get() {
43
+ return this.byMethod("get");
44
+ }
45
+ post() {
46
+ return this.byMethod("post");
47
+ }
48
+ put() {
49
+ return this.byMethod("put");
50
+ }
51
+ delete() {
52
+ return this.byMethod("delete");
53
+ }
54
+ byMethod(method) {
55
+ return new ResourceRouteSelection(Object.values(this.routes).filter((route) => Boolean(route?.methods.includes(method))));
56
+ }
57
+ };
58
+
59
+ //#endregion
60
+ export { ResourceRoutes };
package/dist/Route.cjs CHANGED
@@ -1,5 +1,11 @@
1
1
 
2
2
  //#region src/Route.ts
3
+ /**
4
+ * @class clear-router Route
5
+ * @description A route describes a single enpoint on clear-router
6
+ * @author 3m1n3nc3
7
+ * @repository https://github.com/arkstack-tmp/clear-router
8
+ */
3
9
  var Route = class {
4
10
  ctx;
5
11
  body = {};
@@ -29,14 +35,40 @@ var Route = class {
29
35
  this.controllerName = Array.isArray(handler) ? handler[0]?.name : void 0;
30
36
  this.actionName = Array.isArray(handler) ? handler[1] : typeof handler === "function" ? handler.constructor.name ?? handler.name : void 0;
31
37
  this.onName = options.onName;
38
+ this.normalizeMiddleware = options.normalizeMiddleware;
32
39
  }
33
40
  onName;
41
+ normalizeMiddleware;
42
+ /**
43
+ * Set the route name
44
+ *
45
+ * @param name
46
+ * @returns
47
+ */
34
48
  name(name) {
35
49
  const previousName = this.routeName;
36
50
  this.routeName = name;
37
51
  this.onName?.(name, this, previousName);
38
52
  return this;
39
53
  }
54
+ /**
55
+ * Register one or more middleware that will be executed before the route.
56
+ *
57
+ * @param middlewares
58
+ * @returns
59
+ */
60
+ middleware(middlewares) {
61
+ const normalized = (Array.isArray(middlewares) ? middlewares : [middlewares]).map((middleware) => this.normalizeMiddleware?.(middleware) ?? middleware);
62
+ this.middlewares.push(...normalized);
63
+ this.middlewareCount = this.middlewares.length;
64
+ return this;
65
+ }
66
+ /**
67
+ * Get the path generated and accessible by this route
68
+ *
69
+ * @param params
70
+ * @returns
71
+ */
40
72
  toPath(params = {}) {
41
73
  return this.path.replace(/\/?\{([^{}]+)\}/g, (segment, raw) => {
42
74
  const optional = raw.endsWith("?");
package/dist/Route.d.cts CHANGED
@@ -5,6 +5,12 @@ import { Middleware as Middleware$1 } from "./types/h3.cjs";
5
5
  import { ClearRequest } from "./ClearRequest.cjs";
6
6
 
7
7
  //#region src/Route.d.ts
8
+ /**
9
+ * @class clear-router Route
10
+ * @description A route describes a single enpoint on clear-router
11
+ * @author 3m1n3nc3
12
+ * @repository https://github.com/arkstack-tmp/clear-router
13
+ */
8
14
  declare class Route<X = any, M = Middleware$1 | Middleware, H = any> {
9
15
  ctx: X;
10
16
  body: RequestData;
@@ -26,9 +32,30 @@ declare class Route<X = any, M = Middleware$1 | Middleware, H = any> {
26
32
  registrationPaths?: string[];
27
33
  parameters?: RouteParameter[];
28
34
  onName?: (name: string, route: Route<X, M, H>, previousName?: string) => void;
35
+ normalizeMiddleware?: (middleware: M) => M;
29
36
  });
30
37
  private onName?;
38
+ private normalizeMiddleware?;
39
+ /**
40
+ * Set the route name
41
+ *
42
+ * @param name
43
+ * @returns
44
+ */
31
45
  name(name: string): this;
46
+ /**
47
+ * Register one or more middleware that will be executed before the route.
48
+ *
49
+ * @param middlewares
50
+ * @returns
51
+ */
52
+ middleware(middlewares: M[] | M): this;
53
+ /**
54
+ * Get the path generated and accessible by this route
55
+ *
56
+ * @param params
57
+ * @returns
58
+ */
32
59
  toPath(params?: RequestData): string;
33
60
  }
34
61
  //#endregion
package/dist/Route.d.mts CHANGED
@@ -5,6 +5,12 @@ import { Middleware as Middleware$1 } from "./types/h3.mjs";
5
5
  import { ClearRequest } from "./ClearRequest.mjs";
6
6
 
7
7
  //#region src/Route.d.ts
8
+ /**
9
+ * @class clear-router Route
10
+ * @description A route describes a single enpoint on clear-router
11
+ * @author 3m1n3nc3
12
+ * @repository https://github.com/arkstack-tmp/clear-router
13
+ */
8
14
  declare class Route<X = any, M = Middleware$1 | Middleware, H = any> {
9
15
  ctx: X;
10
16
  body: RequestData;
@@ -26,9 +32,30 @@ declare class Route<X = any, M = Middleware$1 | Middleware, H = any> {
26
32
  registrationPaths?: string[];
27
33
  parameters?: RouteParameter[];
28
34
  onName?: (name: string, route: Route<X, M, H>, previousName?: string) => void;
35
+ normalizeMiddleware?: (middleware: M) => M;
29
36
  });
30
37
  private onName?;
38
+ private normalizeMiddleware?;
39
+ /**
40
+ * Set the route name
41
+ *
42
+ * @param name
43
+ * @returns
44
+ */
31
45
  name(name: string): this;
46
+ /**
47
+ * Register one or more middleware that will be executed before the route.
48
+ *
49
+ * @param middlewares
50
+ * @returns
51
+ */
52
+ middleware(middlewares: M[] | M): this;
53
+ /**
54
+ * Get the path generated and accessible by this route
55
+ *
56
+ * @param params
57
+ * @returns
58
+ */
32
59
  toPath(params?: RequestData): string;
33
60
  }
34
61
  //#endregion
package/dist/Route.mjs CHANGED
@@ -1,4 +1,10 @@
1
1
  //#region src/Route.ts
2
+ /**
3
+ * @class clear-router Route
4
+ * @description A route describes a single enpoint on clear-router
5
+ * @author 3m1n3nc3
6
+ * @repository https://github.com/arkstack-tmp/clear-router
7
+ */
2
8
  var Route = class {
3
9
  ctx;
4
10
  body = {};
@@ -28,14 +34,40 @@ var Route = class {
28
34
  this.controllerName = Array.isArray(handler) ? handler[0]?.name : void 0;
29
35
  this.actionName = Array.isArray(handler) ? handler[1] : typeof handler === "function" ? handler.constructor.name ?? handler.name : void 0;
30
36
  this.onName = options.onName;
37
+ this.normalizeMiddleware = options.normalizeMiddleware;
31
38
  }
32
39
  onName;
40
+ normalizeMiddleware;
41
+ /**
42
+ * Set the route name
43
+ *
44
+ * @param name
45
+ * @returns
46
+ */
33
47
  name(name) {
34
48
  const previousName = this.routeName;
35
49
  this.routeName = name;
36
50
  this.onName?.(name, this, previousName);
37
51
  return this;
38
52
  }
53
+ /**
54
+ * Register one or more middleware that will be executed before the route.
55
+ *
56
+ * @param middlewares
57
+ * @returns
58
+ */
59
+ middleware(middlewares) {
60
+ const normalized = (Array.isArray(middlewares) ? middlewares : [middlewares]).map((middleware) => this.normalizeMiddleware?.(middleware) ?? middleware);
61
+ this.middlewares.push(...normalized);
62
+ this.middlewareCount = this.middlewares.length;
63
+ return this;
64
+ }
65
+ /**
66
+ * Get the path generated and accessible by this route
67
+ *
68
+ * @param params
69
+ * @returns
70
+ */
39
71
  toPath(params = {}) {
40
72
  return this.path.replace(/\/?\{([^{}]+)\}/g, (segment, raw) => {
41
73
  const optional = raw.endsWith("?");
@@ -1,4 +1,10 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
2
  const require_Request = require('./Request.cjs');
2
3
  const require_Response = require('./Response.cjs');
3
4
  const require_plugins = require('./plugins.cjs');
4
5
  const require_router = require('./router.cjs');
6
+
7
+ exports.CoreRouter = require_router.CoreRouter;
8
+ exports.Request = require_Request.Request;
9
+ exports.Response = require_Response.Response;
10
+ exports.definePlugin = require_plugins.definePlugin;
@@ -1,6 +1,7 @@
1
1
  const require_Request = require('./Request.cjs');
2
2
  const require_Response = require('./Response.cjs');
3
3
  const require_bindings = require('./bindings.cjs');
4
+ const require_ResourceRoutes = require('../ResourceRoutes.cjs');
4
5
  const require_Route = require('../Route.cjs');
5
6
  let node_async_hooks = require("node:async_hooks");
6
7
  let node_module = require("node:module");
@@ -45,6 +46,51 @@ var CoreRouter = class {
45
46
  static groupMiddlewares = [];
46
47
  static globalMiddlewares = [];
47
48
  /**
49
+ * Resolve middlewares before assigning to adapter
50
+ *
51
+ * @param middleware
52
+ * @returns
53
+ */
54
+ static resolveMiddleware(middleware) {
55
+ if (!middleware || typeof middleware === "function" && !require_bindings.isClass(middleware)) return middleware;
56
+ const instance = require_bindings.isClass(middleware) ? new middleware() : middleware;
57
+ if (instance && typeof instance.handle === "function") return instance.handle.bind(instance);
58
+ return middleware;
59
+ }
60
+ static resolveMiddlewares(middlewares = []) {
61
+ return middlewares.map((middleware) => this.resolveMiddleware(middleware));
62
+ }
63
+ static routeSpecificity(route) {
64
+ const path = route.registrationPaths.slice().sort((left, right) => right.length - left.length)[0] ?? route.path;
65
+ const segments = this.normalizePath(path).split("/").filter(Boolean);
66
+ return [
67
+ segments.filter((segment) => !segment.startsWith(":")).length,
68
+ segments.length,
69
+ path.length
70
+ ];
71
+ }
72
+ static orderedRoutes() {
73
+ return Array.from(this.routes).sort((left, right) => {
74
+ const leftScore = this.routeSpecificity(left);
75
+ const rightScore = this.routeSpecificity(right);
76
+ for (let index = 0; index < leftScore.length; index++) {
77
+ const difference = rightScore[index] - leftScore[index];
78
+ if (difference !== 0) return difference;
79
+ }
80
+ return 0;
81
+ });
82
+ }
83
+ static removeRouteMethod(route, method, path) {
84
+ route.methods = route.methods.filter((existingMethod) => existingMethod !== method);
85
+ this.routesByPathMethod.delete(`${method.toUpperCase()} ${path}`);
86
+ const methodKey = method.toUpperCase();
87
+ this.routesByMethod.set(methodKey, (this.routesByMethod.get(methodKey) ?? []).filter((existingRoute) => existingRoute !== route));
88
+ if (!route.methods.some((existingMethod) => existingMethod !== "options")) {
89
+ this.routes.delete(route);
90
+ if (route.routeName && this.routesByName.get(route.routeName) === route) this.routesByName.delete(route.routeName);
91
+ }
92
+ }
93
+ /**
48
94
  * Resets the router to it's default state
49
95
  */
50
96
  static reset() {
@@ -456,17 +502,22 @@ var CoreRouter = class {
456
502
  const fullPath = this.normalizePath(`${activePrefix}/${path}`);
457
503
  const registrationPaths = this.routeRegistrationPaths(fullPath);
458
504
  const parameters = this.parseRouteParameters(fullPath);
459
- const route = new require_Route.Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, [
505
+ for (const method of methods) {
506
+ const existing = this.routesByPathMethod.get(`${method.toUpperCase()} ${fullPath}`);
507
+ if (existing) this.removeRouteMethod(existing, method, fullPath);
508
+ }
509
+ const route = new require_Route.Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, this.resolveMiddlewares([
460
510
  ...this.globalMiddlewares,
461
511
  ...activeGroupMiddlewares,
462
512
  ...middlewares || []
463
- ], {
513
+ ]), {
464
514
  registrationPaths,
465
515
  parameters,
466
516
  onName: (name, route, previousName) => {
467
517
  if (previousName && this.routesByName.get(previousName) === route) this.routesByName.delete(previousName);
468
518
  this.routesByName.set(name, route);
469
- }
519
+ },
520
+ normalizeMiddleware: (middleware) => this.resolveMiddleware(middleware)
470
521
  });
471
522
  if (!methods.includes("options") && !this.routesByPathMethod.get(`OPTIONS ${fullPath}`)) this.options(path, this.createDefaultOptionsHandler());
472
523
  this.routes.add(route);
@@ -486,6 +537,7 @@ var CoreRouter = class {
486
537
  * @param options
487
538
  */
488
539
  static apiResource(basePath, controller, options) {
540
+ const resourceRoutes = {};
489
541
  let paramName = "id";
490
542
  if (!!this.config.inferParamName && this.hasPackageInstalled("@h3ravel/support")) {
491
543
  const { str } = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)("@h3ravel/support");
@@ -522,9 +574,10 @@ var CoreRouter = class {
522
574
  const { method, path } = actions[action];
523
575
  const actionMiddlewares = typeof options?.middlewares === "object" && !Array.isArray(options.middlewares) ? options.middlewares[action] : options?.middlewares;
524
576
  const name = `${basePath}${path}`.replace(/\/:[^/]+|\/\{[^}]+\}/g, "").replace(/\{(\w+):[^}]+\}/g, "$1").replace(/\/|:|[{}]/g, ".").replace(/\.{2,}/g, ".").replace(/^\.|\.$/g, "");
525
- this.add(method, `${basePath}${path}`, [controller, action], Array.isArray(actionMiddlewares) ? actionMiddlewares : actionMiddlewares ? [actionMiddlewares] : void 0).name(name + "." + action.toLowerCase());
577
+ resourceRoutes[action] = this.add(method, `${basePath}${path}`, [controller, action], Array.isArray(actionMiddlewares) ? actionMiddlewares : actionMiddlewares ? [actionMiddlewares] : void 0).name(name + "." + action.toLowerCase());
526
578
  }
527
579
  }
580
+ return new require_ResourceRoutes.ResourceRoutes(resourceRoutes);
528
581
  }
529
582
  /**
530
583
  * Adds a new GET route to the router.
@@ -4,6 +4,7 @@ import { Route } from "../Route.cjs";
4
4
  import { Request } from "./Request.cjs";
5
5
  import { ClearRouterPluginArgumentsContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, PluginArgumentsResolver, PluginBind } from "./plugins.cjs";
6
6
  import { Controller } from "../Controller.cjs";
7
+ import { ResourceRoutes } from "../ResourceRoutes.cjs";
7
8
  import { AsyncLocalStorage } from "node:async_hooks";
8
9
 
9
10
  //#region src/core/router.d.ts
@@ -37,6 +38,17 @@ declare abstract class CoreRouter {
37
38
  static prefix: string;
38
39
  static groupMiddlewares: any[];
39
40
  static globalMiddlewares: any[];
41
+ /**
42
+ * Resolve middlewares before assigning to adapter
43
+ *
44
+ * @param middleware
45
+ * @returns
46
+ */
47
+ protected static resolveMiddleware(middleware: any): any;
48
+ protected static resolveMiddlewares(middlewares?: any[]): any[];
49
+ protected static routeSpecificity(route: Route<any, any, any>): [number, number, number];
50
+ protected static orderedRoutes(): Array<Route<any, any, any>>;
51
+ protected static removeRouteMethod(route: Route<any, any, any>, method: HttpMethod, path: string): void;
40
52
  /**
41
53
  * Resets the router to it's default state
42
54
  */
@@ -134,7 +146,7 @@ declare abstract class CoreRouter {
134
146
  only?: ControllerAction[];
135
147
  except?: ControllerAction[];
136
148
  middlewares?: ApiResourceMiddleware<any>;
137
- }): void;
149
+ }): ResourceRoutes<any, any, any>;
138
150
  /**
139
151
  * Adds a new GET route to the router.
140
152
  *