Skip to content

Commit 18ba20f

Browse files
Merge pull request #88 from uniocjs/dev-groupguanfang
feat: add middleware customer (#21)
2 parents 8de67a4 + 299cd88 commit 18ba20f

File tree

4 files changed

+118
-1
lines changed

4 files changed

+118
-1
lines changed

.changeset/yellow-rocks-juggle.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@unioc/adapter-nestjs": patch
3+
---
4+
5+
feat: add middleware customer (#21)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import type { MiddlewareConfigProxy, MiddlewareConsumer, NestMiddleware, RouteInfo, Type } from '@nestjs/common/interfaces'
2+
import type { IPluginContext } from '@unioc/core'
3+
import type { MiddlewareConsumerBuilder } from './middleware-customer'
4+
import { isClass } from '@unioc/shared'
5+
6+
export interface IResolvedMiddleware {
7+
handler(...args: any[]): any
8+
instance?: NestMiddleware
9+
routes: (string | Type<any> | RouteInfo)[]
10+
}
11+
12+
export class MiddlewareConfigProxyBuilder implements MiddlewareConfigProxy {
13+
private _excludedRoutes: (string | RouteInfo)[] = []
14+
private _routes: (string | Type<any> | RouteInfo)[] = []
15+
private _middleware: (Type<any> | ((...args: any[]) => any))[] = []
16+
17+
constructor(private readonly _middlewareConsumer: MiddlewareConsumerBuilder) {}
18+
19+
protected getMiddlewareConsumer(): MiddlewareConsumer {
20+
this._middlewareConsumer.add(this)
21+
return this._middlewareConsumer
22+
}
23+
24+
exclude(...routes: (string | RouteInfo)[]): MiddlewareConfigProxy {
25+
this._excludedRoutes = [...this._excludedRoutes, ...routes]
26+
return this
27+
}
28+
29+
forRoutes(...routes: (string | Type<any> | RouteInfo)[]): MiddlewareConsumer {
30+
this._routes = [...this._routes, ...routes]
31+
return this.getMiddlewareConsumer()
32+
}
33+
34+
public getExcludedRoutes(): (string | RouteInfo)[] {
35+
return this._excludedRoutes
36+
}
37+
38+
public getRoutes(): (string | Type<any> | RouteInfo)[] {
39+
return this._routes
40+
}
41+
42+
public setMiddleware(middleware: (Type<any> | ((...args: any[]) => any))[]): void {
43+
this._middleware = middleware
44+
}
45+
46+
public async resolveMiddlewares(ctx: IPluginContext): Promise<IResolvedMiddleware[]> {
47+
const handlers: IResolvedMiddleware[] = []
48+
49+
for (const middleware of this._middleware) {
50+
if (isClass(middleware)) {
51+
const instance: NestMiddleware = await ctx.createClass(middleware).resolve()
52+
if (instance && typeof instance === 'object' && 'use' in instance && typeof instance.use === 'function') {
53+
handlers.push({
54+
handler: instance.use,
55+
instance,
56+
routes: this._routes,
57+
})
58+
}
59+
}
60+
else {
61+
handlers.push({
62+
handler: middleware,
63+
instance: undefined,
64+
routes: this._routes,
65+
})
66+
}
67+
}
68+
69+
return handlers
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { MiddlewareConsumer, Type } from '@nestjs/common'
2+
import type { MiddlewareConfigProxy } from '@nestjs/common/interfaces'
3+
import { MiddlewareConfigProxyBuilder } from './middleware-config-proxy'
4+
5+
export class MiddlewareConsumerBuilder implements MiddlewareConsumer {
6+
private _middlewareConfigs: MiddlewareConfigProxyBuilder[] = []
7+
8+
apply(...middleware: (Type<any> | ((...args: any[]) => any))[]): MiddlewareConfigProxy {
9+
const config = new MiddlewareConfigProxyBuilder(this)
10+
config.setMiddleware(middleware)
11+
return config
12+
}
13+
14+
add(...middlewareConfigs: MiddlewareConfigProxyBuilder[]): MiddlewareConsumer {
15+
this._middlewareConfigs = [...this._middlewareConfigs, ...middlewareConfigs]
16+
return this
17+
}
18+
19+
public getMiddlewareConfigs(): MiddlewareConfigProxyBuilder[] {
20+
return this._middlewareConfigs
21+
}
22+
}

packages/adapter/adapter-nestjs/src/plugin.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import type { InjectionToken, ModuleMetadata } from '@nestjs/common'
1+
import type { InjectionToken, ModuleMetadata, NestModule } from '@nestjs/common'
22
import type { IPlugin } from '@unioc/core'
33
import type { IClass } from '@unioc/shared'
44
import { PROPERTY_DEPS_METADATA, SELF_DECLARED_DEPS_METADATA } from '@nestjs/common/constants.js'
55
import { AbstractRestfulBootstrap } from '@unioc/web'
66
import { ErrorCollector } from './error-collector'
7+
import { MiddlewareConsumerBuilder } from './middleware/middleware-customer'
78
import { NestJSResolver } from './nest-resolver'
89
import { NestJSRestfulHandler } from './restful/restful-handler'
910
import { NestJSRestfulScanner } from './restful/restful-scanner'
@@ -47,6 +48,24 @@ export function NestJS(options: NestJS.Options = {}): IPlugin {
4748
bootstrap.addRestfulScanner(scanner)
4849
bootstrap.createValue(scanner, NestJSRestfulScanner)
4950
await scanner.resolveAll()
51+
52+
// apply restful middlewares
53+
const modules = nestJSResolver.getResolvedModules()
54+
const middlewareConsumer = new MiddlewareConsumerBuilder()
55+
56+
for (const moduleWrapper of modules) {
57+
const resolvedInstance: NestModule = await moduleWrapper.resolve()
58+
if (resolvedInstance && typeof resolvedInstance === 'object' && 'configure' in resolvedInstance && typeof resolvedInstance.configure === 'function') {
59+
await resolvedInstance.configure(middlewareConsumer)
60+
}
61+
}
62+
63+
// apply middlewares
64+
const middlewareConfigs = middlewareConsumer.getMiddlewareConfigs()
65+
for (const middlewareConfig of middlewareConfigs) {
66+
const _middlewares = await middlewareConfig.resolveMiddlewares(this)
67+
// TODO
68+
}
5069
},
5170

5271
async resolve(ctx) {

0 commit comments

Comments
 (0)