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/index.d.mts CHANGED
@@ -20,6 +20,11 @@ type ControllerAction = 'index' | 'show' | 'create' | 'update' | 'destroy';
20
20
  type RequestData = Record<string, any>;
21
21
  type ApiResourceMiddleware<M = any> = M | M[] | { [K in ControllerAction]?: M | M[] };
22
22
  interface RouterConfig {
23
+ /**
24
+ * When enabled, API param name will be infered from the route path.
25
+ * So instead of getting /api/users/:id, we will now get /api/users/:user
26
+ */
27
+ inferParamName?: boolean;
23
28
  /**
24
29
  * Configuration for method override functionality, allowing clients to use a
25
30
  * specific header or body parameter to override the HTTP method.
@@ -239,6 +244,19 @@ declare abstract class CoreRouter {
239
244
  private static readonly pluginArgumentResolversKey;
240
245
  private static requestProvider?;
241
246
  private static responseProvider?;
247
+ static config: RouterConfig;
248
+ protected static groupContext: AsyncLocalStorage<{
249
+ prefix: string;
250
+ groupMiddlewares: any[];
251
+ }>;
252
+ protected static pluginRequestContext: AsyncLocalStorage<ClearRouterPluginRequestContext>;
253
+ static routes: Set<Route<any, any, any>>;
254
+ static routesByPathMethod: Map<string, Route<any, any, any>>;
255
+ static routesByMethod: Map<"GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD", Route<any, any, any>[]>;
256
+ static routesByName: Map<string, Route<any, any, any>>;
257
+ static prefix: string;
258
+ static groupMiddlewares: any[];
259
+ static globalMiddlewares: any[];
242
260
  /**
243
261
  * Resets the router to it's default state
244
262
  */
@@ -257,17 +275,16 @@ declare abstract class CoreRouter {
257
275
  prefix: string;
258
276
  groupMiddlewares: any[];
259
277
  }>;
260
- routes: Array<Route<any, any, any>>;
261
- routesByPathMethod: Record<string, Route<any, any, any>>;
262
- routesByMethod: { [method in Uppercase<HttpMethod>]?: Array<Route<any, any, any>> };
263
- routesByName: Record<string, Route<any, any, any>>;
278
+ routes: Set<never>;
279
+ routesByPathMethod: Map<any, any>;
280
+ routesByMethod: Map<any, any>;
281
+ routesByName: Map<any, any>;
264
282
  prefix: string;
265
283
  groupMiddlewares: any[];
266
284
  globalMiddlewares: any[];
267
285
  };
268
286
  protected static bindStateAccessors(): void;
269
287
  protected static createDefaultOptionsHandler(): any;
270
- static config: RouterConfig;
271
288
  static configureDefaults(options?: RouterConfig): void;
272
289
  /**
273
290
  * Use a registered plugin
@@ -279,18 +296,6 @@ declare abstract class CoreRouter {
279
296
  */
280
297
  static use<Options = any>(plugin: ClearRouterPluginInput<Options>, options?: Options): Promise<void>;
281
298
  protected static pluginsReady(): Promise<void>;
282
- protected static groupContext: AsyncLocalStorage<{
283
- prefix: string;
284
- groupMiddlewares: any[];
285
- }>;
286
- protected static pluginRequestContext: AsyncLocalStorage<ClearRouterPluginRequestContext>;
287
- static routes: Array<Route<any, any, any>>;
288
- static routesByPathMethod: Record<string, Route<any, any, any>>;
289
- static routesByMethod: { [method in Uppercase<HttpMethod>]?: Array<Route<any, any, any>> };
290
- static routesByName: Record<string, Route<any, any, any>>;
291
- static prefix: string;
292
- static groupMiddlewares: any[];
293
- static globalMiddlewares: any[];
294
299
  protected static getCurrentPluginRequestContext(): ClearRouterPluginRequestContext | undefined;
295
300
  protected static createPluginRequestContext(ctx: any): ClearRouterPluginRequestContext;
296
301
  protected static createPluginBind(): PluginBind;
