@keq-request/nestjs 5.0.0-beta.11 → 5.0.0-beta.12

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.
@@ -1,10 +1,10 @@
1
1
 
2
- > @keq-request/nestjs@5.0.0-beta.11 build /home/runner/work/keq/keq/packages/nestjs
2
+ > @keq-request/nestjs@5.0.0-beta.12 build /home/runner/work/keq/keq/packages/nestjs
3
3
  > tsdown
4
4
 
5
5
  ℹ tsdown v0.21.10 powered by rolldown v1.0.0-rc.17
6
6
  ℹ config file: /home/runner/work/keq/keq/packages/nestjs/tsdown.config.ts
7
- (node:2746) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///home/runner/work/keq/keq/packages/nestjs/tsdown.config.ts?no-cache=0efd33bf-1c41-465a-8588-1641d5aab98c is not specified and it doesn't parse as CommonJS.
7
+ (node:2656) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///home/runner/work/keq/keq/packages/nestjs/tsdown.config.ts?no-cache=9597eb0e-a7b3-4070-b281-a70050e6a072 is not specified and it doesn't parse as CommonJS.
8
8
  Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
9
9
  To eliminate this warning, add "type": "module" to /home/runner/work/keq/keq/packages/nestjs/package.json.
10
10
  (Use `node --trace-warnings ...` to show where the warning was created)
@@ -12,25 +12,25 @@ To eliminate this warning, add "type": "module" to /home/runner/work/keq/keq/pac
12
12
  ℹ target: node20
13
13
  ℹ tsconfig: tsconfig.lib.json
14
14
  ℹ Build start
