clear-router 2.6.2 → 2.6.4
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/core/index.cjs +1 -1
- package/dist/core/index.d.cts +1 -1
- package/dist/core/index.d.mts +1 -1
- package/dist/core/index.mjs +1 -1
- package/dist/decorators/setup.cjs +1 -1
- package/dist/decorators/setup.d.mts +0 -1
- package/dist/decorators/setup.mjs +1 -1
- package/dist/express/index.cjs +2 -2
- package/dist/express/index.d.cts +1 -1
- package/dist/express/index.d.mts +1 -1
- package/dist/express/index.mjs +2 -2
- package/dist/fastify/index.cjs +2 -2
- package/dist/fastify/index.d.cts +1 -1
- package/dist/fastify/index.d.mts +1 -1
- package/dist/fastify/index.mjs +2 -2
- package/dist/h3/index.cjs +2 -2
- package/dist/h3/index.d.cts +1 -1
- package/dist/h3/index.d.mts +1 -1
- package/dist/h3/index.mjs +2 -2
- package/dist/hono/index.cjs +2 -2
- package/dist/hono/index.d.cts +1 -1
- package/dist/hono/index.d.mts +1 -1
- package/dist/hono/index.mjs +2 -2
- package/dist/index.cjs +74 -54
- package/dist/index.d.cts +23 -17
- package/dist/index.d.mts +23 -17
- package/dist/index.mjs +74 -54
- package/dist/koa/index.cjs +2 -2
- package/dist/koa/index.d.cts +1 -1
- package/dist/koa/index.d.mts +1 -1
- package/dist/koa/index.mjs +2 -2
- package/dist/{router-Bu4kNHUo.d.cts → router-BITqScD_.d.cts} +23 -17
- package/dist/{router-DgZmT-17.mjs → router-BM24N08q.mjs} +74 -54
- package/dist/{router-awXi28kb.d.mts → router-Cs8cC5zd.d.mts} +23 -17
- package/dist/{router--8gWGXv-.cjs → router-dJWUSsg1.cjs} +74 -54
- package/dist/types/basic.d.mts +5 -0
- package/package.json +5 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { a as getStandardMetadata, c as Request, i as getDesignParamTypes, n as Container, o as isClass, r as getBindingMetadataFromTargets, s as Response } from "./bindings-XLDXFpHZ.mjs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
4
|
|
|
4
5
|
//#region src/Route.ts
|
|
@@ -74,21 +75,43 @@ var CoreRouter = class {
|
|
|
74
75
|
static pluginArgumentResolversKey = Symbol.for("clear-router:plugin-argument-resolvers");
|
|
75
76
|
static requestProvider;
|
|
76
77
|
static responseProvider;
|
|
78
|
+
static config = {
|
|
79
|
+
inferParamName: false,
|
|
80
|
+
methodOverride: {
|
|
81
|
+
enabled: true,
|
|
82
|
+
bodyKeys: ["_method"],
|
|
83
|
+
headerKeys: ["x-http-method"]
|
|
84
|
+
},
|
|
85
|
+
container: {
|
|
86
|
+
enabled: false,
|
|
87
|
+
autoDiscover: false
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
static groupContext = new AsyncLocalStorage();
|
|
91
|
+
static pluginRequestContext = new AsyncLocalStorage();
|
|
92
|
+
static routes = /* @__PURE__ */ new Set([]);
|
|
93
|
+
static routesByPathMethod = /* @__PURE__ */ new Map();
|
|
94
|
+
static routesByMethod = /* @__PURE__ */ new Map();
|
|
95
|
+
static routesByName = /* @__PURE__ */ new Map();
|
|
96
|
+
static prefix = "";
|
|
97
|
+
static groupMiddlewares = [];
|
|
98
|
+
static globalMiddlewares = [];
|
|
77
99
|
/**
|
|
78
100
|
* Resets the router to it's default state
|
|
79
101
|
*/
|
|
80
102
|
static reset() {
|
|
81
|
-
this.routes
|
|
103
|
+
this.routes.clear();
|
|
82
104
|
this.prefix = "";
|
|
83
105
|
this.groupMiddlewares = [];
|
|
84
106
|
this.globalMiddlewares = [];
|
|
85
|
-
this.routesByPathMethod
|
|
86
|
-
this.routesByMethod
|
|
87
|
-
this.routesByName
|
|
107
|
+
this.routesByPathMethod.clear();
|
|
108
|
+
this.routesByMethod.clear();
|
|
109
|
+
this.routesByName.clear();
|
|
88
110
|
return this;
|
|
89
111
|
}
|
|
90
112
|
static createBaseConfig() {
|
|
91
113
|
return {
|
|
114
|
+
inferParamName: false,
|
|
92
115
|
methodOverride: {
|
|
93
116
|
enabled: true,
|
|
94
117
|
bodyKeys: ["_method"],
|
|
@@ -116,6 +139,7 @@ var CoreRouter = class {
|
|
|
116
139
|
const g = globalThis;
|
|
117
140
|
if (!g[this.defaultConfigKey]) g[this.defaultConfigKey] = this.createBaseConfig();
|
|
118
141
|
return {
|
|
142
|
+
inferParamName: g[this.defaultConfigKey].inferParamName,
|
|
119
143
|
methodOverride: { ...g[this.defaultConfigKey].methodOverride },
|
|
120
144
|
container: { ...g[this.defaultConfigKey].container }
|
|
121
145
|
};
|
|
@@ -147,10 +171,10 @@ var CoreRouter = class {
|
|
|
147
171
|
return {
|
|
148
172
|
config: this.getDefaultConfig(),
|
|
149
173
|
groupContext: new AsyncLocalStorage(),
|
|
150
|
-
routes: [],
|
|
151
|
-
routesByPathMethod:
|
|
152
|
-
routesByMethod:
|
|
153
|
-
routesByName:
|
|
174
|
+
routes: /* @__PURE__ */ new Set([]),
|
|
175
|
+
routesByPathMethod: /* @__PURE__ */ new Map(),
|
|
176
|
+
routesByMethod: /* @__PURE__ */ new Map(),
|
|
177
|
+
routesByName: /* @__PURE__ */ new Map(),
|
|
154
178
|
prefix: "",
|
|
155
179
|
groupMiddlewares: [],
|
|
156
180
|
globalMiddlewares: []
|
|
@@ -224,17 +248,6 @@ var CoreRouter = class {
|
|
|
224
248
|
}
|
|
225
249
|
};
|
|
226
250
|
}
|
|
227
|
-
static config = {
|
|
228
|
-
methodOverride: {
|
|
229
|
-
enabled: true,
|
|
230
|
-
bodyKeys: ["_method"],
|
|
231
|
-
headerKeys: ["x-http-method"]
|
|
232
|
-
},
|
|
233
|
-
container: {
|
|
234
|
-
enabled: false,
|
|
235
|
-
autoDiscover: false
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
251
|
static configureDefaults(options) {
|
|
239
252
|
const g = globalThis;
|
|
240
253
|
const defaults = this.mergeConfig(g[this.defaultConfigKey] || this.createBaseConfig(), options);
|
|
@@ -295,15 +308,6 @@ var CoreRouter = class {
|
|
|
295
308
|
if (!pending.length) return;
|
|
296
309
|
await Promise.all(pending);
|
|
297
310
|
}
|
|
298
|
-
static groupContext = new AsyncLocalStorage();
|
|
299
|
-
static pluginRequestContext = new AsyncLocalStorage();
|
|
300
|
-
static routes = [];
|
|
301
|
-
static routesByPathMethod = {};
|
|
302
|
-
static routesByMethod = {};
|
|
303
|
-
static routesByName = {};
|
|
304
|
-
static prefix = "";
|
|
305
|
-
static groupMiddlewares = [];
|
|
306
|
-
static globalMiddlewares = [];
|
|
307
311
|
static getCurrentPluginRequestContext() {
|
|
308
312
|
return this.pluginRequestContext.getStore();
|
|
309
313
|
}
|
|
@@ -349,10 +353,10 @@ var CoreRouter = class {
|
|
|
349
353
|
headerKeys: ["x-http-method"]
|
|
350
354
|
} };
|
|
351
355
|
if (!this.groupContext) this.groupContext = new AsyncLocalStorage();
|
|
352
|
-
if (!Array.isArray(this.routes)) this.routes = [];
|
|
353
|
-
if (!this.routesByPathMethod
|
|
354
|
-
if (!this.routesByMethod
|
|
355
|
-
if (!this.routesByName
|
|
356
|
+
if (!this.routes || Array.isArray(this.routes)) this.routes = new Set(this.routes ?? []);
|
|
357
|
+
if (!this.routesByPathMethod) this.routesByPathMethod = /* @__PURE__ */ new Map();
|
|
358
|
+
if (!this.routesByMethod) this.routesByMethod = /* @__PURE__ */ new Map();
|
|
359
|
+
if (!this.routesByName) this.routesByName = /* @__PURE__ */ new Map();
|
|
356
360
|
if (typeof this.prefix !== "string") this.prefix = "";
|
|
357
361
|
if (!Array.isArray(this.groupMiddlewares)) this.groupMiddlewares = [];
|
|
358
362
|
if (!Array.isArray(this.globalMiddlewares)) this.globalMiddlewares = [];
|
|
@@ -423,13 +427,15 @@ var CoreRouter = class {
|
|
|
423
427
|
if (typeof container.enabled === "boolean") this.config.container.enabled = container.enabled;
|
|
424
428
|
if (typeof container.autoDiscover === "boolean") this.config.container.autoDiscover = container.autoDiscover;
|
|
425
429
|
}
|
|
430
|
+
if (options?.inferParamName) this.config.inferParamName = options?.inferParamName;
|
|
426
431
|
const override = options?.methodOverride;
|
|
427
|
-
if (
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
432
|
+
if (override) {
|
|
433
|
+
if (typeof override.enabled === "boolean") this.config.methodOverride.enabled = override.enabled;
|
|
434
|
+
const bodyKeys = override.bodyKeys;
|
|
435
|
+
if (typeof bodyKeys !== "undefined") this.config.methodOverride.bodyKeys = (Array.isArray(bodyKeys) ? bodyKeys : [bodyKeys]).map((e) => String(e).trim()).filter(Boolean);
|
|
436
|
+
const headerKeys = override.headerKeys;
|
|
437
|
+
if (typeof headerKeys !== "undefined") this.config.methodOverride.headerKeys = (Array.isArray(headerKeys) ? headerKeys : [headerKeys]).map((e) => String(e).trim().toLowerCase()).filter(Boolean);
|
|
438
|
+
}
|
|
433
439
|
}
|
|
434
440
|
static resolveMethodOverride(method, headers, body) {
|
|
435
441
|
this.ensureState();
|
|
@@ -491,16 +497,16 @@ var CoreRouter = class {
|
|
|
491
497
|
registrationPaths,
|
|
492
498
|
parameters,
|
|
493
499
|
onName: (name, route, previousName) => {
|
|
494
|
-
if (previousName && this.routesByName
|
|
495
|
-
this.routesByName
|
|
500
|
+
if (previousName && this.routesByName.get(previousName) === route) this.routesByName.delete(previousName);
|
|
501
|
+
this.routesByName.set(name, route);
|
|
496
502
|
}
|
|
497
503
|
});
|
|
498
|
-
if (!methods.includes("options") && !this.routesByPathMethod
|
|
499
|
-
this.routes.
|
|
504
|
+
if (!methods.includes("options") && !this.routesByPathMethod.get(`OPTIONS ${fullPath}`)) this.options(path, this.createDefaultOptionsHandler());
|
|
505
|
+
this.routes.add(route);
|
|
500
506
|
for (const method of methods.map((m) => m.toUpperCase())) {
|
|
501
|
-
this.routesByPathMethod
|
|
502
|
-
if (!this.routesByMethod
|
|
503
|
-
this.routesByMethod
|
|
507
|
+
this.routesByPathMethod.set(`${method} ${fullPath}`, route);
|
|
508
|
+
if (!this.routesByMethod.has(method)) this.routesByMethod.set(method, []);
|
|
509
|
+
this.routesByMethod.get(method)?.push(route);
|
|
504
510
|
}
|
|
505
511
|
return route;
|
|
506
512
|
}
|
|
@@ -513,6 +519,11 @@ var CoreRouter = class {
|
|
|
513
519
|
* @param options
|
|
514
520
|
*/
|
|
515
521
|
static apiResource(basePath, controller, options) {
|
|
522
|
+
let paramName = "id";
|
|
523
|
+
if (!!this.config.inferParamName && this.hasPackageInstalled("@h3ravel/support")) {
|
|
524
|
+
const { str } = createRequire(import.meta.url)("@h3ravel/support");
|
|
525
|
+
paramName = str(basePath).singular().afterLast("/").toString();
|
|
526
|
+
}
|
|
516
527
|
const actions = {
|
|
517
528
|
index: {
|
|
518
529
|
method: "get",
|
|
@@ -520,7 +531,7 @@ var CoreRouter = class {
|
|
|
520
531
|
},
|
|
521
532
|
show: {
|
|
522
533
|
method: "get",
|
|
523
|
-
path:
|
|
534
|
+
path: `/:${paramName}`
|
|
524
535
|
},
|
|
525
536
|
create: {
|
|
526
537
|
method: "post",
|
|
@@ -528,11 +539,11 @@ var CoreRouter = class {
|
|
|
528
539
|
},
|
|
529
540
|
update: {
|
|
530
541
|
method: "put",
|
|
531
|
-
path:
|
|
542
|
+
path: `/:${paramName}`
|
|
532
543
|
},
|
|
533
544
|
destroy: {
|
|
534
545
|
method: "delete",
|
|
535
|
-
path:
|
|
546
|
+
path: `/:${paramName}`
|
|
536
547
|
}
|
|
537
548
|
};
|
|
538
549
|
const only = options?.only || Object.keys(actions);
|
|
@@ -543,7 +554,8 @@ var CoreRouter = class {
|
|
|
543
554
|
if (typeof preController[action] === "function") {
|
|
544
555
|
const { method, path } = actions[action];
|
|
545
556
|
const actionMiddlewares = typeof options?.middlewares === "object" && !Array.isArray(options.middlewares) ? options.middlewares[action] : options?.middlewares;
|
|
546
|
-
|
|
557
|
+
const name = `${basePath}${path}`.replace(/\/:[^/]+|\/\{[^}]+\}/g, "").replace(/\{(\w+):[^}]+\}/g, "$1").replace(/\/|:|[{}]/g, ".").replace(/\.{2,}/g, ".").replace(/^\.|\.$/g, "");
|
|
558
|
+
this.add(method, `${basePath}${path}`, [controller, action], Array.isArray(actionMiddlewares) ? actionMiddlewares : actionMiddlewares ? [actionMiddlewares] : void 0).name(name + "." + action.toLowerCase());
|
|
547
559
|
}
|
|
548
560
|
}
|
|
549
561
|
}
|
|
@@ -662,14 +674,14 @@ var CoreRouter = class {
|
|
|
662
674
|
}
|
|
663
675
|
static allRoutes(type) {
|
|
664
676
|
this.ensureState();
|
|
665
|
-
if (type === "method") return this.routesByMethod;
|
|
666
|
-
if (type === "path") return this.routesByPathMethod;
|
|
667
|
-
if (type === "name") return this.routesByName;
|
|
668
|
-
return this.routes.filter((e) => e.methods.length > 1 || e.methods[0] !== "options");
|
|
677
|
+
if (type === "method") return Object.fromEntries(this.routesByMethod.entries());
|
|
678
|
+
if (type === "path") return Object.fromEntries(this.routesByPathMethod.entries());
|
|
679
|
+
if (type === "name") return Object.fromEntries(this.routesByName.entries());
|
|
680
|
+
return Array.from(this.routes).filter((e) => e.methods.length > 1 || e.methods[0] !== "options");
|
|
669
681
|
}
|
|
670
682
|
static route(name) {
|
|
671
683
|
this.ensureState();
|
|
672
|
-
return this.routesByName
|
|
684
|
+
return this.routesByName.get(name);
|
|
673
685
|
}
|
|
674
686
|
static url(name, params) {
|
|
675
687
|
return this.route(name)?.toPath(params);
|
|
@@ -690,6 +702,14 @@ var CoreRouter = class {
|
|
|
690
702
|
static setResponseProvider(provider) {
|
|
691
703
|
this.responseProvider = provider;
|
|
692
704
|
}
|
|
705
|
+
static hasPackageInstalled(name) {
|
|
706
|
+
try {
|
|
707
|
+
createRequire(import.meta.url).resolve(name, { paths: [process.cwd()] });
|
|
708
|
+
return true;
|
|
709
|
+
} catch {
|
|
710
|
+
return false;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
693
713
|
static initializeInstance(provider, args) {
|
|
694
714
|
const isRequest = [
|
|
695
715
|
"CoreRequest",
|
|
@@ -49,6 +49,11 @@ type ControllerAction = 'index' | 'show' | 'create' | 'update' | 'destroy';
|
|
|
49
49
|
type RequestData = Record<string, any>;
|
|
50
50
|
type ApiResourceMiddleware<M = any> = M | M[] | { [K in ControllerAction]?: M | M[] };
|
|
51
51
|
interface RouterConfig {
|
|
52
|
+
/**
|
|
53
|
+
* When enabled, API param name will be infered from the route path.
|
|
54
|
+
* So instead of getting /api/users/:id, we will now get /api/users/:user
|
|
55
|
+
*/
|
|
56
|
+
inferParamName?: boolean;
|
|
52
57
|
/**
|
|
53
58
|
* Configuration for method override functionality, allowing clients to use a
|
|
54
59
|
* specific header or body parameter to override the HTTP method.
|
|
@@ -326,6 +331,19 @@ declare abstract class CoreRouter {
|
|
|
326
331
|
private static readonly pluginArgumentResolversKey;
|
|
327
332
|
private static requestProvider?;
|
|
328
333
|
private static responseProvider?;
|
|
334
|
+
static config: RouterConfig;
|
|
335
|
+
protected static groupContext: AsyncLocalStorage<{
|
|
336
|
+
prefix: string;
|
|
337
|
+
groupMiddlewares: any[];
|
|
338
|
+
}>;
|
|
339
|
+
protected static pluginRequestContext: AsyncLocalStorage<ClearRouterPluginRequestContext>;
|
|
340
|
+
static routes: Set<Route<any, any, any>>;
|
|
341
|
+
static routesByPathMethod: Map<string, Route<any, any, any>>;
|
|
342
|
+
static routesByMethod: Map<"GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD", Route<any, any, any>[]>;
|
|
343
|
+
static routesByName: Map<string, Route<any, any, any>>;
|
|
344
|
+
static prefix: string;
|
|
345
|
+
static groupMiddlewares: any[];
|
|
346
|
+
static globalMiddlewares: any[];
|
|
329
347
|
/**
|
|
330
348
|
* Resets the router to it's default state
|
|
331
349
|
*/
|
|
@@ -344,17 +362,16 @@ declare abstract class CoreRouter {
|
|
|
344
362
|
prefix: string;
|
|
345
363
|
groupMiddlewares: any[];
|
|
346
364
|
}>;
|
|
347
|
-
routes:
|
|
348
|
-
routesByPathMethod:
|
|
349
|
-
routesByMethod:
|
|
350
|
-
routesByName:
|
|
365
|
+
routes: Set<never>;
|
|
366
|
+
routesByPathMethod: Map<any, any>;
|
|
367
|
+
routesByMethod: Map<any, any>;
|
|
368
|
+
routesByName: Map<any, any>;
|
|
351
369
|
prefix: string;
|
|
352
370
|
groupMiddlewares: any[];
|
|
353
371
|
globalMiddlewares: any[];
|
|
354
372
|
};
|
|
355
373
|
protected static bindStateAccessors(): void;
|
|
356
374
|
protected static createDefaultOptionsHandler(): any;
|
|
357
|
-
static config: RouterConfig;
|
|
358
375
|
static configureDefaults(options?: RouterConfig): void;
|
|
359
376
|
/**
|
|
360
377
|
* Use a registered plugin
|
|
@@ -366,18 +383,6 @@ declare abstract class CoreRouter {
|
|
|
366
383
|
*/
|
|
367
384
|
static use<Options = any>(plugin: ClearRouterPluginInput<Options>, options?: Options): Promise<void>;
|
|
368
385
|
protected static pluginsReady(): Promise<void>;
|
|
369
|
-
protected static groupContext: AsyncLocalStorage<{
|
|
370
|
-
prefix: string;
|
|
371
|
-
groupMiddlewares: any[];
|
|
372
|
-
}>;
|
|
373
|
-
protected static pluginRequestContext: AsyncLocalStorage<ClearRouterPluginRequestContext>;
|
|
374
|
-
static routes: Array<Route<any, any, any>>;
|
|
375
|
-
static routesByPathMethod: Record<string, Route<any, any, any>>;
|
|
376
|
-
static routesByMethod: { [method in Uppercase<HttpMethod>]?: Array<Route<any, any, any>> };
|
|
377
|
-
static routesByName: Record<string, Route<any, any, any>>;
|
|
378
|
-
static prefix: string;
|
|
379
|
-
static groupMiddlewares: any[];
|
|
380
|
-
static globalMiddlewares: any[];
|
|
381
386
|
protected static getCurrentPluginRequestContext(): ClearRouterPluginRequestContext | undefined;
|
|
382
387
|
protected static createPluginRequestContext(ctx: any): ClearRouterPluginRequestContext;
|
|
383
388
|
protected static createPluginBind(): PluginBind;
|
|
@@ -542,6 +547,7 @@ declare abstract class CoreRouter {
|
|
|
542
547
|
* @param provider
|
|
543
548
|
*/
|
|
544
549
|
static setResponseProvider(provider: typeof Response$2): void;
|
|
550
|
+
private static hasPackageInstalled;
|
|
545
551
|
/**
|
|
546
552
|
* Provide a class that will overide the base Response instance
|
|
547
553
|
*
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const require_bindings = require('./bindings-CLsZjOEy.cjs');
|
|
2
2
|
let node_async_hooks = require("node:async_hooks");
|
|
3
|
+
let node_module = require("node:module");
|
|
3
4
|
|
|
4
5
|
//#region src/Route.ts
|
|
5
6
|
var Route = class {
|
|
@@ -74,21 +75,43 @@ var CoreRouter = class {
|
|
|
74
75
|
static pluginArgumentResolversKey = Symbol.for("clear-router:plugin-argument-resolvers");
|
|
75
76
|
static requestProvider;
|
|
76
77
|
static responseProvider;
|
|
78
|
+
static config = {
|
|
79
|
+
inferParamName: false,
|
|
80
|
+
methodOverride: {
|
|
81
|
+
enabled: true,
|
|
82
|
+
bodyKeys: ["_method"],
|
|
83
|
+
headerKeys: ["x-http-method"]
|
|
84
|
+
},
|
|
85
|
+
container: {
|
|
86
|
+
enabled: false,
|
|
87
|
+
autoDiscover: false
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
static groupContext = new node_async_hooks.AsyncLocalStorage();
|
|
91
|
+
static pluginRequestContext = new node_async_hooks.AsyncLocalStorage();
|
|
92
|
+
static routes = /* @__PURE__ */ new Set([]);
|
|
93
|
+
static routesByPathMethod = /* @__PURE__ */ new Map();
|
|
94
|
+
static routesByMethod = /* @__PURE__ */ new Map();
|
|
95
|
+
static routesByName = /* @__PURE__ */ new Map();
|
|
96
|
+
static prefix = "";
|
|
97
|
+
static groupMiddlewares = [];
|
|
98
|
+
static globalMiddlewares = [];
|
|
77
99
|
/**
|
|
78
100
|
* Resets the router to it's default state
|
|
79
101
|
*/
|
|
80
102
|
static reset() {
|
|
81
|
-
this.routes
|
|
103
|
+
this.routes.clear();
|
|
82
104
|
this.prefix = "";
|
|
83
105
|
this.groupMiddlewares = [];
|
|
84
106
|
this.globalMiddlewares = [];
|
|
85
|
-
this.routesByPathMethod
|
|
86
|
-
this.routesByMethod
|
|
87
|
-
this.routesByName
|
|
107
|
+
this.routesByPathMethod.clear();
|
|
108
|
+
this.routesByMethod.clear();
|
|
109
|
+
this.routesByName.clear();
|
|
88
110
|
return this;
|
|
89
111
|
}
|
|
90
112
|
static createBaseConfig() {
|
|
91
113
|
return {
|
|
114
|
+
inferParamName: false,
|
|
92
115
|
methodOverride: {
|
|
93
116
|
enabled: true,
|
|
94
117
|
bodyKeys: ["_method"],
|
|
@@ -116,6 +139,7 @@ var CoreRouter = class {
|
|
|
116
139
|
const g = globalThis;
|
|
117
140
|
if (!g[this.defaultConfigKey]) g[this.defaultConfigKey] = this.createBaseConfig();
|
|
118
141
|
return {
|
|
142
|
+
inferParamName: g[this.defaultConfigKey].inferParamName,
|
|
119
143
|
methodOverride: { ...g[this.defaultConfigKey].methodOverride },
|
|
120
144
|
container: { ...g[this.defaultConfigKey].container }
|
|
121
145
|
};
|
|
@@ -147,10 +171,10 @@ var CoreRouter = class {
|
|
|
147
171
|
return {
|
|
148
172
|
config: this.getDefaultConfig(),
|
|
149
173
|
groupContext: new node_async_hooks.AsyncLocalStorage(),
|
|
150
|
-
routes: [],
|
|
151
|
-
routesByPathMethod:
|
|
152
|
-
routesByMethod:
|
|
153
|
-
routesByName:
|
|
174
|
+
routes: /* @__PURE__ */ new Set([]),
|
|
175
|
+
routesByPathMethod: /* @__PURE__ */ new Map(),
|
|
176
|
+
routesByMethod: /* @__PURE__ */ new Map(),
|
|
177
|
+
routesByName: /* @__PURE__ */ new Map(),
|
|
154
178
|
prefix: "",
|
|
155
179
|
groupMiddlewares: [],
|
|
156
180
|
globalMiddlewares: []
|
|
@@ -224,17 +248,6 @@ var CoreRouter = class {
|
|
|
224
248
|
}
|
|
225
249
|
};
|
|
226
250
|
}
|
|
227
|
-
static config = {
|
|
228
|
-
methodOverride: {
|
|
229
|
-
enabled: true,
|
|
230
|
-
bodyKeys: ["_method"],
|
|
231
|
-
headerKeys: ["x-http-method"]
|
|
232
|
-
},
|
|
233
|
-
container: {
|
|
234
|
-
enabled: false,
|
|
235
|
-
autoDiscover: false
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
251
|
static configureDefaults(options) {
|
|
239
252
|
const g = globalThis;
|
|
240
253
|
const defaults = this.mergeConfig(g[this.defaultConfigKey] || this.createBaseConfig(), options);
|
|
@@ -295,15 +308,6 @@ var CoreRouter = class {
|
|
|
295
308
|
if (!pending.length) return;
|
|
296
309
|
await Promise.all(pending);
|
|
297
310
|
}
|
|
298
|
-
static groupContext = new node_async_hooks.AsyncLocalStorage();
|
|
299
|
-
static pluginRequestContext = new node_async_hooks.AsyncLocalStorage();
|
|
300
|
-
static routes = [];
|
|
301
|
-
static routesByPathMethod = {};
|
|
302
|
-
static routesByMethod = {};
|
|
303
|
-
static routesByName = {};
|
|
304
|
-
static prefix = "";
|
|
305
|
-
static groupMiddlewares = [];
|
|
306
|
-
static globalMiddlewares = [];
|
|
307
311
|
static getCurrentPluginRequestContext() {
|
|
308
312
|
return this.pluginRequestContext.getStore();
|
|
309
313
|
}
|
|
@@ -349,10 +353,10 @@ var CoreRouter = class {
|
|
|
349
353
|
headerKeys: ["x-http-method"]
|
|
350
354
|
} };
|
|
351
355
|
if (!this.groupContext) this.groupContext = new node_async_hooks.AsyncLocalStorage();
|
|
352
|
-
if (!Array.isArray(this.routes)) this.routes = [];
|
|
353
|
-
if (!this.routesByPathMethod
|
|
354
|
-
if (!this.routesByMethod
|
|
355
|
-
if (!this.routesByName
|
|
356
|
+
if (!this.routes || Array.isArray(this.routes)) this.routes = new Set(this.routes ?? []);
|
|
357
|
+
if (!this.routesByPathMethod) this.routesByPathMethod = /* @__PURE__ */ new Map();
|
|
358
|
+
if (!this.routesByMethod) this.routesByMethod = /* @__PURE__ */ new Map();
|
|
359
|
+
if (!this.routesByName) this.routesByName = /* @__PURE__ */ new Map();
|
|
356
360
|
if (typeof this.prefix !== "string") this.prefix = "";
|
|
357
361
|
if (!Array.isArray(this.groupMiddlewares)) this.groupMiddlewares = [];
|
|
358
362
|
if (!Array.isArray(this.globalMiddlewares)) this.globalMiddlewares = [];
|
|
@@ -423,13 +427,15 @@ var CoreRouter = class {
|
|
|
423
427
|
if (typeof container.enabled === "boolean") this.config.container.enabled = container.enabled;
|
|
424
428
|
if (typeof container.autoDiscover === "boolean") this.config.container.autoDiscover = container.autoDiscover;
|
|
425
429
|
}
|
|
430
|
+
if (options?.inferParamName) this.config.inferParamName = options?.inferParamName;
|
|
426
431
|
const override = options?.methodOverride;
|
|
427
|
-
if (
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
432
|
+
if (override) {
|
|
433
|
+
if (typeof override.enabled === "boolean") this.config.methodOverride.enabled = override.enabled;
|
|
434
|
+
const bodyKeys = override.bodyKeys;
|
|
435
|
+
if (typeof bodyKeys !== "undefined") this.config.methodOverride.bodyKeys = (Array.isArray(bodyKeys) ? bodyKeys : [bodyKeys]).map((e) => String(e).trim()).filter(Boolean);
|
|
436
|
+
const headerKeys = override.headerKeys;
|
|
437
|
+
if (typeof headerKeys !== "undefined") this.config.methodOverride.headerKeys = (Array.isArray(headerKeys) ? headerKeys : [headerKeys]).map((e) => String(e).trim().toLowerCase()).filter(Boolean);
|
|
438
|
+
}
|
|
433
439
|
}
|
|
434
440
|
static resolveMethodOverride(method, headers, body) {
|
|
435
441
|
this.ensureState();
|
|
@@ -491,16 +497,16 @@ var CoreRouter = class {
|
|
|
491
497
|
registrationPaths,
|
|
492
498
|
parameters,
|
|
493
499
|
onName: (name, route, previousName) => {
|
|
494
|
-
if (previousName && this.routesByName
|
|
495
|
-
this.routesByName
|
|
500
|
+
if (previousName && this.routesByName.get(previousName) === route) this.routesByName.delete(previousName);
|
|
501
|
+
this.routesByName.set(name, route);
|
|
496
502
|
}
|
|
497
503
|
});
|
|
498
|
-
if (!methods.includes("options") && !this.routesByPathMethod
|
|
499
|
-
this.routes.
|
|
504
|
+
if (!methods.includes("options") && !this.routesByPathMethod.get(`OPTIONS ${fullPath}`)) this.options(path, this.createDefaultOptionsHandler());
|
|
505
|
+
this.routes.add(route);
|
|
500
506
|
for (const method of methods.map((m) => m.toUpperCase())) {
|
|
501
|
-
this.routesByPathMethod
|
|
502
|
-
if (!this.routesByMethod
|
|
503
|
-
this.routesByMethod
|
|
507
|
+
this.routesByPathMethod.set(`${method} ${fullPath}`, route);
|
|
508
|
+
if (!this.routesByMethod.has(method)) this.routesByMethod.set(method, []);
|
|
509
|
+
this.routesByMethod.get(method)?.push(route);
|
|
504
510
|
}
|
|
505
511
|
return route;
|
|
506
512
|
}
|
|
@@ -513,6 +519,11 @@ var CoreRouter = class {
|
|
|
513
519
|
* @param options
|
|
514
520
|
*/
|
|
515
521
|
static apiResource(basePath, controller, options) {
|
|
522
|
+
let paramName = "id";
|
|
523
|
+
if (!!this.config.inferParamName && this.hasPackageInstalled("@h3ravel/support")) {
|
|
524
|
+
const { str } = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)("@h3ravel/support");
|
|
525
|
+
paramName = str(basePath).singular().afterLast("/").toString();
|
|
526
|
+
}
|
|
516
527
|
const actions = {
|
|
517
528
|
index: {
|
|
518
529
|
method: "get",
|
|
@@ -520,7 +531,7 @@ var CoreRouter = class {
|
|
|
520
531
|
},
|
|
521
532
|
show: {
|
|
522
533
|
method: "get",
|
|
523
|
-
path:
|
|
534
|
+
path: `/:${paramName}`
|
|
524
535
|
},
|
|
525
536
|
create: {
|
|
526
537
|
method: "post",
|
|
@@ -528,11 +539,11 @@ var CoreRouter = class {
|
|
|
528
539
|
},
|
|
529
540
|
update: {
|
|
530
541
|
method: "put",
|
|
531
|
-
path:
|
|
542
|
+
path: `/:${paramName}`
|
|
532
543
|
},
|
|
533
544
|
destroy: {
|
|
534
545
|
method: "delete",
|
|
535
|
-
path:
|
|
546
|
+
path: `/:${paramName}`
|
|
536
547
|
}
|
|
537
548
|
};
|
|
538
549
|
const only = options?.only || Object.keys(actions);
|
|
@@ -543,7 +554,8 @@ var CoreRouter = class {
|
|
|
543
554
|
if (typeof preController[action] === "function") {
|
|
544
555
|
const { method, path } = actions[action];
|
|
545
556
|
const actionMiddlewares = typeof options?.middlewares === "object" && !Array.isArray(options.middlewares) ? options.middlewares[action] : options?.middlewares;
|
|
546
|
-
|
|
557
|
+
const name = `${basePath}${path}`.replace(/\/:[^/]+|\/\{[^}]+\}/g, "").replace(/\{(\w+):[^}]+\}/g, "$1").replace(/\/|:|[{}]/g, ".").replace(/\.{2,}/g, ".").replace(/^\.|\.$/g, "");
|
|
558
|
+
this.add(method, `${basePath}${path}`, [controller, action], Array.isArray(actionMiddlewares) ? actionMiddlewares : actionMiddlewares ? [actionMiddlewares] : void 0).name(name + "." + action.toLowerCase());
|
|
547
559
|
}
|
|
548
560
|
}
|
|
549
561
|
}
|
|
@@ -662,14 +674,14 @@ var CoreRouter = class {
|
|
|
662
674
|
}
|
|
663
675
|
static allRoutes(type) {
|
|
664
676
|
this.ensureState();
|
|
665
|
-
if (type === "method") return this.routesByMethod;
|
|
666
|
-
if (type === "path") return this.routesByPathMethod;
|
|
667
|
-
if (type === "name") return this.routesByName;
|
|
668
|
-
return this.routes.filter((e) => e.methods.length > 1 || e.methods[0] !== "options");
|
|
677
|
+
if (type === "method") return Object.fromEntries(this.routesByMethod.entries());
|
|
678
|
+
if (type === "path") return Object.fromEntries(this.routesByPathMethod.entries());
|
|
679
|
+
if (type === "name") return Object.fromEntries(this.routesByName.entries());
|
|
680
|
+
return Array.from(this.routes).filter((e) => e.methods.length > 1 || e.methods[0] !== "options");
|
|
669
681
|
}
|
|
670
682
|
static route(name) {
|
|
671
683
|
this.ensureState();
|
|
672
|
-
return this.routesByName
|
|
684
|
+
return this.routesByName.get(name);
|
|
673
685
|
}
|
|
674
686
|
static url(name, params) {
|
|
675
687
|
return this.route(name)?.toPath(params);
|
|
@@ -690,6 +702,14 @@ var CoreRouter = class {
|
|
|
690
702
|
static setResponseProvider(provider) {
|
|
691
703
|
this.responseProvider = provider;
|
|
692
704
|
}
|
|
705
|
+
static hasPackageInstalled(name) {
|
|
706
|
+
try {
|
|
707
|
+
(0, node_module.createRequire)(require("url").pathToFileURL(__filename).href).resolve(name, { paths: [process.cwd()] });
|
|
708
|
+
return true;
|
|
709
|
+
} catch {
|
|
710
|
+
return false;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
693
713
|
static initializeInstance(provider, args) {
|
|
694
714
|
const isRequest = [
|
|
695
715
|
"CoreRequest",
|
package/dist/types/basic.d.mts
CHANGED
|
@@ -17,6 +17,11 @@ type ControllerAction = 'index' | 'show' | 'create' | 'update' | 'destroy';
|
|
|
17
17
|
type RequestData = Record<string, any>;
|
|
18
18
|
type ApiResourceMiddleware<M = any> = M | M[] | { [K in ControllerAction]?: M | M[] };
|
|
19
19
|
interface RouterConfig {
|
|
20
|
+
/**
|
|
21
|
+
* When enabled, API param name will be infered from the route path.
|
|
22
|
+
* So instead of getting /api/users/:id, we will now get /api/users/:user
|
|
23
|
+
*/
|
|
24
|
+
inferParamName?: boolean;
|
|
20
25
|
/**
|
|
21
26
|
* Configuration for method override functionality, allowing clients to use a
|
|
22
27
|
* specific header or body parameter to override the HTTP method.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clear-router",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.4",
|
|
4
4
|
"description": "Laravel-style routing for Node.js with support for Express, H3, Fastify, Hono, and Koa, including CommonJS, ESM, and TypeScript support.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"h3",
|
|
@@ -88,6 +88,7 @@
|
|
|
88
88
|
"h3": "^2.0.1-rc.16",
|
|
89
89
|
"hono": "^4.0.0",
|
|
90
90
|
"koa": "^3.0.0",
|
|
91
|
+
"@h3ravel/support": "^0.15.11",
|
|
91
92
|
"reflect-metadata": "^0.2.2"
|
|
92
93
|
},
|
|
93
94
|
"peerDependenciesMeta": {
|
|
@@ -109,6 +110,9 @@
|
|
|
109
110
|
"koa": {
|
|
110
111
|
"optional": true
|
|
111
112
|
},
|
|
113
|
+
"@h3ravel/support": {
|
|
114
|
+
"optional": true
|
|
115
|
+
},
|
|
112
116
|
"reflect-metadata": {
|
|
113
117
|
"optional": true
|
|
114
118
|
}
|