clear-router 2.1.8 → 2.1.10

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/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Clear Router
2
2
 
3
+ [![NPM Downloads](https://img.shields.io/npm/dt/clear-router.svg)](https://www.npmjs.com/package/clear-router)
4
+ [![npm version](https://img.shields.io/npm/v/clear-router.svg)](https://www.npmjs.com/package/clear-router)
5
+ [![License](https://img.shields.io/npm/l/clear-router.svg)](https://github.com/toneflix/clear-router/blob/main/LICENSE)
6
+ [![Publish to NPM](https://github.com/arkstack-hq/clear-router/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/arkstack-hq/clear-router/actions/workflows/npm-publish.yml)
7
+ [![Run Tests](https://github.com/arkstack-hq/clear-router/actions/workflows/ci.yml/badge.svg)](https://github.com/arkstack-hq/clear-router/actions/workflows/ci.yml)
8
+
3
9
  Laravel-style routing system for H3 and Express.js, with clean route definitions, middleware support, controller bindings and full TypeScript support.
4
10
 
5
11
  ## Installation
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_Route = require('../Route-DhC4kNPX.cjs');
3
+ let node_async_hooks = require("node:async_hooks");
3
4
 
4
5
  //#region src/express/router.ts
5
6
  /**
@@ -10,6 +11,7 @@ const require_Route = require('../Route-DhC4kNPX.cjs');
10
11
  * @repository https://github.com/toneflix/clear-router
11
12
  */
12
13
  var Router = class Router {
14
+ static groupContext = new node_async_hooks.AsyncLocalStorage();
13
15
  /**
14
16
  * All registered routes
15
17
  */
@@ -50,12 +52,15 @@ var Router = class Router {
50
52
  * @param middlewares - Array of middleware functions
51
53
  */
52
54
  static add(methods, path, handler, middlewares) {
55
+ const context = this.groupContext.getStore();
56
+ const activePrefix = context?.prefix ?? this.prefix;
57
+ const activeGroupMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
53
58
  methods = Array.isArray(methods) ? methods : [methods];
54
59
  middlewares = middlewares ? Array.isArray(middlewares) ? middlewares : [middlewares] : void 0;
55
- const fullPath = this.normalizePath(`${this.prefix}/${path}`);
60
+ const fullPath = this.normalizePath(`${activePrefix}/${path}`);
56
61
  const route = new require_Route.Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, [
57
62
  ...this.globalMiddlewares,
58
- ...this.groupMiddlewares,
63
+ ...activeGroupMiddlewares,
59
64
  ...middlewares || []
60
65
  ]);
61
66
  if (!methods.includes("options") && !this.routesByPathMethod[`OPTIONS ${fullPath}`]) this.options(path, ({ res }) => {
@@ -181,17 +186,17 @@ var Router = class Router {
181
186
  * @param middlewares - Middleware functions applied to all routes in group
182
187
  */
183
188
  static async group(prefix, callback, middlewares) {
184
- const previousPrefix = this.prefix;
185
- const previousMiddlewares = this.groupMiddlewares;
189
+ const context = this.groupContext.getStore();
190
+ const previousPrefix = context?.prefix ?? this.prefix;
191
+ const previousMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
186
192
  const fullPrefix = [previousPrefix, prefix].filter(Boolean).join("/");
187
- this.prefix = this.normalizePath(fullPrefix);
188
- this.groupMiddlewares = [...previousMiddlewares, ...middlewares || []];
189
- try {
193
+ const nextContext = {
194
+ prefix: this.normalizePath(fullPrefix),
195
+ groupMiddlewares: [...previousMiddlewares, ...middlewares || []]
196
+ };
197
+ await this.groupContext.run(nextContext, async () => {
190
198
  await Promise.resolve(callback());
191
- } finally {
192
- this.prefix = previousPrefix;
193
- this.groupMiddlewares = previousMiddlewares;
194
- }
199
+ });
195
200
  }
196
201
  /**
197
202
  * Apply global middlewares for the duration of the callback
@@ -10,6 +10,7 @@ import { Router as Router$1 } from "express";
10
10
  * @repository https://github.com/toneflix/clear-router
11
11
  */
12
12
  declare class Router {
13
+ private static readonly groupContext;
13
14
  /**
14
15
  * All registered routes
15
16
  */
@@ -126,9 +127,9 @@ declare class Router {
126
127
  * Get all registered routes with their information
127
128
  * @returns Array of route information objects
128
129
  */
129
- static allRoutes(type?: 'path'): Record<string, Route<HttpContext, Middleware>>;
130
- static allRoutes(type?: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<HttpContext, Middleware>> };
131
- static allRoutes(type?: 'method'): Array<Route<HttpContext, Middleware>>;
130
+ static allRoutes(): Array<Route<HttpContext, Middleware>>;
131
+ static allRoutes(type: 'path'): Record<string, Route<HttpContext, Middleware>>;
132
+ static allRoutes(type: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<HttpContext, Middleware>> };
132
133
  /**
133
134
  * Apply all registered routes to the provided Express Router instance
134
135
  * Handles controller-method binding and middleware application
@@ -10,6 +10,7 @@ import { Router as Router$1 } from "express";
10
10
  * @repository https://github.com/toneflix/clear-router
11
11
  */
12
12
  declare class Router {
13
+ private static readonly groupContext;
13
14
  /**
14
15
  * All registered routes
15
16
  */
@@ -126,9 +127,9 @@ declare class Router {
126
127
  * Get all registered routes with their information
127
128
  * @returns Array of route information objects
128
129
  */
129
- static allRoutes(type?: 'path'): Record<string, Route<HttpContext, Middleware>>;
130
- static allRoutes(type?: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<HttpContext, Middleware>> };
131
- static allRoutes(type?: 'method'): Array<Route<HttpContext, Middleware>>;
130
+ static allRoutes(): Array<Route<HttpContext, Middleware>>;
131
+ static allRoutes(type: 'path'): Record<string, Route<HttpContext, Middleware>>;
132
+ static allRoutes(type: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<HttpContext, Middleware>> };
132
133
  /**
133
134
  * Apply all registered routes to the provided Express Router instance
134
135
  * Handles controller-method binding and middleware application
@@ -1,4 +1,5 @@
1
1
  import { n as ClearRequest, t as Route } from "../Route-BbPXcDGX.mjs";
2
+ import { AsyncLocalStorage } from "node:async_hooks";
2
3
 
3
4
  //#region src/express/router.ts
4
5
  /**
@@ -9,6 +10,7 @@ import { n as ClearRequest, t as Route } from "../Route-BbPXcDGX.mjs";
9
10
  * @repository https://github.com/toneflix/clear-router
10
11
  */
11
12
  var Router = class Router {
13
+ static groupContext = new AsyncLocalStorage();
12
14
  /**
13
15
  * All registered routes
14
16
  */
@@ -49,12 +51,15 @@ var Router = class Router {
49
51
  * @param middlewares - Array of middleware functions
50
52
  */
51
53
  static add(methods, path, handler, middlewares) {
54
+ const context = this.groupContext.getStore();
55
+ const activePrefix = context?.prefix ?? this.prefix;
56
+ const activeGroupMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
52
57
  methods = Array.isArray(methods) ? methods : [methods];
53
58
  middlewares = middlewares ? Array.isArray(middlewares) ? middlewares : [middlewares] : void 0;
54
- const fullPath = this.normalizePath(`${this.prefix}/${path}`);
59
+ const fullPath = this.normalizePath(`${activePrefix}/${path}`);
55
60
  const route = new Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, [
56
61
  ...this.globalMiddlewares,
57
- ...this.groupMiddlewares,
62
+ ...activeGroupMiddlewares,
58
63
  ...middlewares || []
59
64
  ]);
60
65
  if (!methods.includes("options") && !this.routesByPathMethod[`OPTIONS ${fullPath}`]) this.options(path, ({ res }) => {
@@ -180,17 +185,17 @@ var Router = class Router {
180
185
  * @param middlewares - Middleware functions applied to all routes in group
181
186
  */
182
187
  static async group(prefix, callback, middlewares) {
183
- const previousPrefix = this.prefix;
184
- const previousMiddlewares = this.groupMiddlewares;
188
+ const context = this.groupContext.getStore();
189
+ const previousPrefix = context?.prefix ?? this.prefix;
190
+ const previousMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
185
191
  const fullPrefix = [previousPrefix, prefix].filter(Boolean).join("/");
186
- this.prefix = this.normalizePath(fullPrefix);
187
- this.groupMiddlewares = [...previousMiddlewares, ...middlewares || []];
188
- try {
192
+ const nextContext = {
193
+ prefix: this.normalizePath(fullPrefix),
194
+ groupMiddlewares: [...previousMiddlewares, ...middlewares || []]
195
+ };
196
+ await this.groupContext.run(nextContext, async () => {
189
197
  await Promise.resolve(callback());
190
- } finally {
191
- this.prefix = previousPrefix;
192
- this.groupMiddlewares = previousMiddlewares;
193
- }
198
+ });
194
199
  }
195
200
  /**
196
201
  * Apply global middlewares for the duration of the callback
package/dist/h3/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_Route = require('../Route-DhC4kNPX.cjs');
3
+ let node_async_hooks = require("node:async_hooks");
3
4
  let h3 = require("h3");
4
5
 
5
6
  //#region src/h3/router.ts
@@ -10,6 +11,7 @@ let h3 = require("h3");
10
11
  * @repository https://github.com/toneflix/clear-router
11
12
  */
12
13
  var Router = class Router {
14
+ static groupContext = new node_async_hooks.AsyncLocalStorage();
13
15
  /**
14
16
  * All registered routes
15
17
  */
@@ -50,12 +52,15 @@ var Router = class Router {
50
52
  * @param middlewares - Array of middleware functions
51
53
  */
52
54
  static add(methods, path, handler, middlewares) {
55
+ const context = this.groupContext.getStore();
56
+ const activePrefix = context?.prefix ?? this.prefix;
57
+ const activeGroupMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
53
58
  methods = Array.isArray(methods) ? methods : [methods];
54
59
  middlewares = middlewares ? Array.isArray(middlewares) ? middlewares : [middlewares] : void 0;
55
- const fullPath = this.normalizePath(`${this.prefix}/${path}`);
60
+ const fullPath = this.normalizePath(`${activePrefix}/${path}`);
56
61
  const route = new require_Route.Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, [
57
62
  ...this.globalMiddlewares,
58
- ...this.groupMiddlewares,
63
+ ...activeGroupMiddlewares,
59
64
  ...middlewares || []
60
65
  ]);
61
66
  if (!methods.includes("options") && !this.routesByPathMethod[`OPTIONS ${fullPath}`]) this.options(path, ({ res }) => {
@@ -181,17 +186,17 @@ var Router = class Router {
181
186
  * @param middlewares - Middleware functions applied to all routes in group
182
187
  */
183
188
  static async group(prefix, callback, middlewares) {
184
- const previousPrefix = this.prefix;
185
- const previousMiddlewares = this.groupMiddlewares;
189
+ const context = this.groupContext.getStore();
190
+ const previousPrefix = context?.prefix ?? this.prefix;
191
+ const previousMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
186
192
  const fullPrefix = [previousPrefix, prefix].filter(Boolean).join("/");
187
- this.prefix = this.normalizePath(fullPrefix);
188
- this.groupMiddlewares = [...previousMiddlewares, ...middlewares || []];
189
- try {
193
+ const nextContext = {
194
+ prefix: this.normalizePath(fullPrefix),
195
+ groupMiddlewares: [...previousMiddlewares, ...middlewares || []]
196
+ };
197
+ await this.groupContext.run(nextContext, async () => {
190
198
  await Promise.resolve(callback());
191
- } finally {
192
- this.prefix = previousPrefix;
193
- this.groupMiddlewares = previousMiddlewares;
194
- }
199
+ });
195
200
  }
196
201
  /**
197
202
  * Apply global middlewares for the duration of the callback
@@ -9,6 +9,7 @@ import { H3 } from "h3";
9
9
  * @repository https://github.com/toneflix/clear-router
10
10
  */
11
11
  declare class Router {
12
+ private static readonly groupContext;
12
13
  /**
13
14
  * All registered routes
14
15
  */
@@ -124,10 +125,10 @@ declare class Router {
124
125
  /**
125
126
  * Get all registered routes with their information
126
127
  * @returns Array of route information objects
127
- */
128
- static allRoutes(type?: 'path'): Record<string, Route<HttpContext, Middleware>>;
129
- static allRoutes(type?: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<HttpContext, Middleware>> };
130
- static allRoutes(type?: 'method'): Array<Route<HttpContext, Middleware>>;
128
+ */
129
+ static allRoutes(): Array<Route<HttpContext, Middleware>>;
130
+ static allRoutes(type: 'path'): Record<string, Route<HttpContext, Middleware>>;
131
+ static allRoutes(type: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<HttpContext, Middleware>> };
131
132
  /**
132
133
  * Apply all registered routes to the provided H3 Router instance
133
134
  * Handles controller-method binding and middleware application
@@ -9,6 +9,7 @@ import { H3 } from "h3";
9
9
  * @repository https://github.com/toneflix/clear-router
10
10
  */
11
11
  declare class Router {
12
+ private static readonly groupContext;
12
13
  /**
13
14
  * All registered routes
14
15
  */
@@ -124,10 +125,10 @@ declare class Router {
124
125
  /**
125
126
  * Get all registered routes with their information
126
127
  * @returns Array of route information objects
127
- */
128
- static allRoutes(type?: 'path'): Record<string, Route<HttpContext, Middleware>>;
129
- static allRoutes(type?: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<HttpContext, Middleware>> };
130
- static allRoutes(type?: 'method'): Array<Route<HttpContext, Middleware>>;
128
+ */
129
+ static allRoutes(): Array<Route<HttpContext, Middleware>>;
130
+ static allRoutes(type: 'path'): Record<string, Route<HttpContext, Middleware>>;
131
+ static allRoutes(type: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<HttpContext, Middleware>> };
131
132
  /**
132
133
  * Apply all registered routes to the provided H3 Router instance
133
134
  * Handles controller-method binding and middleware application
package/dist/h3/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { n as ClearRequest, t as Route } from "../Route-BbPXcDGX.mjs";
2
+ import { AsyncLocalStorage } from "node:async_hooks";
2
3
  import { getQuery, getRouterParams, readBody } from "h3";
3
4
 
4
5
  //#region src/h3/router.ts
@@ -9,6 +10,7 @@ import { getQuery, getRouterParams, readBody } from "h3";
9
10
  * @repository https://github.com/toneflix/clear-router
10
11
  */
11
12
  var Router = class Router {
13
+ static groupContext = new AsyncLocalStorage();
12
14
  /**
13
15
  * All registered routes
14
16
  */
@@ -49,12 +51,15 @@ var Router = class Router {
49
51
  * @param middlewares - Array of middleware functions
50
52
  */
51
53
  static add(methods, path, handler, middlewares) {
54
+ const context = this.groupContext.getStore();
55
+ const activePrefix = context?.prefix ?? this.prefix;
56
+ const activeGroupMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
52
57
  methods = Array.isArray(methods) ? methods : [methods];
53
58
  middlewares = middlewares ? Array.isArray(middlewares) ? middlewares : [middlewares] : void 0;
54
- const fullPath = this.normalizePath(`${this.prefix}/${path}`);
59
+ const fullPath = this.normalizePath(`${activePrefix}/${path}`);
55
60
  const route = new Route(methods.includes("options") ? methods : methods.concat("options"), fullPath, handler, [
56
61
  ...this.globalMiddlewares,
57
- ...this.groupMiddlewares,
62
+ ...activeGroupMiddlewares,
58
63
  ...middlewares || []
59
64
  ]);
60
65
  if (!methods.includes("options") && !this.routesByPathMethod[`OPTIONS ${fullPath}`]) this.options(path, ({ res }) => {
@@ -180,17 +185,17 @@ var Router = class Router {
180
185
  * @param middlewares - Middleware functions applied to all routes in group
181
186
  */
182
187
  static async group(prefix, callback, middlewares) {
183
- const previousPrefix = this.prefix;
184
- const previousMiddlewares = this.groupMiddlewares;
188
+ const context = this.groupContext.getStore();
189
+ const previousPrefix = context?.prefix ?? this.prefix;
190
+ const previousMiddlewares = context?.groupMiddlewares ?? this.groupMiddlewares;
185
191
  const fullPrefix = [previousPrefix, prefix].filter(Boolean).join("/");
186
- this.prefix = this.normalizePath(fullPrefix);
187
- this.groupMiddlewares = [...previousMiddlewares, ...middlewares || []];
188
- try {
192
+ const nextContext = {
193
+ prefix: this.normalizePath(fullPrefix),
194
+ groupMiddlewares: [...previousMiddlewares, ...middlewares || []]
195
+ };
196
+ await this.groupContext.run(nextContext, async () => {
189
197
  await Promise.resolve(callback());
190
- } finally {
191
- this.prefix = previousPrefix;
192
- this.groupMiddlewares = previousMiddlewares;
193
- }
198
+ });
194
199
  }
195
200
  /**
196
201
  * Apply global middlewares for the duration of the callback
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clear-router",
3
- "version": "2.1.8",
3
+ "version": "2.1.10",
4
4
  "description": "Laravel-style routing system for Express.js and H3, with CommonJS, ESM, and TypeScript support",
5
5
  "keywords": [
6
6
  "h3",
@@ -90,6 +90,7 @@
90
90
  "lint": "eslint",
91
91
  "test:esm": "vitest tests/esm.test.ts",
92
92
  "test:ts": "vitest tests/typescript.test.ts",
93
+ "test:coverage": "vitest run --coverage",
93
94
  "example": "tsx example/express/index.ts",
94
95
  "example:esm": "tsx example/express/esm.ts",
95
96
  "example:ts": "tsx example/express/typescript.ts",