15
- ℹ [CJS] dist/index.js 5.83 kB │ gzip: 2.01 kB
16
- ℹ [CJS] dist/index.js.map 7.28 kB │ gzip: 2.38 kB
17
- ℹ [CJS] 2 files, total: 13.11 kB
15
+ ℹ [CJS] dist/index.js 6.68 kB │ gzip: 2.21 kB
16
+ ℹ [CJS] dist/index.js.map 9.02 kB │ gzip: 2.82 kB
17
+ ℹ [CJS] 2 files, total: 15.70 kB
18
18
  [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugin `tsdown:deps`. See https://rolldown.rs/options/checks#plugintimings for more details.
19
19
 
20
- ℹ [CJS] dist/index.d.ts.map 0.99 kB │ gzip: 0.43 kB
21
- ℹ [CJS] dist/index.d.ts 1.86 kB │ gzip: 0.65 kB
22
- ℹ [CJS] 2 files, total: 2.85 kB
20
+ ℹ [CJS] dist/index.d.ts.map 1.03 kB │ gzip: 0.44 kB
21
+ ℹ [CJS] dist/index.d.ts 1.92 kB │ gzip: 0.67 kB
23
22
  [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
24
- - rolldown-plugin-dts:generate (48%)
25
- - tsdown:deps (46%)
23
+ - rolldown-plugin-dts:generate (63%)
24
+ ℹ [CJS] 2 files, total: 2.96 kB
25
+ ✔ Build complete in 5744ms
26
+ - tsdown:deps (31%)
26
27
  See https://rolldown.rs/options/checks#plugintimings for more details.
27
28
 
28
- ✔ Build complete in 5198ms
29
+ ℹ [ESM] dist/index.mjs 5.39 kB │ gzip: 1.77 kB
30
+ ℹ [ESM] dist/index.mjs.map 8.95 kB │ gzip: 2.79 kB
31
+ ℹ [ESM] dist/index.d.mts.map 1.03 kB │ gzip: 0.45 kB
32
+ ℹ [ESM] dist/index.d.mts 1.93 kB │ gzip: 0.67 kB
33
+ ℹ [ESM] 4 files, total: 17.30 kB
29
34
  [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugin `rolldown-plugin-dts:generate`. See https://rolldown.rs/options/checks#plugintimings for more details.
30
- ℹ [ESM] dist/index.mjs 4.54 kB │ gzip: 1.57 kB
31
35
 
32
- ℹ [ESM] dist/index.mjs.map 7.21 kB │ gzip: 2.36 kB
33
- ℹ [ESM] dist/index.d.mts.map 0.99 kB │ gzip: 0.43 kB
34
- ℹ [ESM] dist/index.d.mts 1.86 kB │ gzip: 0.66 kB
35
- ℹ [ESM] 4 files, total: 14.60 kB
36
- ✔ Build complete in 5201ms
36
+ ✔ Build complete in 5755ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @keq-request/nestjs
2
2
 
3
+ ## 5.0.0-beta.12
4
+
5
+ ### Minor Changes
6
+
7
+ - fbc851f: **Feat:** Add `exclude()` method to `KeqMiddlewareConfigProxy`, allowing middleware to skip specific routes. Supports `KeqRouteInfo` with `host`, `method`, and `pathname` patterns, following the NestJS `MiddlewareConfigProxy.exclude()` convention.
8
+
9
+ ### Patch Changes
10
+
11
+ - keq@5.0.0-beta.12
12
+
3
13
  ## 5.0.0-beta.11
4
14
 
5
15
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -31,6 +31,7 @@ interface KeqModuleClass {
31
31
  readonly KEQ_REQUEST: symbol;
32
32
  }
33
33
  interface KeqMiddlewareConfigProxy {
34
+ exclude(...routes: KeqRouteInfo[]): KeqMiddlewareConfigProxy;
34
35
  forRoutes(...routes: Array<typeof KEQ_ROUTES.ALL | KeqRouteInfo | KeqModuleClass>): KeqMiddlewareConsumer;
35
36
  }
36
37
  interface KeqMiddlewareConsumer {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/keq.module.ts","../src/constants.ts","../src/interfaces/keq-nest-middleware.interface.ts","../src/interfaces/keq-middleware-consumer.interface.ts","../src/interfaces/keq-middleware-module.interface.ts","../src/interfaces/keq-module-options.interface.ts"],"mappings":";;;;;cAYa,SAAA,YAAqB,YAAA;EAAA,iBAEb,gBAAA;EAAA,iBACA,SAAA;EAAA,iBACA,UAAA;cAFA,gBAAA,EAAkB,gBAAA,EAClB,SAAA,EAAW,SAAA,EACX,UAAA,EAAY,UAAA;EAG/B,YAAA,CAAA;AAAA;;;cCnBW,UAAA;EAAA,SAEH,GAAA;AAAA;;;UCCO,iBAAA;EACf,GAAA,CAAI,GAAA,EAAK,mBAAA,EAAqB,IAAA,EAAM,OAAA,UAAiB,WAAA;AAAA;;;UCEtC,YAAA;EACf,IAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,UAGe,cAAA;EAAA,SACN,WAAA;AAAA;AAAA,UAGM,wBAAA;EACf,SAAA,IAAa,MAAA,EAAQ,KAAA,QAAa,UAAA,CAAW,GAAA,GAAM,YAAA,GAAe,cAAA,IAAkB,qBAAA;AAAA;AAAA,UAGrE,qBAAA;EACf,KAAA,IAAS,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,iBAAA,IAAqB,aAAA,IAAiB,wBAAA;AAAA;;;UClBxD,mBAAA;EACf,sBAAA,CAAuB,QAAA,EAAU,qBAAA;AAAA;;;UCDlB,gBAAA;EACf,WAAA,GAAc,aAAA;EACd,OAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/keq.module.ts","../src/constants.ts","../src/interfaces/keq-nest-middleware.interface.ts","../src/interfaces/keq-middleware-consumer.interface.ts","../src/interfaces/keq-middleware-module.interface.ts","../src/interfaces/keq-module-options.interface.ts"],"mappings":";;;;;cAYa,SAAA,YAAqB,YAAA;EAAA,iBAEb,gBAAA;EAAA,iBACA,SAAA;EAAA,iBACA,UAAA;cAFA,gBAAA,EAAkB,gBAAA,EAClB,SAAA,EAAW,SAAA,EACX,UAAA,EAAY,UAAA;EAG/B,YAAA,CAAA;AAAA;;;cCnBW,UAAA;EAAA,SAEH,GAAA;AAAA;;;UCCO,iBAAA;EACf,GAAA,CAAI,GAAA,EAAK,mBAAA,EAAqB,IAAA,EAAM,OAAA,UAAiB,WAAA;AAAA;;;UCEtC,YAAA;EACf,IAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,UAGe,cAAA;EAAA,SACN,WAAA;AAAA;AAAA,UAGM,wBAAA;EACf,OAAA,IAAW,MAAA,EAAQ,YAAA,KAAiB,wBAAA;EACpC,SAAA,IAAa,MAAA,EAAQ,KAAA,QAAa,UAAA,CAAW,GAAA,GAAM,YAAA,GAAe,cAAA,IAAkB,qBAAA;AAAA;AAAA,UAGrE,qBAAA;EACf,KAAA,IAAS,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,iBAAA,IAAqB,aAAA,IAAiB,wBAAA;AAAA;;;UCnBxD,mBAAA;EACf,sBAAA,CAAuB,QAAA,EAAU,qBAAA;AAAA;;;UCDlB,gBAAA;EACf,WAAA,GAAc,aAAA;EACd,OAAA;AAAA"}
package/dist/index.d.ts CHANGED
@@ -31,6 +31,7 @@ interface KeqModuleClass {
31
31
  readonly KEQ_REQUEST: symbol;
32
32
  }
33
33
  interface KeqMiddlewareConfigProxy {
34
+ exclude(...routes: KeqRouteInfo[]): KeqMiddlewareConfigProxy;
34
35
  forRoutes(...routes: Array<typeof KEQ_ROUTES.ALL | KeqRouteInfo | KeqModuleClass>): KeqMiddlewareConsumer;
35
36
  }
36
37
  interface KeqMiddlewareConsumer {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/keq.module.ts","../src/constants.ts","../src/interfaces/keq-nest-middleware.interface.ts","../src/interfaces/keq-middleware-consumer.interface.ts","../src/interfaces/keq-middleware-module.interface.ts","../src/interfaces/keq-module-options.interface.ts"],"mappings":";;;;;cAYa,SAAA,YAAqB,YAAA;EAAA,iBAEb,gBAAA;EAAA,iBACA,SAAA;EAAA,iBACA,UAAA;cAFA,gBAAA,EAAkB,gBAAA,EAClB,SAAA,EAAW,SAAA,EACX,UAAA,EAAY,UAAA;EAG/B,YAAA,CAAA;AAAA;;;cCnBW,UAAA;EAAA,SAEH,GAAA;AAAA;;;UCCO,iBAAA;EACf,GAAA,CAAI,GAAA,EAAK,mBAAA,EAAqB,IAAA,EAAM,OAAA,UAAiB,WAAA;AAAA;;;UCEtC,YAAA;EACf,IAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,UAGe,cAAA;EAAA,SACN,WAAA;AAAA;AAAA,UAGM,wBAAA;EACf,SAAA,IAAa,MAAA,EAAQ,KAAA,QAAa,UAAA,CAAW,GAAA,GAAM,YAAA,GAAe,cAAA,IAAkB,qBAAA;AAAA;AAAA,UAGrE,qBAAA;EACf,KAAA,IAAS,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,iBAAA,IAAqB,aAAA,IAAiB,wBAAA;AAAA;;;UClBxD,mBAAA;EACf,sBAAA,CAAuB,QAAA,EAAU,qBAAA;AAAA;;;UCDlB,gBAAA;EACf,WAAA,GAAc,aAAA;EACd,OAAA;AAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/keq.module.ts","../src/constants.ts","../src/interfaces/keq-nest-middleware.interface.ts","../src/interfaces/keq-middleware-consumer.interface.ts","../src/interfaces/keq-middleware-module.interface.ts","../src/interfaces/keq-module-options.interface.ts"],"mappings":";;;;;cAYa,SAAA,YAAqB,YAAA;EAAA,iBAEb,gBAAA;EAAA,iBACA,SAAA;EAAA,iBACA,UAAA;cAFA,gBAAA,EAAkB,gBAAA,EAClB,SAAA,EAAW,SAAA,EACX,UAAA,EAAY,UAAA;EAG/B,YAAA,CAAA;AAAA;;;cCnBW,UAAA;EAAA,SAEH,GAAA;AAAA;;;UCCO,iBAAA;EACf,GAAA,CAAI,GAAA,EAAK,mBAAA,EAAqB,IAAA,EAAM,OAAA,UAAiB,WAAA;AAAA;;;UCEtC,YAAA;EACf,IAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,UAGe,cAAA;EAAA,SACN,WAAA;AAAA;AAAA,UAGM,wBAAA;EACf,OAAA,IAAW,MAAA,EAAQ,YAAA,KAAiB,wBAAA;EACpC,SAAA,IAAa,MAAA,EAAQ,KAAA,QAAa,UAAA,CAAW,GAAA,GAAM,YAAA,GAAe,cAAA,IAAkB,qBAAA;AAAA;AAAA,UAGrE,qBAAA;EACf,KAAA,IAAS,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,iBAAA,IAAqB,aAAA,IAAiB,wBAAA;AAAA;;;UCnBxD,mBAAA;EACf,sBAAA,CAAuB,QAAA,EAAU,qBAAA;AAAA;;;UCDlB,gBAAA;EACf,WAAA,GAAc,aAAA;EACd,OAAA;AAAA"}
package/dist/index.js CHANGED
@@ -37,15 +37,28 @@ var KeqMiddlewareConsumerImpl = class {
37
37
  middlewares,
38
38
  routes: []
39
39
  };
40
+ const excludedRouteInfos = [];
40
41
  this.entries.push(entry);
41
- return { forRoutes: (...routes) => {
42
- entry.routes = routes;
43
- return this;
44
- } };
42
+ const proxy = {
43
+ exclude: (...routes) => {
44
+ excludedRouteInfos.push(...routes);
45
+ return proxy;
46
+ },
47
+ forRoutes: (...routes) => {
48
+ entry.routes = routes;
49
+ if (excludedRouteInfos.length > 0) entry.excludedRouteInfos = excludedRouteInfos;
50
+ return this;
51
+ }
52
+ };
53
+ return proxy;
45
54
  }
46
55
  applyTo(keqRequest, moduleRef) {
47
56
  for (const entry of this.entries) {
48
- const resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef));
57
+ let resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef));
58
+ if (entry.excludedRouteInfos && entry.excludedRouteInfos.length > 0) {
59
+ const excludedRoutes = entry.excludedRouteInfos.map((info) => this.buildRoute(info));
60
+ resolved = resolved.map((mw) => this.wrapWithExclusion(mw, excludedRoutes));
61
+ }
49
62
  if (entry.routes.length === 0 || entry.routes.some((r) => r === KEQ_ROUTES.ALL)) for (const mw of resolved) keqRequest.use(mw);
50
63
  else for (const routeTarget of entry.routes) {
51
64
  if (routeTarget === KEQ_ROUTES.ALL) continue;
@@ -91,6 +104,17 @@ var KeqMiddlewareConsumerImpl = class {
91
104
  if (routes.length === 1) return routes[0];
92
105
  return (0, keq.composeRoute)(routes);
93
106
  }
107
+ wrapWithExclusion(middleware, excludedRoutes) {
108
+ const excluded = async (ctx, next) => {
109
+ if (await this.checkExcluded(ctx, excludedRoutes)) return next();
110
+ return middleware(ctx, next);
111
+ };
112
+ return excluded;
113
+ }
114
+ async checkExcluded(ctx, excludedRoutes) {
115
+ for (const route of excludedRoutes) if (await route(ctx)) return true;
116
+ return false;
117
+ }
94
118
  };
95
119
  //#endregion
96
120
  //#region src/utils/has-configure-keq-middleware.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["KeqRequest"],"sources":["../src/constants.ts","../src/keq-middleware-consumer.ts","../src/utils/has-configure-keq-middleware.ts","../src/keq.module.ts"],"sourcesContent":["export const KEQ_ROUTES = {\n ALL: Symbol('KEQ_ROUTES.ALL'),\n} as const\n","import type { Type } from '@nestjs/common'\nimport type { ModuleRef } from '@nestjs/core'\nimport type { KeqMiddleware, KeqRoute } from 'keq'\nimport { composeRoute, KeqRequest } from 'keq'\nimport picomatch from 'picomatch'\nimport { KEQ_ROUTES } from './constants.js'\nimport type { KeqMiddlewareConfigProxy, KeqMiddlewareConsumer, KeqModuleClass, KeqRouteInfo } from './interfaces/keq-middleware-consumer.interface.js'\nimport type { KeqNestMiddleware } from './interfaces/keq-nest-middleware.interface.js'\n\n\ninterface MiddlewareEntry {\n middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>\n routes: Array<typeof KEQ_ROUTES.ALL | KeqRouteInfo | KeqModuleClass>\n}\n\nexport class KeqMiddlewareConsumerImpl implements KeqMiddlewareConsumer {\n private entries: MiddlewareEntry[] = []\n\n apply(...middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>): KeqMiddlewareConfigProxy {\n const entry: MiddlewareEntry = { middlewares, routes: [] }\n this.entries.push(entry)\n return {\n forRoutes: (...routes) => {\n entry.routes = routes\n return this\n },\n }\n }\n\n applyTo(keqRequest: KeqRequest, moduleRef: ModuleRef): void {\n for (const entry of this.entries) {\n const resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef))\n const isGlobal = entry.routes.length === 0\n || entry.routes.some((r) => r === KEQ_ROUTES.ALL)\n\n if (isGlobal) {\n for (const mw of resolved) keqRequest.use(mw)\n } else {\n for (const routeTarget of entry.routes) {\n if (routeTarget === KEQ_ROUTES.ALL) continue\n\n if (this.isKeqModuleClass(routeTarget)) {\n const targetRequest = moduleRef.get<KeqRequest>(routeTarget.KEQ_REQUEST, { strict: false })\n if (targetRequest) {\n for (const mw of resolved) targetRequest.use(mw)\n }\n } else {\n const route = this.buildRoute(routeTarget as KeqRouteInfo)\n keqRequest.useRouter().route(route, resolved)\n }\n }\n }\n }\n }\n\n private isKeqModuleClass(route: unknown): route is KeqModuleClass {\n return (\n typeof route === 'function'\n && 'KEQ_REQUEST' in route\n && typeof (route as Record<string, unknown>).KEQ_REQUEST === 'symbol'\n )\n }\n\n private isNestMiddlewareClass(m: Type<KeqNestMiddleware> | KeqMiddleware): m is Type<KeqNestMiddleware> {\n return typeof m === 'function' && m.prototype !== undefined && 'use' in m.prototype\n }\n\n private resolveMiddleware(m: Type<KeqNestMiddleware> | KeqMiddleware, moduleRef: ModuleRef): KeqMiddleware {\n if (this.isNestMiddlewareClass(m)) {\n const instance = moduleRef.get<KeqNestMiddleware>(m, { strict: false })\n return async (ctx, next) => {\n await instance.use(ctx, next)\n }\n }\n return m\n }\n\n private buildRoute(info: KeqRouteInfo): KeqRoute {\n const routes: KeqRoute[] = []\n if (info.host) {\n const host = info.host\n routes.push((ctx) => ctx.request.url.host === host)\n }\n if (info.method) {\n const method = info.method.toLowerCase()\n routes.push((ctx) => ctx.request.method.toLowerCase() === method)\n }\n if (info.pathname) {\n const isMatch: (test: string) => boolean = picomatch(info.pathname)\n routes.push((ctx) => isMatch(ctx.request.url.pathname))\n }\n if (routes.length === 1) return routes[0]\n return composeRoute(routes)\n }\n}\n","import type { KeqMiddlewareModule } from '../interfaces/keq-middleware-module.interface.js'\n\n\nexport function hasConfigureKeqMiddleware(instance: unknown): instance is KeqMiddlewareModule {\n return (\n instance !== null\n && instance !== undefined\n && typeof (instance as Record<string, unknown>).configureKeqMiddleware === 'function'\n )\n}\n","import { Global, Module, OnModuleInit } from '@nestjs/common'\nimport { ModulesContainer, ModuleRef } from '@nestjs/core'\nimport { KeqRequest } from 'keq'\nimport { KeqMiddlewareConsumerImpl } from './keq-middleware-consumer.js'\nimport { hasConfigureKeqMiddleware } from './utils/has-configure-keq-middleware.js'\n\n\n@Global()\n@Module({\n providers: [{ provide: KeqRequest, useFactory: () => new KeqRequest() }],\n exports: [KeqRequest],\n})\nexport class KeqModule implements OnModuleInit {\n constructor(\n private readonly modulesContainer: ModulesContainer,\n private readonly moduleRef: ModuleRef,\n private readonly keqRequest: KeqRequest,\n ) {}\n\n onModuleInit(): void {\n for (const [, moduleWrapper] of this.modulesContainer) {\n const instance = moduleWrapper.instance\n if (hasConfigureKeqMiddleware(instance)) {\n const consumer = new KeqMiddlewareConsumerImpl()\n instance.configureKeqMiddleware(consumer)\n consumer.applyTo(this.keqRequest, this.moduleRef)\n }\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["KeqRequest"],"sources":["../src/constants.ts","../src/keq-middleware-consumer.ts","../src/utils/has-configure-keq-middleware.ts","../src/keq.module.ts"],"sourcesContent":["export const KEQ_ROUTES = {\n ALL: Symbol('KEQ_ROUTES.ALL'),\n} as const\n","import type { Type } from '@nestjs/common'\nimport type { ModuleRef } from '@nestjs/core'\nimport type { KeqExecutionContext, KeqMiddleware, KeqRoute } from 'keq'\nimport { composeRoute, KeqRequest } from 'keq'\nimport picomatch from 'picomatch'\nimport { KEQ_ROUTES } from './constants.js'\nimport type { KeqMiddlewareConfigProxy, KeqMiddlewareConsumer, KeqModuleClass, KeqRouteInfo } from './interfaces/keq-middleware-consumer.interface.js'\nimport type { KeqNestMiddleware } from './interfaces/keq-nest-middleware.interface.js'\n\n\ninterface MiddlewareEntry {\n middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>\n routes: Array<typeof KEQ_ROUTES.ALL | KeqRouteInfo | KeqModuleClass>\n excludedRouteInfos?: KeqRouteInfo[]\n}\n\nexport class KeqMiddlewareConsumerImpl implements KeqMiddlewareConsumer {\n private entries: MiddlewareEntry[] = []\n\n apply(...middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>): KeqMiddlewareConfigProxy {\n const entry: MiddlewareEntry = { middlewares, routes: [] }\n const excludedRouteInfos: KeqRouteInfo[] = []\n this.entries.push(entry)\n\n const proxy: KeqMiddlewareConfigProxy = {\n exclude: (...routes) => {\n excludedRouteInfos.push(...routes)\n return proxy\n },\n forRoutes: (...routes) => {\n entry.routes = routes\n if (excludedRouteInfos.length > 0) {\n entry.excludedRouteInfos = excludedRouteInfos\n }\n return this\n },\n }\n return proxy\n }\n\n applyTo(keqRequest: KeqRequest, moduleRef: ModuleRef): void {\n for (const entry of this.entries) {\n let resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef))\n\n if (entry.excludedRouteInfos && entry.excludedRouteInfos.length > 0) {\n const excludedRoutes = entry.excludedRouteInfos.map((info) => this.buildRoute(info))\n resolved = resolved.map((mw) => this.wrapWithExclusion(mw, excludedRoutes))\n }\n\n const isGlobal = entry.routes.length === 0\n || entry.routes.some((r) => r === KEQ_ROUTES.ALL)\n\n if (isGlobal) {\n for (const mw of resolved) keqRequest.use(mw)\n } else {\n for (const routeTarget of entry.routes) {\n if (routeTarget === KEQ_ROUTES.ALL) continue\n\n if (this.isKeqModuleClass(routeTarget)) {\n const targetRequest = moduleRef.get<KeqRequest>(routeTarget.KEQ_REQUEST, { strict: false })\n if (targetRequest) {\n for (const mw of resolved) targetRequest.use(mw)\n }\n } else {\n const route = this.buildRoute(routeTarget as KeqRouteInfo)\n keqRequest.useRouter().route(route, resolved)\n }\n }\n }\n }\n }\n\n private isKeqModuleClass(route: unknown): route is KeqModuleClass {\n return (\n typeof route === 'function'\n && 'KEQ_REQUEST' in route\n && typeof (route as Record<string, unknown>).KEQ_REQUEST === 'symbol'\n )\n }\n\n private isNestMiddlewareClass(m: Type<KeqNestMiddleware> | KeqMiddleware): m is Type<KeqNestMiddleware> {\n return typeof m === 'function' && m.prototype !== undefined && 'use' in m.prototype\n }\n\n private resolveMiddleware(m: Type<KeqNestMiddleware> | KeqMiddleware, moduleRef: ModuleRef): KeqMiddleware {\n if (this.isNestMiddlewareClass(m)) {\n const instance = moduleRef.get<KeqNestMiddleware>(m, { strict: false })\n return async (ctx, next) => {\n await instance.use(ctx, next)\n }\n }\n return m\n }\n\n private buildRoute(info: KeqRouteInfo): KeqRoute {\n const routes: KeqRoute[] = []\n if (info.host) {\n const host = info.host\n routes.push((ctx) => ctx.request.url.host === host)\n }\n if (info.method) {\n const method = info.method.toLowerCase()\n routes.push((ctx) => ctx.request.method.toLowerCase() === method)\n }\n if (info.pathname) {\n const isMatch: (test: string) => boolean = picomatch(info.pathname)\n routes.push((ctx) => isMatch(ctx.request.url.pathname))\n }\n if (routes.length === 1) return routes[0]\n return composeRoute(routes)\n }\n\n private wrapWithExclusion(middleware: KeqMiddleware, excludedRoutes: KeqRoute[]): KeqMiddleware {\n const excluded: KeqMiddleware = async (ctx, next) => {\n if (await this.checkExcluded(ctx, excludedRoutes)) {\n return next()\n }\n return middleware(ctx, next)\n }\n return excluded\n }\n\n private async checkExcluded(ctx: KeqExecutionContext, excludedRoutes: KeqRoute[]): Promise<boolean> {\n for (const route of excludedRoutes) {\n if (await route(ctx)) return true\n }\n return false\n }\n}\n","import type { KeqMiddlewareModule } from '../interfaces/keq-middleware-module.interface.js'\n\n\nexport function hasConfigureKeqMiddleware(instance: unknown): instance is KeqMiddlewareModule {\n return (\n instance !== null\n && instance !== undefined\n && typeof (instance as Record<string, unknown>).configureKeqMiddleware === 'function'\n )\n}\n","import { Global, Module, OnModuleInit } from '@nestjs/common'\nimport { ModulesContainer, ModuleRef } from '@nestjs/core'\nimport { KeqRequest } from 'keq'\nimport { KeqMiddlewareConsumerImpl } from './keq-middleware-consumer.js'\nimport { hasConfigureKeqMiddleware } from './utils/has-configure-keq-middleware.js'\n\n\n@Global()\n@Module({\n providers: [{ provide: KeqRequest, useFactory: () => new KeqRequest() }],\n exports: [KeqRequest],\n})\nexport class KeqModule implements OnModuleInit {\n constructor(\n private readonly modulesContainer: ModulesContainer,\n private readonly moduleRef: ModuleRef,\n private readonly keqRequest: KeqRequest,\n ) {}\n\n onModuleInit(): void {\n for (const [, moduleWrapper] of this.modulesContainer) {\n const instance = moduleWrapper.instance\n if (hasConfigureKeqMiddleware(instance)) {\n const consumer = new KeqMiddlewareConsumerImpl()\n instance.configureKeqMiddleware(consumer)\n consumer.applyTo(this.keqRequest, this.moduleRef)\n }\n }\n }\n}\n"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -13,15 +13,28 @@ var KeqMiddlewareConsumerImpl = class {
13
13
  middlewares,
14
14
  routes: []
15
15
  };
16
+ const excludedRouteInfos = [];
16
17
  this.entries.push(entry);
17
- return { forRoutes: (...routes) => {
18
- entry.routes = routes;
19
- return this;
20
- } };
18
+ const proxy = {
19
+ exclude: (...routes) => {
20
+ excludedRouteInfos.push(...routes);
21
+ return proxy;
22
+ },
23
+ forRoutes: (...routes) => {
24
+ entry.routes = routes;
25
+ if (excludedRouteInfos.length > 0) entry.excludedRouteInfos = excludedRouteInfos;
26
+ return this;
27
+ }
28
+ };
29
+ return proxy;
21
30
  }
