clear-router 2.9.0 → 2.9.2

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.
@@ -0,0 +1,98 @@
1
+ //#region src/decorators/middleware.ts
2
+ const CLASS_KEY = "__class__";
3
+ const metadataKey = Symbol.for("clear-router:middleware-metadata");
4
+ const store = /* @__PURE__ */ new WeakMap();
5
+ /**
6
+ * Attach one or more middleware to a controller class or a controller method.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * @Middleware([auth])
11
+ * class AccountController {}
12
+ *
13
+ * class LoginController {
14
+ * @Middleware(GuestMiddleware)
15
+ * create () {}
16
+ * }
17
+ * ```
18
+ *
19
+ * Accepts the middleware variadically or as arrays, and every supported
20
+ * middleware shape: callbacks, middleware classes, or instances exposing a
21
+ * `handle` method.
22
+ *
23
+ * @param middlewares
24
+ * @returns
25
+ */
26
+ function middleware(...middlewares) {
27
+ const flattened = middlewares.flat();
28
+ return ((target, propertyKeyOrContext) => {
29
+ if (isStandardClassContext(propertyKeyOrContext)) {
30
+ setClassMiddlewareMetadata(target, flattened);
31
+ setStandardMetadata(propertyKeyOrContext.metadata, CLASS_KEY, flattened);
32
+ return;
33
+ }
34
+ if (isStandardMethodContext(propertyKeyOrContext)) {
35
+ setStandardMetadata(propertyKeyOrContext.metadata, propertyKeyOrContext.name, flattened);
36
+ return;
37
+ }
38
+ if (typeof propertyKeyOrContext === "undefined") {
39
+ setClassMiddlewareMetadata(target, flattened);
40
+ return;
41
+ }
42
+ setMiddlewareMetadata(target, propertyKeyOrContext, flattened);
43
+ });
44
+ }
45
+ /**
46
+ * Collect the decorator-declared middleware for a controller route handler,
47
+ * ordered class-level first then method-level. Returns an empty array for
48
+ * non-controller (callback) handlers or handlers without any decorators.
49
+ *
50
+ * @param handler
51
+ * @returns
52
+ */
53
+ function getControllerMiddlewares(handler) {
54
+ if (!Array.isArray(handler) || handler.length !== 2) return [];
55
+ const [controller, method] = handler;
56
+ if (!controller) return [];
57
+ const constructor = typeof controller === "function" ? controller : controller.constructor;
58
+ const prototype = typeof controller === "function" ? controller.prototype : Object.getPrototypeOf(controller);
59
+ const standardMetadata = constructor?.[Symbol.metadata];
60
+ const classMiddlewares = getMiddlewareMetadata(constructor, CLASS_KEY) ?? getMiddlewareMetadata(prototype, CLASS_KEY) ?? getStandardMetadata(standardMetadata, CLASS_KEY) ?? [];
61
+ const methodMiddlewares = getMiddlewareMetadata(prototype, method) ?? getMiddlewareMetadata(constructor, method) ?? getStandardMetadata(standardMetadata, method) ?? [];
62
+ return [...classMiddlewares, ...methodMiddlewares];
63
+ }
64
+ function setClassMiddlewareMetadata(target, middlewares) {
65
+ setMiddlewareMetadata(target, CLASS_KEY, middlewares);
66
+ const prototype = target.prototype;
67
+ if (prototype) setMiddlewareMetadata(prototype, CLASS_KEY, middlewares);
68
+ }
69
+ function setMiddlewareMetadata(target, propertyKey, middlewares) {
70
+ const map = store.get(target) ?? /* @__PURE__ */ new Map();
71
+ const existing = map.get(propertyKey);
72
+ map.set(propertyKey, existing ? [...existing, ...middlewares] : middlewares);
73
+ store.set(target, map);
74
+ }
75
+ function getMiddlewareMetadata(target, propertyKey) {
76
+ if (!target) return void 0;
77
+ return store.get(target)?.get(propertyKey);
78
+ }
79
+ function setStandardMetadata(metadata, propertyKey, middlewares) {
80
+ if (!metadata) return;
81
+ const record = metadata;
82
+ record[metadataKey] = record[metadataKey] ?? {};
83
+ const existing = record[metadataKey][propertyKey];
84
+ record[metadataKey][propertyKey] = existing ? [...existing, ...middlewares] : middlewares;
85
+ }
86
+ function getStandardMetadata(metadata, propertyKey) {
87
+ const record = metadata && metadata[metadataKey];
88
+ return record ? record[propertyKey] : void 0;
89
+ }
90
+ function isStandardMethodContext(value) {
91
+ return Boolean(value && typeof value === "object" && value.kind === "method" && typeof value.name !== "undefined");
92
+ }
93
+ function isStandardClassContext(value) {
94
+ return Boolean(value && typeof value === "object" && value.kind === "class" && typeof value.name !== "undefined");
95
+ }
96
+
97
+ //#endregion
98
+ export { getControllerMiddlewares, middleware };
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_bindings = require('../core/bindings.cjs');
3
+ const require_middleware = require('./middleware.cjs');
3
4
  const require_CoreRouter = require('../core/CoreRouter.cjs');
