clear-router 2.7.7 → 2.8.1
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.
- package/dist/{Request-BhTJDR_5.d.mts → Request-Ci0UQ-Vl.d.mts} +27 -0
- package/dist/ResourceRouteSelection.cjs +26 -0
- package/dist/ResourceRouteSelection.d.cts +20 -0
- package/dist/ResourceRouteSelection.d.mts +20 -0
- package/dist/ResourceRouteSelection.mjs +25 -0
- package/dist/ResourceRoutes.cjs +150 -0
- package/dist/ResourceRoutes.d.cts +96 -0
- package/dist/ResourceRoutes.d.mts +96 -0
- package/dist/ResourceRoutes.mjs +150 -0
- package/dist/Route.cjs +32 -0
- package/dist/Route.d.cts +27 -0
- package/dist/Route.d.mts +27 -0
- package/dist/Route.mjs +32 -0
- package/dist/core/helpers.cjs +9 -0
- package/dist/core/helpers.d.cts +4 -0
- package/dist/core/helpers.d.mts +4 -0
- package/dist/core/helpers.mjs +8 -0
- package/dist/core/index.cjs +8 -0
- package/dist/core/index.d.cts +2 -1
- package/dist/core/index.d.mts +2 -1
- package/dist/core/index.mjs +2 -1
- package/dist/core/router.cjs +66 -37
- package/dist/core/router.d.cts +17 -4
- package/dist/core/router.d.mts +17 -4
- package/dist/core/router.mjs +66 -37
- package/dist/decorators/setup.d.mts +0 -1
- package/dist/express/router.cjs +2 -2
- package/dist/express/router.d.cts +5 -4
- package/dist/express/router.d.mts +5 -4
- package/dist/express/router.mjs +2 -2
- package/dist/fastify/router.cjs +2 -2
- package/dist/fastify/router.d.cts +5 -4
- package/dist/fastify/router.d.mts +5 -4
- package/dist/fastify/router.mjs +2 -2
- package/dist/h3/router.cjs +2 -2
- package/dist/h3/router.d.cts +22 -21
- package/dist/h3/router.d.mts +22 -21
- package/dist/h3/router.mjs +2 -2
- package/dist/hono/router.cjs +2 -2
- package/dist/hono/router.d.cts +5 -4
- package/dist/hono/router.d.mts +5 -4
- package/dist/hono/router.mjs +2 -2
- package/dist/index.cjs +3 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/koa/router.cjs +2 -2
- package/dist/koa/router.d.cts +5 -4
- package/dist/koa/router.d.mts +5 -4
- package/dist/koa/router.mjs +2 -2
- package/dist/types/basic.d.cts +13 -4
- package/dist/types/basic.d.mts +13 -4
- package/dist/types/express.d.cts +6 -2
- package/dist/types/express.d.mts +6 -2
- package/dist/types/fastify.d.cts +3 -2
- package/dist/types/fastify.d.mts +3 -2
- package/dist/types/h3.d.cts +7 -2
- package/dist/types/h3.d.mts +7 -2
- package/dist/types/hono.d.cts +4 -3
- package/dist/types/hono.d.mts +4 -3
- package/dist/types/koa.d.cts +3 -2
- package/dist/types/koa.d.mts +3 -2
- package/package.json +1 -1
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("?");
|
package/dist/core/index.cjs
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
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
|
+
const require_helpers = require('./helpers.cjs');
|
|
7
|
+
|
|
8
|
+
exports.CoreRouter = require_router.CoreRouter;
|
|
9
|
+
exports.Request = require_Request.Request;
|
|
10
|
+
exports.Response = require_Response.Response;
|
|
11
|
+
exports.definePlugin = require_plugins.definePlugin;
|
|
12
|
+
exports.wrap = require_helpers.wrap;
|
package/dist/core/index.d.cts
CHANGED
|
@@ -2,4 +2,5 @@ import { Response } from "./Response.cjs";
|
|
|
2
2
|
import { Request } from "./Request.cjs";
|
|
3
3
|
import { ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, definePlugin } from "./plugins.cjs";
|
|
4
4
|
import { CoreRouter } from "./router.cjs";
|
|
5
|
-
|
|
5
|
+
import { wrap } from "./helpers.cjs";
|
|
6
|
+
export { ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, CoreRouter, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, Request, Response, definePlugin, wrap };
|
package/dist/core/index.d.mts
CHANGED
|
@@ -2,4 +2,5 @@ import { Response } from "./Response.mjs";
|
|
|
2
2
|
import { Request } from "./Request.mjs";
|
|
3
3
|
import { ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, definePlugin } from "./plugins.mjs";
|
|
4
4
|
import { CoreRouter } from "./router.mjs";
|
|
5
|
-
|
|
5
|
+
import { wrap } from "./helpers.mjs";
|
|
6
|
+
export { ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, CoreRouter, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, Request, Response, definePlugin, wrap };
|
package/dist/core/index.mjs
CHANGED
|
@@ -2,5 +2,6 @@ import { Request } from "./Request.mjs";
|
|
|
2
2
|
import { Response } from "./Response.mjs";
|
|
3
3
|
import { definePlugin } from "./plugins.mjs";
|
|
4
4
|
import { CoreRouter } from "./router.mjs";
|
|
5
|
+
import { wrap } from "./helpers.mjs";
|
|
5
6
|
|
|
6
|
-
export { CoreRouter, Request, Response, definePlugin };
|
|
7
|
+
export { CoreRouter, Request, Response, definePlugin, wrap };
|
package/dist/core/router.cjs
CHANGED
|
@@ -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,60 @@ 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
|
+
static removeRoute(route) {
|
|
94
|
+
this.routes.delete(route);
|
|
95
|
+
if (route.routeName && this.routesByName.get(route.routeName) === route) this.routesByName.delete(route.routeName);
|
|
96
|
+
for (const method of route.methods) {
|
|
97
|
+
const methodKey = method.toUpperCase();
|
|
98
|
+
this.routesByPathMethod.delete(`${methodKey} ${route.path}`);
|
|
99
|
+
this.routesByMethod.set(methodKey, (this.routesByMethod.get(methodKey) ?? []).filter((existingRoute) => existingRoute !== route));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
48
103
|
* Resets the router to it's default state
|
|
49
104
|
*/
|
|
50
105
|
static reset() {
|
|
@@ -456,17 +511,22 @@ var CoreRouter = class {
|
|
|
456
511
|
const fullPath = this.normalizePath(`${activePrefix}/${path}`);
|
|
457
512
|
const registrationPaths = this.routeRegistrationPaths(fullPath);
|
|
458
513
|
const parameters = this.parseRouteParameters(fullPath);
|
|
459
|
-
|
|
514
|
+
for (const method of methods) {
|
|
515
|
+
const existing = this.routesByPathMethod.get(`${method.toUpperCase()} ${fullPath}`);
|
|
516
|
+
if (existing) this.removeRouteMethod(existing, method, fullPath);
|
|
517
|
+
}
|
|
518
|
+
const route = new require_Route.Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, this.resolveMiddlewares([
|
|
460
519
|
...this.globalMiddlewares,
|
|
461
520
|
...activeGroupMiddlewares,
|
|
462
521
|
...middlewares || []
|
|
463
|
-
], {
|
|
522
|
+
]), {
|
|
464
523
|
registrationPaths,
|
|
465
524
|
parameters,
|
|
466
525
|
onName: (name, route, previousName) => {
|
|
467
526
|
if (previousName && this.routesByName.get(previousName) === route) this.routesByName.delete(previousName);
|
|
468
527
|
this.routesByName.set(name, route);
|
|
469
|
-
}
|
|
528
|
+
},
|
|
529
|
+
normalizeMiddleware: (middleware) => this.resolveMiddleware(middleware)
|
|
470
530
|
});
|
|
471
531
|
if (!methods.includes("options") && !this.routesByPathMethod.get(`OPTIONS ${fullPath}`)) this.options(path, this.createDefaultOptionsHandler());
|
|
472
532
|
this.routes.add(route);
|
|
@@ -491,40 +551,9 @@ var CoreRouter = class {
|
|
|
491
551
|
const { str } = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)("@h3ravel/support");
|
|
492
552
|
paramName = str(basePath).singular().afterLast("/").toString();
|
|
493
553
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
path: "/"
|
|
498
|
-
},
|
|
499
|
-
show: {
|
|
500
|
-
method: "get",
|
|
501
|
-
path: `/:${paramName}`
|
|
502
|
-
},
|
|
503
|
-
create: {
|
|
504
|
-
method: "post",
|
|
505
|
-
path: "/"
|
|
506
|
-
},
|
|
507
|
-
update: {
|
|
508
|
-
method: "put",
|
|
509
|
-
path: `/:${paramName}`
|
|
510
|
-
},
|
|
511
|
-
destroy: {
|
|
512
|
-
method: "delete",
|
|
513
|
-
path: `/:${paramName}`
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
const only = options?.only || Object.keys(actions);
|
|
517
|
-
const except = options?.except || [];
|
|
518
|
-
const preController = typeof controller === "function" ? new controller() : controller;
|
|
519
|
-
for (const action of only) {
|
|
520
|
-
if (except.includes(action)) continue;
|
|
521
|
-
if (typeof preController[action] === "function") {
|
|
522
|
-
const { method, path } = actions[action];
|
|
523
|
-
const actionMiddlewares = typeof options?.middlewares === "object" && !Array.isArray(options.middlewares) ? options.middlewares[action] : options?.middlewares;
|
|
524
|
-
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());
|
|
526
|
-
}
|
|
527
|
-
}
|
|
554
|
+
return new require_ResourceRoutes.ResourceRoutes(basePath, controller, paramName, options, ({ method, path, handler, middlewares, name }) => {
|
|
555
|
+
return this.add(method, path, handler, middlewares).name(name);
|
|
556
|
+
}, (route) => this.removeRoute(route)).register();
|
|
528
557
|
}
|
|
529
558
|
/**
|
|
530
559
|
* Adds a new GET route to the router.
|
package/dist/core/router.d.cts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ApiResourceMiddleware,
|
|
1
|
+
import { ApiResourceMiddleware, HttpMethod, ResourceAction, RouterConfig } from "../types/basic.cjs";
|
|
2
2
|
import { Response } from "./Response.cjs";
|
|
3
3
|
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,18 @@ 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;
|
|
52
|
+
protected static removeRoute(route: Route<any, any, any>): void;
|
|
40
53
|
/**
|
|
41
54
|
* Resets the router to it's default state
|
|
42
55
|
*/
|
|
@@ -131,10 +144,10 @@ declare abstract class CoreRouter {
|
|
|
131
144
|
* @param options
|
|
132
145
|
*/
|
|
133
146
|
static apiResource(basePath: string, controller: any, options?: {
|
|
134
|
-
only?:
|
|
135
|
-
except?:
|
|
147
|
+
only?: ResourceAction[];
|
|
148
|
+
except?: ResourceAction[];
|
|
136
149
|
middlewares?: ApiResourceMiddleware<any>;
|
|
137
|
-
}):
|
|
150
|
+
}): ResourceRoutes<any, any, any>;
|
|
138
151
|
/**
|
|
139
152
|
* Adds a new GET route to the router.
|
|
140
153
|
*
|
package/dist/core/router.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ApiResourceMiddleware,
|
|
1
|
+
import { ApiResourceMiddleware, HttpMethod, ResourceAction, RouterConfig } from "../types/basic.mjs";
|
|
2
2
|
import { Response } from "./Response.mjs";
|
|
3
3
|
import { Route } from "../Route.mjs";
|
|
4
4
|
import { Request } from "./Request.mjs";
|
|
5
5
|
import { ClearRouterPluginArgumentsContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, PluginArgumentsResolver, PluginBind } from "./plugins.mjs";
|
|
6
6
|
import { Controller } from "../Controller.mjs";
|
|
7
|
+
import { ResourceRoutes } from "../ResourceRoutes.mjs";
|
|
7
8
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
9
|
|
|
9
10
|
//#region src/core/router.d.ts
|
|
@@ -37,6 +38,18 @@ 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;
|
|
52
|
+
protected static removeRoute(route: Route<any, any, any>): void;
|
|
40
53
|
/**
|
|
41
54
|
* Resets the router to it's default state
|
|
42
55
|
*/
|
|
@@ -131,10 +144,10 @@ declare abstract class CoreRouter {
|
|
|
131
144
|
* @param options
|
|
132
145
|
*/
|
|
133
146
|
static apiResource(basePath: string, controller: any, options?: {
|
|
134
|
-
only?:
|
|
135
|
-
except?:
|
|
147
|
+
only?: ResourceAction[];
|
|
148
|
+
except?: ResourceAction[];
|
|
136
149
|
middlewares?: ApiResourceMiddleware<any>;
|
|
137
|
-
}):
|
|
150
|
+
}): ResourceRoutes<any, any, any>;
|
|
138
151
|
/**
|
|
139
152
|
* Adds a new GET route to the router.
|
|
140
153
|
*
|
package/dist/core/router.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Request } from "./Request.mjs";
|
|
2
2
|
import { Response } from "./Response.mjs";
|
|
3
3
|
import { Container, getBindingMetadataFromTargets, getDesignParamTypes, getStandardMetadata, isClass } from "./bindings.mjs";
|
|
4
|
+
import { ResourceRoutes } from "../ResourceRoutes.mjs";
|
|
4
5
|
import { Route } from "../Route.mjs";
|
|
5
6
|
import { createRequire } from "node:module";
|
|
6
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -45,6 +46,60 @@ 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" && !isClass(middleware)) return middleware;
|
|
56
|
+
const instance = 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
|
+
static removeRoute(route) {
|
|
94
|
+
this.routes.delete(route);
|
|
95
|
+
if (route.routeName && this.routesByName.get(route.routeName) === route) this.routesByName.delete(route.routeName);
|
|
96
|
+
for (const method of route.methods) {
|
|
97
|
+
const methodKey = method.toUpperCase();
|
|
98
|
+
this.routesByPathMethod.delete(`${methodKey} ${route.path}`);
|
|
99
|
+
this.routesByMethod.set(methodKey, (this.routesByMethod.get(methodKey) ?? []).filter((existingRoute) => existingRoute !== route));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
48
103
|
* Resets the router to it's default state
|
|
49
104
|
*/
|
|
50
105
|
static reset() {
|
|
@@ -456,17 +511,22 @@ var CoreRouter = class {
|
|
|
456
511
|
const fullPath = this.normalizePath(`${activePrefix}/${path}`);
|
|
457
512
|
const registrationPaths = this.routeRegistrationPaths(fullPath);
|
|
458
513
|
const parameters = this.parseRouteParameters(fullPath);
|
|
459
|
-
|
|
514
|
+
for (const method of methods) {
|
|
515
|
+
const existing = this.routesByPathMethod.get(`${method.toUpperCase()} ${fullPath}`);
|
|
516
|
+
if (existing) this.removeRouteMethod(existing, method, fullPath);
|
|
517
|
+
}
|
|
518
|
+
const route = new Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, this.resolveMiddlewares([
|
|
460
519
|
...this.globalMiddlewares,
|
|
461
520
|
...activeGroupMiddlewares,
|
|
462
521
|
...middlewares || []
|
|
463
|
-
], {
|
|
522
|
+
]), {
|
|
464
523
|
registrationPaths,
|
|
465
524
|
parameters,
|
|
466
525
|
onName: (name, route, previousName) => {
|
|
467
526
|
if (previousName && this.routesByName.get(previousName) === route) this.routesByName.delete(previousName);
|
|
468
527
|
this.routesByName.set(name, route);
|
|
469
|
-
}
|
|
528
|
+
},
|
|
529
|
+
normalizeMiddleware: (middleware) => this.resolveMiddleware(middleware)
|
|
470
530
|
});
|
|
471
531
|
if (!methods.includes("options") && !this.routesByPathMethod.get(`OPTIONS ${fullPath}`)) this.options(path, this.createDefaultOptionsHandler());
|
|
472
532
|
this.routes.add(route);
|
|
@@ -491,40 +551,9 @@ var CoreRouter = class {
|
|
|
491
551
|
const { str } = createRequire(import.meta.url)("@h3ravel/support");
|
|
492
552
|
paramName = str(basePath).singular().afterLast("/").toString();
|
|
493
553
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
path: "/"
|
|
498
|
-
},
|
|
499
|
-
show: {
|
|
500
|
-
method: "get",
|
|
501
|
-
path: `/:${paramName}`
|
|
502
|
-
},
|
|
503
|
-
create: {
|
|
504
|
-
method: "post",
|
|
505
|
-
path: "/"
|
|
506
|
-
},
|
|
507
|
-
update: {
|
|
508
|
-
method: "put",
|
|
509
|
-
path: `/:${paramName}`
|
|
510
|
-
},
|
|
511
|
-
destroy: {
|
|
512
|
-
method: "delete",
|
|
513
|
-
path: `/:${paramName}`
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
const only = options?.only || Object.keys(actions);
|
|
517
|
-
const except = options?.except || [];
|
|
518
|
-
const preController = typeof controller === "function" ? new controller() : controller;
|
|
519
|
-
for (const action of only) {
|
|
520
|
-
if (except.includes(action)) continue;
|
|
521
|
-
if (typeof preController[action] === "function") {
|
|
522
|
-
const { method, path } = actions[action];
|
|
523
|
-
const actionMiddlewares = typeof options?.middlewares === "object" && !Array.isArray(options.middlewares) ? options.middlewares[action] : options?.middlewares;
|
|
524
|
-
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());
|
|
526
|
-
}
|
|
527
|
-
}
|
|
554
|
+
return new ResourceRoutes(basePath, controller, paramName, options, ({ method, path, handler, middlewares, name }) => {
|
|
555
|
+
return this.add(method, path, handler, middlewares).name(name);
|
|
556
|
+
}, (route) => this.removeRoute(route)).register();
|
|
528
557
|
}
|
|
529
558
|
/**
|
|
530
559
|
* Adds a new GET route to the router.
|
package/dist/express/router.cjs
CHANGED
|
@@ -62,7 +62,7 @@ var Router = class Router extends require_router.CoreRouter {
|
|
|
62
62
|
* @param options
|
|
63
63
|
*/
|
|
64
64
|
static apiResource(basePath, controller, options) {
|
|
65
|
-
super.apiResource(basePath, controller, options);
|
|
65
|
+
return super.apiResource(basePath, controller, options);
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
68
|
* Adds a new GET route to the router.
|
|
@@ -160,7 +160,7 @@ var Router = class Router extends require_router.CoreRouter {
|
|
|
160
160
|
return super.route(name);
|
|
161
161
|
}
|
|
162
162
|
static async apply(router) {
|
|
163
|
-
for (const route of
|
|
163
|
+
for (const route of this.orderedRoutes()) {
|
|
164
164
|
let handlerFunction = null;
|
|
165
165
|
let instance = null;
|
|
166
166
|
let bindingTarget;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ApiResourceMiddleware,
|
|
1
|
+
import { ApiResourceMiddleware, HttpMethod, ResourceAction } from "../types/basic.cjs";
|
|
2
2
|
import { Handler, HttpContext, Middleware } from "../types/express.cjs";
|
|
3
3
|
import { Route } from "../Route.cjs";
|
|
4
|
+
import { ResourceRoutes } from "../ResourceRoutes.cjs";
|
|
4
5
|
import { CoreRouter } from "../core/router.cjs";
|
|
5
6
|
import { Router } from "express";
|
|
6
7
|
|
|
@@ -33,10 +34,10 @@ declare class Router$1 extends CoreRouter {
|
|
|
33
34
|
* @param options
|
|
34
35
|
*/
|
|
35
36
|
static apiResource(basePath: string, controller: any, options?: {
|
|
36
|
-
only?:
|
|
37
|
-
except?:
|
|
37
|
+
only?: ResourceAction[];
|
|
38
|
+
except?: ResourceAction[];
|
|
38
39
|
middlewares?: ApiResourceMiddleware<Middleware>;
|
|
39
|
-
}):
|
|
40
|
+
}): ResourceRoutes<HttpContext, Middleware, Handler>;
|
|
40
41
|
/**
|
|
41
42
|
* Adds a new GET route to the router.
|
|
42
43
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ApiResourceMiddleware,
|
|
1
|
+
import { ApiResourceMiddleware, HttpMethod, ResourceAction } from "../types/basic.mjs";
|
|
2
2
|
import { Handler, HttpContext, Middleware } from "../types/express.mjs";
|
|
3
3
|
import { Route } from "../Route.mjs";
|
|
4
|
+
import { ResourceRoutes } from "../ResourceRoutes.mjs";
|
|
4
5
|
import { CoreRouter } from "../core/router.mjs";
|
|
5
6
|
import { Router } from "express";
|
|
6
7
|
|
|
@@ -33,10 +34,10 @@ declare class Router$1 extends CoreRouter {
|
|
|
33
34
|
* @param options
|
|
34
35
|
*/
|
|
35
36
|
static apiResource(basePath: string, controller: any, options?: {
|
|
36
|
-
only?:
|
|
37
|
-
except?:
|
|
37
|
+
only?: ResourceAction[];
|
|
38
|
+
except?: ResourceAction[];
|
|
38
39
|
middlewares?: ApiResourceMiddleware<Middleware>;
|
|
39
|
-
}):
|
|
40
|
+
}): ResourceRoutes<HttpContext, Middleware, Handler>;
|
|
40
41
|
/**
|
|
41
42
|
* Adds a new GET route to the router.
|
|
42
43
|
*
|