22
31
  applyTo(keqRequest, moduleRef) {
23
32
  for (const entry of this.entries) {
24
- const resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef));
33
+ let resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef));
34
+ if (entry.excludedRouteInfos && entry.excludedRouteInfos.length > 0) {
35
+ const excludedRoutes = entry.excludedRouteInfos.map((info) => this.buildRoute(info));
36
+ resolved = resolved.map((mw) => this.wrapWithExclusion(mw, excludedRoutes));
37
+ }
25
38
  if (entry.routes.length === 0 || entry.routes.some((r) => r === KEQ_ROUTES.ALL)) for (const mw of resolved) keqRequest.use(mw);
26
39
  else for (const routeTarget of entry.routes) {
27
40
  if (routeTarget === KEQ_ROUTES.ALL) continue;
@@ -67,6 +80,17 @@ var KeqMiddlewareConsumerImpl = class {
67
80
  if (routes.length === 1) return routes[0];
68
81
  return composeRoute(routes);
69
82
  }
83
+ wrapWithExclusion(middleware, excludedRoutes) {
84
+ const excluded = async (ctx, next) => {
85
+ if (await this.checkExcluded(ctx, excludedRoutes)) return next();
86
+ return middleware(ctx, next);
87
+ };
88
+ return excluded;
89
+ }
90
+ async checkExcluded(ctx, excludedRoutes) {
91
+ for (const route of excludedRoutes) if (await route(ctx)) return true;
92
+ return false;
93
+ }
70
94
  };