@@ -455,6 +460,7 @@ declare abstract class CoreRouter {
455
460
  * @param provider
456
461
  */
457
462
  static setResponseProvider(provider: typeof Response$1): void;
463
+ private static hasPackageInstalled;
458
464
  /**
459
465
  * Provide a class that will overide the base Response instance
460
466
  *
package/dist/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { createRequire } from "node:module";
1
2
  import { AsyncLocalStorage } from "node:async_hooks";
2
3
 
3
4
  //#region src/ClearRequest.ts
@@ -300,21 +301,43 @@ var CoreRouter = class {
300
301
  static pluginArgumentResolversKey = Symbol.for("clear-router:plugin-argument-resolvers");
301
302
  static requestProvider;
302
303
  static responseProvider;
304
+ static config = {
305
+ inferParamName: false,
306
+ methodOverride: {
307
+ enabled: true,
308
+ bodyKeys: ["_method"],
309
+ headerKeys: ["x-http-method"]
310
+ },
311
+ container: {
312
+ enabled: false,
313
+ autoDiscover: false
314
+ }
315
+ };
316
+ static groupContext = new AsyncLocalStorage();
317
+ static pluginRequestContext = new AsyncLocalStorage();
318
+ static routes = /* @__PURE__ */ new Set([]);
319
+ static routesByPathMethod = /* @__PURE__ */ new Map();
320
+ static routesByMethod = /* @__PURE__ */ new Map();
321
+ static routesByName = /* @__PURE__ */ new Map();
322
+ static prefix = "";
323
+ static groupMiddlewares = [];
324
+ static globalMiddlewares = [];
303
325
  /**
304
326
  * Resets the router to it's default state
305
327
  */
306
328
  static reset() {
307
- this.routes = [];
329
+ this.routes.clear();
308
330
  this.prefix = "";
309
331
  this.groupMiddlewares = [];
310
332
  this.globalMiddlewares = [];
311
- this.routesByPathMethod = {};
312
- this.routesByMethod = {};
313
- this.routesByName = {};
333
+ this.routesByPathMethod.clear();
334
+ this.routesByMethod.clear();
335
+ this.routesByName.clear();
314
336
  return this;
315
337
  }
316
338
  static createBaseConfig() {
317
339
  return {
340
+ inferParamName: false,
318
341
  methodOverride: {
319
342
  enabled: true,
320
343
  bodyKeys: ["_method"],
@@ -342,6 +365,7 @@ var CoreRouter = class {
342
365
  const g = globalThis;
343
366
  if (!g[this.defaultConfigKey]) g[this.defaultConfigKey] = this.createBaseConfig();
344
367
  return {
368
+ inferParamName: g[this.defaultConfigKey].inferParamName,
345
369
  methodOverride: { ...g[this.defaultConfigKey].methodOverride },
346
370
  container: { ...g[this.defaultConfigKey].container }
347
371
  };
@@ -373,10 +397,10 @@ var CoreRouter = class {
373
397
  return {
374
398
  config: this.getDefaultConfig(),
375
399
  groupContext: new AsyncLocalStorage(),
376
- routes: [],
377
- routesByPathMethod: {},
378
- routesByMethod: {},
379
- routesByName: {},
400
+ routes: /* @__PURE__ */ new Set([]),
401
+ routesByPathMethod: /* @__PURE__ */ new Map(),
402
+ routesByMethod: /* @__PURE__ */ new Map(),
403
+ routesByName: /* @__PURE__ */ new Map(),
380
404
  prefix: "",
381
405
  groupMiddlewares: [],
382
406
  globalMiddlewares: []
@@ -450,17 +474,6 @@ var CoreRouter = class {
450
474
  }
451
475
  };
452
476
  }
453
- static config = {
454
- methodOverride: {
455
- enabled: true,
456
- bodyKeys: ["_method"],
457
- headerKeys: ["x-http-method"]
458
- },
459
- container: {
460
- enabled: false,
461
- autoDiscover: false
462
- }
463
- };
464
477
  static configureDefaults(options) {
465
478
  const g = globalThis;
466
479
  const defaults = this.mergeConfig(g[this.defaultConfigKey] || this.createBaseConfig(), options);
@@ -521,15 +534,6 @@ var CoreRouter = class {
521
534
  if (!pending.length) return;
522
535
  await Promise.all(pending);
523
536
  }
524
- static groupContext = new AsyncLocalStorage();
525
- static pluginRequestContext = new AsyncLocalStorage();
526
- static routes = [];
527
- static routesByPathMethod = {};
528
- static routesByMethod = {};
529
- static routesByName = {};
530
- static prefix = "";
531
- static groupMiddlewares = [];
532
- static globalMiddlewares = [];
533
537
  static getCurrentPluginRequestContext() {
534
538
  return this.pluginRequestContext.getStore();
535
539
  }
@@ -575,10 +579,10 @@ var CoreRouter = class {
575
579
  headerKeys: ["x-http-method"]
576
580
  } };
577
581
  if (!this.groupContext) this.groupContext = new AsyncLocalStorage();
578
- if (!Array.isArray(this.routes)) this.routes = [];
579
- if (!this.routesByPathMethod || typeof this.routesByPathMethod !== "object") this.routesByPathMethod = {};
580
- if (!this.routesByMethod || typeof this.routesByMethod !== "object") this.routesByMethod = {};
581
- if (!this.routesByName || typeof this.routesByName !== "object") this.routesByName = {};
582
+ if (!this.routes || Array.isArray(this.routes)) this.routes = new Set(this.routes ?? []);
583
+ if (!this.routesByPathMethod) this.routesByPathMethod = /* @__PURE__ */ new Map();
584
+ if (!this.routesByMethod) this.routesByMethod = /* @__PURE__ */ new Map();
585
+ if (!this.routesByName) this.routesByName = /* @__PURE__ */ new Map();
582
586
  if (typeof this.prefix !== "string") this.prefix = "";
583
587
  if (!Array.isArray(this.groupMiddlewares)) this.groupMiddlewares = [];
584
588
  if (!Array.isArray(this.globalMiddlewares)) this.globalMiddlewares = [];
@@ -649,13 +653,15 @@ var CoreRouter = class {
649
653
  if (typeof container.enabled === "boolean") this.config.container.enabled = container.enabled;
650
654
  if (typeof container.autoDiscover === "boolean") this.config.container.autoDiscover = container.autoDiscover;
651
655
  }
656
+ if (options?.inferParamName) this.config.inferParamName = options?.inferParamName;
652
657
  const override = options?.methodOverride;
653
- if (!override) return;
654
- if (typeof override.enabled === "boolean") this.config.methodOverride.enabled = override.enabled;
655
- const bodyKeys = override.bodyKeys;
656
- if (typeof bodyKeys !== "undefined") this.config.methodOverride.bodyKeys = (Array.isArray(bodyKeys) ? bodyKeys : [bodyKeys]).map((e) => String(e).trim()).filter(Boolean);
657
- const headerKeys = override.headerKeys;
658
- if (typeof headerKeys !== "undefined") this.config.methodOverride.headerKeys = (Array.isArray(headerKeys) ? headerKeys : [headerKeys]).map((e) => String(e).trim().toLowerCase()).filter(Boolean);
658
+ if (override) {
659
+ if (typeof override.enabled === "boolean") this.config.methodOverride.enabled = override.enabled;
660
+ const bodyKeys = override.bodyKeys;
661
+ if (typeof bodyKeys !== "undefined") this.config.methodOverride.bodyKeys = (Array.isArray(bodyKeys) ? bodyKeys : [bodyKeys]).map((e) => String(e).trim()).filter(Boolean);
662
+ const headerKeys = override.headerKeys;
663
+ if (typeof headerKeys !== "undefined") this.config.methodOverride.headerKeys = (Array.isArray(headerKeys) ? headerKeys : [headerKeys]).map((e) => String(e).trim().toLowerCase()).filter(Boolean);
664
+ }
659
665
  }
660
666
  static resolveMethodOverride(method, headers, body) {
661
667
  this.ensureState();
@@ -717,16 +723,16 @@ var CoreRouter = class {
717
723
  registrationPaths,
718
724
  parameters,
719
725
  onName: (name, route, previousName) => {
720
- if (previousName && this.routesByName[previousName] === route) delete this.routesByName[previousName];
721
- this.routesByName[name] = route;
726
+ if (previousName && this.routesByName.get(previousName) === route) this.routesByName.delete(previousName);
727
+ this.routesByName.set(name, route);
722
728
  }
723
729
  });
724
- if (!methods.includes("options") && !this.routesByPathMethod[`OPTIONS ${fullPath}`]) this.options(path, this.createDefaultOptionsHandler());
725
- this.routes.push(route);
730
+ if (!methods.includes("options") && !this.routesByPathMethod.get(`OPTIONS ${fullPath}`)) this.options(path, this.createDefaultOptionsHandler());
731
+ this.routes.add(route);
726
732
  for (const method of methods.map((m) => m.toUpperCase())) {
727
- this.routesByPathMethod[`${method} ${fullPath}`] = route;
728
- if (!this.routesByMethod[method]) this.routesByMethod[method] = [];
729
- this.routesByMethod[method].push(route);
733
+ this.routesByPathMethod.set(`${method} ${fullPath}`, route);
734
+ if (!this.routesByMethod.has(method)) this.routesByMethod.set(method, []);
735
+ this.routesByMethod.get(method)?.push(route);
730
736
  }
731
737
  return route;
732
738
  }
@@ -739,6 +745,11 @@ var CoreRouter = class {
739
745
  * @param options
740
746
  */
741
747
  static apiResource(basePath, controller, options) {
748
+ let paramName = "id";
749
+ if (!!this.config.inferParamName && this.hasPackageInstalled("@h3ravel/support")) {
750
+ const { str } = createRequire(import.meta.url)("@h3ravel/support");
751
+ paramName = str(basePath).singular().afterLast("/").toString();
752
+ }
742
753
  const actions = {
743
754
  index: {
744
755
  method: "get",
@@ -746,7 +757,7 @@ var CoreRouter = class {
746
757
  },
747
758
  show: {
748
759
  method: "get",
749
- path: "/:id"
760
+ path: `/:${paramName}`
750
761
  },
751
762
  create: {
752
763
  method: "post",
@@ -754,11 +765,11 @@ var CoreRouter = class {
754
765
  },
755
766
  update: {
756
767
  method: "put",
757
- path: "/:id"
768
+ path: `/:${paramName}`
758
769
  },
759
770
  destroy: {
760
771
  method: "delete",
761
- path: "/:id"
772
+ path: `/:${paramName}`
762
773
  }
763
774
  };
764
775
  const only = options?.only || Object.keys(actions);
@@ -769,7 +780,8 @@ var CoreRouter = class {
769
780
  if (typeof preController[action] === "function") {
770
781
  const { method, path } = actions[action];
771
782
  const actionMiddlewares = typeof options?.middlewares === "object" && !Array.isArray(options.middlewares) ? options.middlewares[action] : options?.middlewares;
772
- this.add(method, `${basePath}${path}`, [controller, action], Array.isArray(actionMiddlewares) ? actionMiddlewares : actionMiddlewares ? [actionMiddlewares] : void 0);
783
+ const name = `${basePath}${path}`.replace(/\/:[^/]+|\/\{[^}]+\}/g, "").replace(/\{(\w+):[^}]+\}/g, "$1").replace(/\/|:|[{}]/g, ".").replace(/\.{2,}/g, ".").replace(/^\.|\.$/g, "");
784
+ this.add(method, `${basePath}${path}`, [controller, action], Array.isArray(actionMiddlewares) ? actionMiddlewares : actionMiddlewares ? [actionMiddlewares] : void 0).name(name + "." + action.toLowerCase());
773
785
  }
774
786
  }
775
787
  }
@@ -888,14 +900,14 @@ var CoreRouter = class {
888
900
  }
889
901
  static allRoutes(type) {
890
902
  this.ensureState();
891
- if (type === "method") return this.routesByMethod;
892
- if (type === "path") return this.routesByPathMethod;
893
- if (type === "name") return this.routesByName;
894
- return this.routes.filter((e) => e.methods.length > 1 || e.methods[0] !== "options");
903
+ if (type === "method") return Object.fromEntries(this.routesByMethod.entries());
904
+ if (type === "path") return Object.fromEntries(this.routesByPathMethod.entries());
905
+ if (type === "name") return Object.fromEntries(this.routesByName.entries());
906
+ return Array.from(this.routes).filter((e) => e.methods.length > 1 || e.methods[0] !== "options");
895
907
  }
896
908
  static route(name) {
897
909
  this.ensureState();
898
- return this.routesByName[name];
910
+ return this.routesByName.get(name);
899
911
  }
900
912
  static url(name, params) {
901
913
  return this.route(name)?.toPath(params);
@@ -916,6 +928,14 @@ var CoreRouter = class {
916
928
  static setResponseProvider(provider) {
917
929
  this.responseProvider = provider;
918
930
  }
931
+ static hasPackageInstalled(name) {
932
+ try {
933
+ createRequire(import.meta.url).resolve(name, { paths: [process.cwd()] });
934
+ return true;
935
+ } catch {
936
+ return false;
937
+ }
938
+ }
919
939
  static initializeInstance(provider, args) {
920
940
  const isRequest = [
921
941
  "CoreRequest",
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  require('../bindings-CLsZjOEy.cjs');
3
- const require_router = require('../router--8gWGXv-.cjs');
3
+ const require_router = require('../router-dJWUSsg1.cjs');
4
4
  const require_responses = require('../responses-Bvnk0uvc.cjs');
5
5
 
6
6
  //#region src/koa/router.ts
@@ -184,7 +184,7 @@ var Router = class Router extends require_router.CoreRouter {
184
184
  * @returns The @koa/router instance with the applied routes
185
185
  */
186
186
  static apply(router) {
187
- for (const route of this.routes) {
187
+ for (const route of Array.from(this.routes)) {
188
188
  let handlerFunction = null;
189
189
  let instance = null;
190
190
  let bindingTarget;
@@ -1,4 +1,4 @@
1
- import { F as ControllerAction, I as HttpMethod, P as ApiResourceMiddleware, _ as KoaRouterApp, g as HttpContext, h as Handler, m as Route, t as CoreRouter, v as Middleware } from "../router-Bu4kNHUo.cjs";
1
+ import { F as ControllerAction, I as HttpMethod, P as ApiResourceMiddleware, _ as KoaRouterApp, g as HttpContext, h as Handler, m as Route, t as CoreRouter, v as Middleware } from "../router-BITqScD_.cjs";
2
2
 
3
3
  //#region src/koa/router.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { F as ControllerAction, I as HttpMethod, P as ApiResourceMiddleware, _ as KoaRouterApp, g as HttpContext, h as Handler, m as Route, t as CoreRouter, v as Middleware } from "../router-awXi28kb.mjs";
1
+ import { F as ControllerAction, I as HttpMethod, P as ApiResourceMiddleware, _ as KoaRouterApp, g as HttpContext, h as Handler, m as Route, t as CoreRouter, v as Middleware } from "../router-Cs8cC5zd.mjs";
2
2
 
3
3
  //#region src/koa/router.d.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  import "../bindings-XLDXFpHZ.mjs";
2
- import { t as CoreRouter } from "../router-DgZmT-17.mjs";
2
+ import { t as CoreRouter } from "../router-BM24N08q.mjs";
3
3
  import { n as resolveResponseMeta, t as isFetchResponse } from "../responses-BvETUeDL.mjs";
4
4
 
5
5
  //#region src/koa/router.ts
@@ -183,7 +183,7 @@ var Router = class Router extends CoreRouter {
183
183
  * @returns The @koa/router instance with the applied routes
184
184
  */
185
185
  static apply(router) {
186
- for (const route of this.routes) {
186
+ for (const route of Array.from(this.routes)) {
187
187
  let handlerFunction = null;
188
188
  let instance = null;
189
189
  let bindingTarget;
@@ -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: Array<Route<any, any, any>>;
348
- routesByPathMethod: Record<string, Route<any, any, any>>;
349
- routesByMethod: { [method in Uppercase<HttpMethod>]?: Array<Route<any, any, any>> };
350
- routesByName: Record<string, Route<any, any, any>>;
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
  *