4
5
  require('./index.cjs');
5
6
  require("reflect-metadata");
@@ -12,4 +13,8 @@ require_CoreRouter.CoreRouter.configureDefaults({ container: {
12
13
 
13
14
  //#endregion
14
15
  exports.Bind = require_bindings.Bind;
15
- exports.Container = require_bindings.Container;
16
+ exports.Container = require_bindings.Container;
17
+ exports.ContainerResolutionError = require_bindings.ContainerResolutionError;
18
+ exports.InjectionToken = require_bindings.InjectionToken;
19
+ exports.getControllerMiddlewares = require_middleware.getControllerMiddlewares;
20
+ exports.middleware = require_middleware.middleware;
@@ -1,2 +1,3 @@
1
- import { Bind, BindDecorator, BindFactory, BindToken, BindValue, Container } from "../core/bindings.cjs";
2
- export { Bind, BindDecorator, BindFactory, BindToken, BindValue, Container };
1
+ import { Bind, BindClass, BindDecorator, BindFactory, BindProvider, BindToken, BindValue, BindingOptions, BindingScope, ClassProvider, Container, ContainerResolutionError, ExistingProvider, FactoryProvider, InjectionToken, ValueProvider } from "../core/bindings.cjs";
2
+ import { MiddlewareDecorator, MiddlewareInput, getControllerMiddlewares, middleware } from "./middleware.cjs";
3
+ export { Bind, BindClass, BindDecorator, BindFactory, BindProvider, BindToken, BindValue, BindingOptions, BindingScope, ClassProvider, Container, ContainerResolutionError, ExistingProvider, FactoryProvider, InjectionToken, MiddlewareDecorator, MiddlewareInput, ValueProvider, getControllerMiddlewares, middleware };
@@ -1,2 +1,3 @@
1
- import { Bind, BindDecorator, BindFactory, BindToken, BindValue, Container } from "../core/bindings.mjs";
2
- export { Bind, BindDecorator, BindFactory, BindToken, BindValue, Container };
1
+ import { Bind, BindClass, BindDecorator, BindFactory, BindProvider, BindToken, BindValue, BindingOptions, BindingScope, ClassProvider, Container, ContainerResolutionError, ExistingProvider, FactoryProvider, InjectionToken, ValueProvider } from "../core/bindings.mjs";
2
+ import { MiddlewareDecorator, MiddlewareInput, getControllerMiddlewares, middleware } from "./middleware.mjs";
3
+ export { Bind, BindClass, BindDecorator, BindFactory, BindProvider, BindToken, BindValue, BindingOptions, BindingScope, ClassProvider, Container, ContainerResolutionError, ExistingProvider, FactoryProvider, InjectionToken, MiddlewareDecorator, MiddlewareInput, ValueProvider, getControllerMiddlewares, middleware };
@@ -1,4 +1,5 @@
1
- import { Bind, Container } from "../core/bindings.mjs";
1
+ import { Bind, Container, ContainerResolutionError, InjectionToken } from "../core/bindings.mjs";
2
+ import { getControllerMiddlewares, middleware } from "./middleware.mjs";
2
3
  import { CoreRouter } from "../core/CoreRouter.mjs";
3
4
  import "./index.mjs";
4
5
  import "reflect-metadata";
@@ -10,4 +11,4 @@ CoreRouter.configureDefaults({ container: {
10
11
  } });
11
12
 
12
13
  //#endregion
13
- export { Bind, Container };
14
+ export { Bind, Container, ContainerResolutionError, InjectionToken, getControllerMiddlewares, middleware };
package/dist/index.cjs CHANGED
@@ -7,19 +7,35 @@ const require_RouteGroup = require('./RouteGroup.cjs');
7
7
  const require_RouteRegistrar = require('./RouteRegistrar.cjs');
8
8
  const require_Request = require('./core/Request.cjs');
9
9
  const require_Response = require('./core/Response.cjs');
10
+ const require_bindings = require('./core/bindings.cjs');
10
11
  const require_plugins = require('./core/plugins.cjs');
12
+ const require_middleware = require('./decorators/middleware.cjs');
11
13
  const require_CoreRouter = require('./core/CoreRouter.cjs');
12
14
  require('./core/index.cjs');
13
15
 
16
+ exports.Bind = require_bindings.Bind;
14
17
  exports.ClearRequest = require_ClearRequest.ClearRequest;
18
+ exports.Container = require_bindings.Container;
19
+ exports.ContainerResolutionError = require_bindings.ContainerResolutionError;
15
20
  exports.Controller = require_Controller.Controller;
16
21
  exports.CoreRouter = require_CoreRouter.CoreRouter;
22
+ exports.InjectionToken = require_bindings.InjectionToken;
17
23
  exports.Request = require_Request.Request;
18
24
  exports.Response = require_Response.Response;
19
25
  exports.Route = require_Route.Route;
20
26
  exports.RouteGroup = require_RouteGroup.RouteGroup;
21
27
  exports.RouteRegistrar = require_RouteRegistrar.RouteRegistrar;
22
28
  exports.definePlugin = require_plugins.definePlugin;
29
+ exports.getBindingMetadata = require_bindings.getBindingMetadata;
30
+ exports.getBindingMetadataFromTargets = require_bindings.getBindingMetadataFromTargets;
31
+ exports.getControllerMiddlewares = require_middleware.getControllerMiddlewares;
32
+ exports.getDesignParamTypes = require_bindings.getDesignParamTypes;
33
+ exports.getMetadataKey = require_bindings.getMetadataKey;
34
+ exports.getStandardMetadata = require_bindings.getStandardMetadata;
23
35
  exports.importFile = require_helpers.importFile;
36
+ exports.isClass = require_bindings.isClass;
37
+ exports.middleware = require_middleware.middleware;
24
38
  exports.parseDomainParameters = require_Route.parseDomainParameters;
39
+ exports.setBindingMetadata = require_bindings.setBindingMetadata;
40
+ exports.setStandardMetadata = require_bindings.setStandardMetadata;
25
41
  exports.wrap = require_helpers.wrap;
package/dist/index.d.cts CHANGED
@@ -3,10 +3,12 @@ import { Response } from "./core/Response.cjs";
3
3
  import { ClearRequest } from "./ClearRequest.cjs";
4
4
  import { Route, parseDomainParameters } from "./Route.cjs";
5
5
  import { Request } from "./core/Request.cjs";
6
+ import { Bind, BindClass, BindDecorator, BindFactory, BindProvider, BindToken, BindValue, BindingOptions, BindingScope, ClassProvider, Container, ContainerResolutionError, ExistingProvider, FactoryProvider, InjectionToken, ValueProvider, getBindingMetadata, getBindingMetadataFromTargets, getDesignParamTypes, getMetadataKey, getStandardMetadata, isClass, setBindingMetadata, setStandardMetadata } from "./core/bindings.cjs";
6
7
  import { ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, definePlugin } from "./core/plugins.cjs";
8
+ import { MiddlewareDecorator, MiddlewareInput, getControllerMiddlewares, middleware } from "./decorators/middleware.cjs";
7
9
  import { Controller } from "./Controller.cjs";
8
10
  import { RouteGroup } from "./RouteGroup.cjs";
9
11
  import { RouteRegistrar, RouteRegistrarGroupFactory } from "./RouteRegistrar.cjs";
10
12
  import { CoreRouter } from "./core/CoreRouter.cjs";
11
13
  import { importFile, wrap } from "./core/helpers.cjs";
12
- export { ClearHttpContext, ClearRequest, ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, Controller, CoreRouter, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, Request, Response, Route, RouteGroup, RouteParameter, RouteRegistrar, RouteRegistrarGroupFactory, definePlugin, importFile, parseDomainParameters, wrap };
14
+ export { Bind, BindClass, BindDecorator, BindFactory, BindProvider, BindToken, BindValue, BindingOptions, BindingScope, ClassProvider, ClearHttpContext, ClearRequest, ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, Container, ContainerResolutionError, Controller, CoreRouter, ExistingProvider, FactoryProvider, InjectionToken, MiddlewareDecorator, MiddlewareInput, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, Request, Response, Route, RouteGroup, RouteParameter, RouteRegistrar, RouteRegistrarGroupFactory, ValueProvider, definePlugin, getBindingMetadata, getBindingMetadataFromTargets, getControllerMiddlewares, getDesignParamTypes, getMetadataKey, getStandardMetadata, importFile, isClass, middleware, parseDomainParameters, setBindingMetadata, setStandardMetadata, wrap };
package/dist/index.d.mts CHANGED
@@ -3,10 +3,12 @@ import { Response } from "./core/Response.mjs";
3
3
  import { ClearRequest } from "./ClearRequest.mjs";
4
4
  import { Route, parseDomainParameters } from "./Route.mjs";
5
5
  import { Request } from "./core/Request.mjs";
6
+ import { Bind, BindClass, BindDecorator, BindFactory, BindProvider, BindToken, BindValue, BindingOptions, BindingScope, ClassProvider, Container, ContainerResolutionError, ExistingProvider, FactoryProvider, InjectionToken, ValueProvider, getBindingMetadata, getBindingMetadataFromTargets, getDesignParamTypes, getMetadataKey, getStandardMetadata, isClass, setBindingMetadata, setStandardMetadata } from "./core/bindings.mjs";
6
7
  import { ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, definePlugin } from "./core/plugins.mjs";
8
+ import { MiddlewareDecorator, MiddlewareInput, getControllerMiddlewares, middleware } from "./decorators/middleware.mjs";
7
9
  import { Controller } from "./Controller.mjs";
8
10
  import { RouteGroup } from "./RouteGroup.mjs";
9
11
  import { RouteRegistrar, RouteRegistrarGroupFactory } from "./RouteRegistrar.mjs";
10
12
  import { CoreRouter } from "./core/CoreRouter.mjs";
11
13
  import { importFile, wrap } from "./core/helpers.mjs";
12
- export { ClearHttpContext, ClearRequest, ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, Controller, CoreRouter, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, Request, Response, Route, RouteGroup, RouteParameter, RouteRegistrar, RouteRegistrarGroupFactory, definePlugin, importFile, parseDomainParameters, wrap };
14
+ export { Bind, BindClass, BindDecorator, BindFactory, BindProvider, BindToken, BindValue, BindingOptions, BindingScope, ClassProvider, ClearHttpContext, ClearRequest, ClearRouterPlugin, ClearRouterPluginArgumentsContext, ClearRouterPluginContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, Container, ContainerResolutionError, Controller, CoreRouter, ExistingProvider, FactoryProvider, InjectionToken, MiddlewareDecorator, MiddlewareInput, PluginArgumentsResolver, PluginBind, PluginBindFactory, PluginBindValue, PluginSetupResult, Request, Response, Route, RouteGroup, RouteParameter, RouteRegistrar, RouteRegistrarGroupFactory, ValueProvider, definePlugin, getBindingMetadata, getBindingMetadataFromTargets, getControllerMiddlewares, getDesignParamTypes, getMetadataKey, getStandardMetadata, importFile, isClass, middleware, parseDomainParameters, setBindingMetadata, setStandardMetadata, wrap };
package/dist/index.mjs CHANGED
@@ -6,8 +6,10 @@ import { RouteGroup } from "./RouteGroup.mjs";
6
6
  import { RouteRegistrar } from "./RouteRegistrar.mjs";
7
7
  import { Request } from "./core/Request.mjs";
8
8
  import { Response } from "./core/Response.mjs";
9
+ import { Bind, Container, ContainerResolutionError, InjectionToken, getBindingMetadata, getBindingMetadataFromTargets, getDesignParamTypes, getMetadataKey, getStandardMetadata, isClass, setBindingMetadata, setStandardMetadata } from "./core/bindings.mjs";
9
10
  import { definePlugin } from "./core/plugins.mjs";
11
+ import { getControllerMiddlewares, middleware } from "./decorators/middleware.mjs";
10
12
  import { CoreRouter } from "./core/CoreRouter.mjs";
11
13
  import "./core/index.mjs";
12
14
 
13
- export { ClearRequest, Controller, CoreRouter, Request, Response, Route, RouteGroup, RouteRegistrar, definePlugin, importFile, parseDomainParameters, wrap };
15
+ export { Bind, ClearRequest, Container, ContainerResolutionError, Controller, CoreRouter, InjectionToken, Request, Response, Route, RouteGroup, RouteRegistrar, definePlugin, getBindingMetadata, getBindingMetadataFromTargets, getControllerMiddlewares, getDesignParamTypes, getMetadataKey, getStandardMetadata, importFile, isClass, middleware, parseDomainParameters, setBindingMetadata, setStandardMetadata, wrap };
@@ -56,6 +56,11 @@ interface RouterConfig {
56
56
  container?: {
57
57
  /** Whether decorated handler parameter binding is enabled */enabled?: boolean; /** Whether unknown constructor tokens should be instantiated automatically */
58
58
  autoDiscover?: boolean;
59
+ /**
60
+ * Whether unresolved decorated arguments should throw instead of using
61
+ * the default handler signature
62
+ */
63
+ strict?: boolean;
59
64
  };
60
65
  }
61
66
  type ResourceRouteDefinition = {
@@ -56,6 +56,11 @@ interface RouterConfig {
56
56
  container?: {
57
57
  /** Whether decorated handler parameter binding is enabled */enabled?: boolean; /** Whether unknown constructor tokens should be instantiated automatically */
58
58
  autoDiscover?: boolean;
59
+ /**
60
+ * Whether unresolved decorated arguments should throw instead of using
61
+ * the default handler signature
62
+ */
63
+ strict?: boolean;
59
64
  };
60
65
  }
61
66
  type ResourceRouteDefinition = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clear-router",
3
- "version": "2.9.0",
3
+ "version": "2.9.2",
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",