71
95
  //#endregion
72
96
  //#region src/utils/has-configure-keq-middleware.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/constants.ts","../src/keq-middleware-consumer.ts","../src/utils/has-configure-keq-middleware.ts","../src/keq.module.ts"],"sourcesContent":["export const KEQ_ROUTES = {\n ALL: Symbol('KEQ_ROUTES.ALL'),\n} as const\n","import type { Type } from '@nestjs/common'\nimport type { ModuleRef } from '@nestjs/core'\nimport type { KeqMiddleware, KeqRoute } from 'keq'\nimport { composeRoute, KeqRequest } from 'keq'\nimport picomatch from 'picomatch'\nimport { KEQ_ROUTES } from './constants.js'\nimport type { KeqMiddlewareConfigProxy, KeqMiddlewareConsumer, KeqModuleClass, KeqRouteInfo } from './interfaces/keq-middleware-consumer.interface.js'\nimport type { KeqNestMiddleware } from './interfaces/keq-nest-middleware.interface.js'\n\n\ninterface MiddlewareEntry {\n middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>\n routes: Array<typeof KEQ_ROUTES.ALL | KeqRouteInfo | KeqModuleClass>\n}\n\nexport class KeqMiddlewareConsumerImpl implements KeqMiddlewareConsumer {\n private entries: MiddlewareEntry[] = []\n\n apply(...middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>): KeqMiddlewareConfigProxy {\n const entry: MiddlewareEntry = { middlewares, routes: [] }\n this.entries.push(entry)\n return {\n forRoutes: (...routes) => {\n entry.routes = routes\n return this\n },\n }\n }\n\n applyTo(keqRequest: KeqRequest, moduleRef: ModuleRef): void {\n for (const entry of this.entries) {\n const resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef))\n const isGlobal = entry.routes.length === 0\n || entry.routes.some((r) => r === KEQ_ROUTES.ALL)\n\n if (isGlobal) {\n for (const mw of resolved) keqRequest.use(mw)\n } else {\n for (const routeTarget of entry.routes) {\n if (routeTarget === KEQ_ROUTES.ALL) continue\n\n if (this.isKeqModuleClass(routeTarget)) {\n const targetRequest = moduleRef.get<KeqRequest>(routeTarget.KEQ_REQUEST, { strict: false })\n if (targetRequest) {\n for (const mw of resolved) targetRequest.use(mw)\n }\n } else {\n const route = this.buildRoute(routeTarget as KeqRouteInfo)\n keqRequest.useRouter().route(route, resolved)\n }\n }\n }\n }\n }\n\n private isKeqModuleClass(route: unknown): route is KeqModuleClass {\n return (\n typeof route === 'function'\n && 'KEQ_REQUEST' in route\n && typeof (route as Record<string, unknown>).KEQ_REQUEST === 'symbol'\n )\n }\n\n private isNestMiddlewareClass(m: Type<KeqNestMiddleware> | KeqMiddleware): m is Type<KeqNestMiddleware> {\n return typeof m === 'function' && m.prototype !== undefined && 'use' in m.prototype\n }\n\n private resolveMiddleware(m: Type<KeqNestMiddleware> | KeqMiddleware, moduleRef: ModuleRef): KeqMiddleware {\n if (this.isNestMiddlewareClass(m)) {\n const instance = moduleRef.get<KeqNestMiddleware>(m, { strict: false })\n return async (ctx, next) => {\n await instance.use(ctx, next)\n }\n }\n return m\n }\n\n private buildRoute(info: KeqRouteInfo): KeqRoute {\n const routes: KeqRoute[] = []\n if (info.host) {\n const host = info.host\n routes.push((ctx) => ctx.request.url.host === host)\n }\n if (info.method) {\n const method = info.method.toLowerCase()\n routes.push((ctx) => ctx.request.method.toLowerCase() === method)\n }\n if (info.pathname) {\n const isMatch: (test: string) => boolean = picomatch(info.pathname)\n routes.push((ctx) => isMatch(ctx.request.url.pathname))\n }\n if (routes.length === 1) return routes[0]\n return composeRoute(routes)\n }\n}\n","import type { KeqMiddlewareModule } from '../interfaces/keq-middleware-module.interface.js'\n\n\nexport function hasConfigureKeqMiddleware(instance: unknown): instance is KeqMiddlewareModule {\n return (\n instance !== null\n && instance !== undefined\n && typeof (instance as Record<string, unknown>).configureKeqMiddleware === 'function'\n )\n}\n","import { Global, Module, OnModuleInit } from '@nestjs/common'\nimport { ModulesContainer, ModuleRef } from '@nestjs/core'\nimport { KeqRequest } from 'keq'\nimport { KeqMiddlewareConsumerImpl } from './keq-middleware-consumer.js'\nimport { hasConfigureKeqMiddleware } from './utils/has-configure-keq-middleware.js'\n\n\n@Global()\n@Module({\n providers: [{ provide: KeqRequest, useFactory: () => new KeqRequest() }],\n exports: [KeqRequest],\n})\nexport class KeqModule implements OnModuleInit {\n constructor(\n private readonly modulesContainer: ModulesContainer,\n private readonly moduleRef: ModuleRef,\n private readonly keqRequest: KeqRequest,\n ) {}\n\n onModuleInit(): void {\n for (const [, moduleWrapper] of this.modulesContainer) {\n const instance = moduleWrapper.instance\n if (hasConfigureKeqMiddleware(instance)) {\n const consumer = new KeqMiddlewareConsumerImpl()\n instance.configureKeqMiddleware(consumer)\n consumer.applyTo(this.keqRequest, this.moduleRef)\n }\n }\n }\n}\n"],"mappings":";;;;;AAAA,MAAa,aAAa,EACxB,KAAK,OAAO,iBAAiB,EAC9B;;;ACaD,IAAa,4BAAb,MAAwE;CACtE,UAAqC,EAAE;CAEvC,MAAM,GAAG,aAAuF;EAC9F,MAAM,QAAyB;GAAE;GAAa,QAAQ,EAAE;GAAE;AAC1D,OAAK,QAAQ,KAAK,MAAM;AACxB,SAAO,EACL,YAAY,GAAG,WAAW;AACxB,SAAM,SAAS;AACf,UAAO;KAEV;;CAGH,QAAQ,YAAwB,WAA4B;AAC1D,OAAK,MAAM,SAAS,KAAK,SAAS;GAChC,MAAM,WAAW,MAAM,YAAY,KAAK,MAAM,KAAK,kBAAkB,GAAG,UAAU,CAAC;AAInF,OAHiB,MAAM,OAAO,WAAW,KACpC,MAAM,OAAO,MAAM,MAAM,MAAM,WAAW,IAAI,CAGjD,MAAK,MAAM,MAAM,SAAU,YAAW,IAAI,GAAG;OAE7C,MAAK,MAAM,eAAe,MAAM,QAAQ;AACtC,QAAI,gBAAgB,WAAW,IAAK;AAEpC,QAAI,KAAK,iBAAiB,YAAY,EAAE;KACtC,MAAM,gBAAgB,UAAU,IAAgB,YAAY,aAAa,EAAE,QAAQ,OAAO,CAAC;AAC3F,SAAI,cACF,MAAK,MAAM,MAAM,SAAU,eAAc,IAAI,GAAG;WAE7C;KACL,MAAM,QAAQ,KAAK,WAAW,YAA4B;AAC1D,gBAAW,WAAW,CAAC,MAAM,OAAO,SAAS;;;;;CAOvD,iBAAyB,OAAyC;AAChE,SACE,OAAO,UAAU,cACd,iBAAiB,SACjB,OAAQ,MAAkC,gBAAgB;;CAIjE,sBAA8B,GAA0E;AACtG,SAAO,OAAO,MAAM,cAAc,EAAE,cAAc,KAAA,KAAa,SAAS,EAAE;;CAG5E,kBAA0B,GAA4C,WAAqC;AACzG,MAAI,KAAK,sBAAsB,EAAE,EAAE;GACjC,MAAM,WAAW,UAAU,IAAuB,GAAG,EAAE,QAAQ,OAAO,CAAC;AACvE,UAAO,OAAO,KAAK,SAAS;AAC1B,UAAM,SAAS,IAAI,KAAK,KAAK;;;AAGjC,SAAO;;CAGT,WAAmB,MAA8B;EAC/C,MAAM,SAAqB,EAAE;AAC7B,MAAI,KAAK,MAAM;GACb,MAAM,OAAO,KAAK;AAClB,UAAO,MAAM,QAAQ,IAAI,QAAQ,IAAI,SAAS,KAAK;;AAErD,MAAI,KAAK,QAAQ;GACf,MAAM,SAAS,KAAK,OAAO,aAAa;AACxC,UAAO,MAAM,QAAQ,IAAI,QAAQ,OAAO,aAAa,KAAK,OAAO;;AAEnE,MAAI,KAAK,UAAU;GACjB,MAAM,UAAqC,UAAU,KAAK,SAAS;AACnE,UAAO,MAAM,QAAQ,QAAQ,IAAI,QAAQ,IAAI,SAAS,CAAC;;AAEzD,MAAI,OAAO,WAAW,EAAG,QAAO,OAAO;AACvC,SAAO,aAAa,OAAO;;;;;ACzF/B,SAAgB,0BAA0B,UAAoD;AAC5F,QACE,aAAa,QACV,aAAa,KAAA,KACb,OAAQ,SAAqC,2BAA2B;;;;;;;;;;;;;;;;;;ACKxE,IAAA,YAAA,MAAM,UAAkC;CAC7C,YACE,kBACA,WACA,YACA;AAHiB,OAAA,mBAAA;AACA,OAAA,YAAA;AACA,OAAA,aAAA;;CAGnB,eAAqB;AACnB,OAAK,MAAM,GAAG,kBAAkB,KAAK,kBAAkB;GACrD,MAAM,WAAW,cAAc;AAC/B,OAAI,0BAA0B,SAAS,EAAE;IACvC,MAAM,WAAW,IAAI,2BAA2B;AAChD,aAAS,uBAAuB,SAAS;AACzC,aAAS,QAAQ,KAAK,YAAY,KAAK,UAAU;;;;;;CAlBxD,QAAQ;CACR,OAAO;EACN,WAAW,CAAC;GAAE,SAAS;GAAY,kBAAkB,IAAI,YAAY;GAAE,CAAC;EACxE,SAAS,CAAC,WAAW;EACtB,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/constants.ts","../src/keq-middleware-consumer.ts","../src/utils/has-configure-keq-middleware.ts","../src/keq.module.ts"],"sourcesContent":["export const KEQ_ROUTES = {\n ALL: Symbol('KEQ_ROUTES.ALL'),\n} as const\n","import type { Type } from '@nestjs/common'\nimport type { ModuleRef } from '@nestjs/core'\nimport type { KeqExecutionContext, KeqMiddleware, KeqRoute } from 'keq'\nimport { composeRoute, KeqRequest } from 'keq'\nimport picomatch from 'picomatch'\nimport { KEQ_ROUTES } from './constants.js'\nimport type { KeqMiddlewareConfigProxy, KeqMiddlewareConsumer, KeqModuleClass, KeqRouteInfo } from './interfaces/keq-middleware-consumer.interface.js'\nimport type { KeqNestMiddleware } from './interfaces/keq-nest-middleware.interface.js'\n\n\ninterface MiddlewareEntry {\n middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>\n routes: Array<typeof KEQ_ROUTES.ALL | KeqRouteInfo | KeqModuleClass>\n excludedRouteInfos?: KeqRouteInfo[]\n}\n\nexport class KeqMiddlewareConsumerImpl implements KeqMiddlewareConsumer {\n private entries: MiddlewareEntry[] = []\n\n apply(...middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>): KeqMiddlewareConfigProxy {\n const entry: MiddlewareEntry = { middlewares, routes: [] }\n const excludedRouteInfos: KeqRouteInfo[] = []\n this.entries.push(entry)\n\n const proxy: KeqMiddlewareConfigProxy = {\n exclude: (...routes) => {\n excludedRouteInfos.push(...routes)\n return proxy\n },\n forRoutes: (...routes) => {\n entry.routes = routes\n if (excludedRouteInfos.length > 0) {\n entry.excludedRouteInfos = excludedRouteInfos\n }\n return this\n },\n }\n return proxy\n }\n\n applyTo(keqRequest: KeqRequest, moduleRef: ModuleRef): void {\n for (const entry of this.entries) {\n let resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef))\n\n if (entry.excludedRouteInfos && entry.excludedRouteInfos.length > 0) {\n const excludedRoutes = entry.excludedRouteInfos.map((info) => this.buildRoute(info))\n resolved = resolved.map((mw) => this.wrapWithExclusion(mw, excludedRoutes))\n }\n\n const isGlobal = entry.routes.length === 0\n || entry.routes.some((r) => r === KEQ_ROUTES.ALL)\n\n if (isGlobal) {\n for (const mw of resolved) keqRequest.use(mw)\n } else {\n for (const routeTarget of entry.routes) {\n if (routeTarget === KEQ_ROUTES.ALL) continue\n\n if (this.isKeqModuleClass(routeTarget)) {\n const targetRequest = moduleRef.get<KeqRequest>(routeTarget.KEQ_REQUEST, { strict: false })\n if (targetRequest) {\n for (const mw of resolved) targetRequest.use(mw)\n }\n } else {\n const route = this.buildRoute(routeTarget as KeqRouteInfo)\n keqRequest.useRouter().route(route, resolved)\n }\n }\n }\n }\n }\n\n private isKeqModuleClass(route: unknown): route is KeqModuleClass {\n return (\n typeof route === 'function'\n && 'KEQ_REQUEST' in route\n && typeof (route as Record<string, unknown>).KEQ_REQUEST === 'symbol'\n )\n }\n\n private isNestMiddlewareClass(m: Type<KeqNestMiddleware> | KeqMiddleware): m is Type<KeqNestMiddleware> {\n return typeof m === 'function' && m.prototype !== undefined && 'use' in m.prototype\n }\n\n private resolveMiddleware(m: Type<KeqNestMiddleware> | KeqMiddleware, moduleRef: ModuleRef): KeqMiddleware {\n if (this.isNestMiddlewareClass(m)) {\n const instance = moduleRef.get<KeqNestMiddleware>(m, { strict: false })\n return async (ctx, next) => {\n await instance.use(ctx, next)\n }\n }\n return m\n }\n\n private buildRoute(info: KeqRouteInfo): KeqRoute {\n const routes: KeqRoute[] = []\n if (info.host) {\n const host = info.host\n routes.push((ctx) => ctx.request.url.host === host)\n }\n if (info.method) {\n const method = info.method.toLowerCase()\n routes.push((ctx) => ctx.request.method.toLowerCase() === method)\n }\n if (info.pathname) {\n const isMatch: (test: string) => boolean = picomatch(info.pathname)\n routes.push((ctx) => isMatch(ctx.request.url.pathname))\n }\n if (routes.length === 1) return routes[0]\n return composeRoute(routes)\n }\n\n private wrapWithExclusion(middleware: KeqMiddleware, excludedRoutes: KeqRoute[]): KeqMiddleware {\n const excluded: KeqMiddleware = async (ctx, next) => {\n if (await this.checkExcluded(ctx, excludedRoutes)) {\n return next()\n }\n return middleware(ctx, next)\n }\n return excluded\n }\n\n private async checkExcluded(ctx: KeqExecutionContext, excludedRoutes: KeqRoute[]): Promise<boolean> {\n for (const route of excludedRoutes) {\n if (await route(ctx)) return true\n }\n return false\n }\n}\n","import type { KeqMiddlewareModule } from '../interfaces/keq-middleware-module.interface.js'\n\n\nexport function hasConfigureKeqMiddleware(instance: unknown): instance is KeqMiddlewareModule {\n return (\n instance !== null\n && instance !== undefined\n && typeof (instance as Record<string, unknown>).configureKeqMiddleware === 'function'\n )\n}\n","import { Global, Module, OnModuleInit } from '@nestjs/common'\nimport { ModulesContainer, ModuleRef } from '@nestjs/core'\nimport { KeqRequest } from 'keq'\nimport { KeqMiddlewareConsumerImpl } from './keq-middleware-consumer.js'\nimport { hasConfigureKeqMiddleware } from './utils/has-configure-keq-middleware.js'\n\n\n@Global()\n@Module({\n providers: [{ provide: KeqRequest, useFactory: () => new KeqRequest() }],\n exports: [KeqRequest],\n})\nexport class KeqModule implements OnModuleInit {\n constructor(\n private readonly modulesContainer: ModulesContainer,\n private readonly moduleRef: ModuleRef,\n private readonly keqRequest: KeqRequest,\n ) {}\n\n onModuleInit(): void {\n for (const [, moduleWrapper] of this.modulesContainer) {\n const instance = moduleWrapper.instance\n if (hasConfigureKeqMiddleware(instance)) {\n const consumer = new KeqMiddlewareConsumerImpl()\n instance.configureKeqMiddleware(consumer)\n consumer.applyTo(this.keqRequest, this.moduleRef)\n }\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keq-request/nestjs",
