@@ -5,7 +5,9 @@ import type { INestJSMethodParamMetadata, NestJSMethodWrapper } from './method-w
5
5
import type { NestJSRestfulScanner } from './restful-scanner'
6
6
import { UnauthorizedException } from '@nestjs/common'
7
7
import { isClass } from '@unioc/shared'
8
+ import { Observable } from 'rxjs'
8
9
import { ExecutionContextBuilder } from '../execution-context-builder'
10
+ import { toResult } from '../utils'
9
11
import { EndingHandler } from './ending-handler'
10
12
import { NestJSMethodOperator } from './method-operator'
11
13
@@ -156,6 +158,34 @@ export class NestJSRestfulHandler implements IRestfulConnect.Handler {
156
158
throw new UnauthorizedException ( )
157
159
}
158
160
161
+ protected async executeInterceptors ( methodWrapper : NestJSMethodWrapper , params : unknown [ ] , observable : Observable < unknown > ) : Promise < Observable < unknown > > {
162
+ const controllerTarget = methodWrapper
163
+ . getControllerOperator ( )
164
+ . getControllerWrapper ( )
165
+ . getClassWrapper ( )
166
+ . getTarget ( )
167
+
168
+ const resolvedInterceptors = await methodWrapper . getControllerOperator ( ) . getControllerWrapper ( ) . getRestfulScanner ( ) . mergeAndResolveToInstance (
169
+ methodWrapper . getMethodInterceptors ( ) ,
170
+ methodWrapper . getControllerOperator ( ) . getControllerInterceptors ( ) ,
171
+ )
172
+
173
+ for ( const interceptor of resolvedInterceptors ) {
174
+ observable = await interceptor . intercept (
175
+ new ExecutionContextBuilder (
176
+ params ,
177
+ 'http' ,
178
+ controllerTarget ,
179
+ controllerTarget . prototype [ methodWrapper . getPropertyKey ( ) ] ,
180
+ ) ,
181
+ {
182
+ handle : ( ) => observable ,
183
+ } ,
184
+ )
185
+ }
186
+ return observable
187
+ }
188
+
159
189
async initialize ( ctx : IRestfulConnect . InitializeContext ) : Promise < void > {
160
190
const map = await this . getRestfulScanner ( )
161
191
. getMiddlewareResolver ( )
@@ -195,10 +225,23 @@ export class NestJSRestfulHandler implements IRestfulConnect.Handler {
195
225
methodArguments = await this . buildParams ( methodWrapper , ctx )
196
226
// 2. Execute guards
197
227
await this . executeGuards ( methodWrapper , methodArguments )
198
- // 3. Execute the controller method
199
- const result = await methodWrapper . execute ( methodArguments , extraOptions )
200
- // 4. TODO: Execute the interceptors
201
- // 5. Send the ending response
228
+ // 3. Execute the controller method in an observable
229
+ const responseObservable = new Observable ( ( subscribe ) => {
230
+ methodWrapper . execute ( methodArguments , extraOptions )
231
+ . then ( ( result ) => {
232
+ if ( result . type === 'result' )
233
+ subscribe . next ( result . value )
234
+ else
235
+ subscribe . error ( result . error )
236
+ subscribe . complete ( )
237
+ } )
238
+ . catch ( error => subscribe . error ( error ) )
239
+ } )
240
+ // 4. Execute the before interceptors
241
+ const interceptedObservable = await this . executeInterceptors ( methodWrapper , methodArguments , responseObservable )
242
+ // 5. Get the result from the observable
243
+ const result = await toResult ( interceptedObservable )
244
+ // 6. Send the ending response if not sent
202
245
await this . _endingHandler . sendConnectEndingIfNotSent ( ctx , result )
203
246
}
204
247
catch ( error ) {
0 commit comments