3
- "version": "5.0.0-beta.11",
3
+ "version": "5.0.0-beta.12",
4
4
  "description": "Request API write by Typescript for flexibility, readability, and a low learning curve.",
5
5
  "keywords": [
6
6
  "request",
@@ -41,12 +41,12 @@
41
41
  "@nestjs/core": "^11.1.19",
42
42
  "@types/node": "^20.19.39",
43
43
  "@types/picomatch": "^4.0.0",
44
- "keq": "5.0.0-beta.11"
44
+ "keq": "5.0.0-beta.12"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@nestjs/common": "^11.0.0",
48
48
  "@nestjs/core": "^11.0.0",
49
- "keq": "^5.0.0-beta.11"
49
+ "keq": "^5.0.0-beta.12"
50
50
  },
51
51
  "engines": {
52
52
  "node": ">=20.0.0"
@@ -15,6 +15,7 @@ export interface KeqModuleClass {
15
15
  }
16
16
 
17
17
  export interface KeqMiddlewareConfigProxy {
18
+ exclude(...routes: KeqRouteInfo[]): KeqMiddlewareConfigProxy
18
19
  forRoutes(...routes: Array<typeof KEQ_ROUTES.ALL | KeqRouteInfo | KeqModuleClass>): KeqMiddlewareConsumer
19
20
  }
20
21
 
@@ -1,6 +1,6 @@
1
1
  import type { Type } from '@nestjs/common'
2
2
  import type { ModuleRef } from '@nestjs/core'
3
- import type { KeqMiddleware, KeqRoute } from 'keq'
3
+ import type { KeqExecutionContext, KeqMiddleware, KeqRoute } from 'keq'
4
4
  import { composeRoute, KeqRequest } from 'keq'
5
5
  import picomatch from 'picomatch'
6
6
  import { KEQ_ROUTES } from './constants.js'
@@ -11,6 +11,7 @@ import type { KeqNestMiddleware } from './interfaces/keq-nest-middleware.interfa
11
11
  interface MiddlewareEntry {
12
12
  middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>
13
13
  routes: Array<typeof KEQ_ROUTES.ALL | KeqRouteInfo | KeqModuleClass>
14
+ excludedRouteInfos?: KeqRouteInfo[]
14
15
  }
15
16
 
16
17
  export class KeqMiddlewareConsumerImpl implements KeqMiddlewareConsumer {
@@ -18,18 +19,34 @@ export class KeqMiddlewareConsumerImpl implements KeqMiddlewareConsumer {
18
19
 
19
20
  apply(...middlewares: Array<Type<KeqNestMiddleware> | KeqMiddleware>): KeqMiddlewareConfigProxy {
20
21
  const entry: MiddlewareEntry = { middlewares, routes: [] }
22
+ const excludedRouteInfos: KeqRouteInfo[] = []
21
23
  this.entries.push(entry)
22
- return {
24
+
25
+ const proxy: KeqMiddlewareConfigProxy = {
26
+ exclude: (...routes) => {
27
+ excludedRouteInfos.push(...routes)
28
+ return proxy
29
+ },
23
30
  forRoutes: (...routes) => {
24
31
  entry.routes = routes
32
+ if (excludedRouteInfos.length > 0) {
33
+ entry.excludedRouteInfos = excludedRouteInfos
34
+ }
25
35
  return this
26
36
  },
27
37
  }
38
+ return proxy
28
39
  }
29
40
 
30
41
  applyTo(keqRequest: KeqRequest, moduleRef: ModuleRef): void {
31
42
  for (const entry of this.entries) {
32
- const resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef))
43
+ let resolved = entry.middlewares.map((m) => this.resolveMiddleware(m, moduleRef))
44
+
45
+ if (entry.excludedRouteInfos && entry.excludedRouteInfos.length > 0) {
46
+ const excludedRoutes = entry.excludedRouteInfos.map((info) => this.buildRoute(info))
47
+ resolved = resolved.map((mw) => this.wrapWithExclusion(mw, excludedRoutes))
48
+ }
49
+
33
50
  const isGlobal = entry.routes.length === 0
34
51
  || entry.routes.some((r) => r === KEQ_ROUTES.ALL)
35
52
 
@@ -92,4 +109,21 @@ export class KeqMiddlewareConsumerImpl implements KeqMiddlewareConsumer {
92
109
  if (routes.length === 1) return routes[0]
93
110
  return composeRoute(routes)
94
111
  }
112
+
113
+ private wrapWithExclusion(middleware: KeqMiddleware, excludedRoutes: KeqRoute[]): KeqMiddleware {
114
+ const excluded: KeqMiddleware = async (ctx, next) => {
115
+ if (await this.checkExcluded(ctx, excludedRoutes)) {
116
+ return next()
117
+ }
118
+ return middleware(ctx, next)
119
+ }
120
+ return excluded
121
+ }
122
+
123
+ private async checkExcluded(ctx: KeqExecutionContext, excludedRoutes: KeqRoute[]): Promise<boolean> {
124
+ for (const route of excludedRoutes) {
125
+ if (await route(ctx)) return true
126
+ }
127
+ return false
128
+ }
95
129
  }