@@ -12,14 +12,15 @@ import {
1212} from '@nestjs/common/constants' ;
1313import { Module } from '@nestjs/core/injector/module' ;
1414import { ArgumentMetadata } from '@nestjs/common/interfaces/features/pipe-transform.interface' ;
15- import { ModuleRef } from '@nestjs/core' ;
15+ import { ApplicationConfig , ModuleRef , NestContainer } from '@nestjs/core' ;
1616import { DataSource } from 'typeorm' ;
1717
18- import { ParamsForExecute } from '../types' ;
18+ import { MapControllerInterceptor , ParamsForExecute } from '../types' ;
1919import { CURRENT_DATA_SOURCE_TOKEN } from '../../../constants' ;
2020import {
2121 ASYNC_ITERATOR_FACTORY ,
2222 KEY_MAIN_INPUT_SCHEMA ,
23+ MAP_CONTROLLER_INTERCEPTORS ,
2324 OPTIONS ,
2425} from '../constants' ;
2526import { IterateFactory } from '../factory' ;
@@ -31,6 +32,13 @@ import {
3132 ValidateQueryError ,
3233} from '../../../types' ;
3334import { ObjectTyped } from '../../../helper' ;
35+ import {
36+ InterceptorsConsumer ,
37+ InterceptorsContextCreator ,
38+ } from '@nestjs/core/interceptors' ;
39+ import { Controller } from '@nestjs/common/interfaces' ;
40+ import { lastValueFrom } from 'rxjs' ;
41+ import { AsyncLocalStorage } from 'async_hooks' ;
3442
3543export function isZodError (
3644 param : string | unknown
@@ -46,11 +54,34 @@ export function isZodError(
4654@Injectable ( )
4755export class ExecuteService {
4856 @Inject ( CURRENT_DATA_SOURCE_TOKEN ) private readonly dataSource ! : DataSource ;
49- @Inject ( ModuleRef ) private readonly moduleRef ! : ModuleRef ;
57+ @Inject ( ModuleRef ) private readonly moduleRef ! : ModuleRef & {
58+ container : NestContainer ;
59+ applicationConfig : ApplicationConfig ;
60+ _moduleKey : string ;
61+ } ;
5062 @Inject ( ASYNC_ITERATOR_FACTORY ) private asyncIteratorFactory ! : IterateFactory <
5163 ExecuteService [ 'runOneOperation' ]
5264 > ;
5365 @Inject ( OPTIONS ) private options ! : ConfigParam ;
66+ @Inject ( MAP_CONTROLLER_INTERCEPTORS )
67+ private mapControllerInterceptor ! : MapControllerInterceptor ;
68+
69+ @Inject ( AsyncLocalStorage ) private asyncLocalStorage ! : AsyncLocalStorage < any > ;
70+
71+ private _interceptorsContextCreator ! : InterceptorsContextCreator ;
72+
73+ get interceptorsContextCreator ( ) {
74+ if ( ! this . _interceptorsContextCreator ) {
75+ this . _interceptorsContextCreator = new InterceptorsContextCreator (
76+ this . moduleRef . container ,
77+ this . moduleRef . applicationConfig
78+ ) ;
79+ }
80+
81+ return this . _interceptorsContextCreator ;
82+ }
83+
84+ private interceptorsConsumer = new InterceptorsConsumer ( ) ;
5485
5586 async run ( params : ParamsForExecute [ ] , tmpIds : ( string | number ) [ ] ) {
5687 if (
@@ -79,7 +110,7 @@ export class ExecuteService {
79110
80111 private async executeOperations (
81112 params : ParamsForExecute [ ] ,
82- tmpIds : ( string | number ) [ ]
113+ tmpIds : ( string | number ) [ ] = [ ]
83114 ) {
84115 const iterateParams = this . asyncIteratorFactory . createIterator (
85116 params as Parameters < ExecuteService [ 'runOneOperation' ] > ,
@@ -101,9 +132,39 @@ export class ExecuteService {
101132 const paramsForExecute = item as unknown as ParamsForExecute [ 'params' ] ;
102133
103134 const itemReplace = this . replaceTmpIds ( paramsForExecute , tmpIdsMap ) ;
135+ const body = itemReplace . at ( - 1 ) ;
136+ const currentTmpId = tmpIds [ i ] ;
137+
138+ if ( methodName === 'postOne' && currentTmpId && body ) {
139+ if ( typeof body === 'object' && 'attributes' in body ) {
140+ body [ 'id' ] = `${ currentTmpId } ` ;
141+ itemReplace [ itemReplace . length - 1 ] ;
142+ }
143+ }
104144
105- // @ts -ignore
106- const result = await controller [ methodName ] ( ...itemReplace ) ;
145+ const interceptors = this . getInterceptorsArray (
146+ controller ,
147+ controller [ methodName ] ,
148+ currentParams . module
149+ ) ;
150+
151+ const result$ : any = await this . interceptorsConsumer . intercept (
152+ interceptors ,
153+ [
154+ ...Object . values ( this . asyncLocalStorage . getStore ( ) || { } ) ,
155+ itemReplace ,
156+ ] ,
157+ controller ,
158+ // @ts -ignore
159+ controller [ methodName ] ,
160+ // @ts -ignore
161+ async ( ) => controller [ methodName ] ( ...itemReplace )
162+ ) ;
163+
164+ const result =
165+ interceptors . length === 0
166+ ? await result$
167+ : await lastValueFrom ( result$ ) ;
107168
108169 if ( tmpIds [ i ] && result && ! Array . isArray ( result . data ) && result . data ) {
109170 tmpIdsMap [ tmpIds [ i ] ] = result . data . id ;
@@ -120,6 +181,41 @@ export class ExecuteService {
120181 return resultArray ;
121182 }
122183
184+ private getInterceptorsArray (
185+ controller : Controller ,
186+ callback : ( ...arg : any ) => any ,
187+ module : ParamsForExecute [ 'module' ]
188+ ) {
189+ let controllerFromMap = this . mapControllerInterceptor . get ( controller ) ;
190+
191+ if ( ! controllerFromMap ) {
192+ controllerFromMap = new Map ( ) ;
193+ this . mapControllerInterceptor . set ( controller , controllerFromMap ) ;
194+ }
195+
196+ const interceptorsFromMap = controllerFromMap . get ( callback ) ;
197+
198+ if ( interceptorsFromMap ) {
199+ return interceptorsFromMap ;
200+ }
201+
202+ const interceptorsForController = this . interceptorsContextCreator . create (
203+ controller ,
204+ callback ,
205+ module . token
206+ ) ;
207+
208+ const interceptorsForMethode = new Set (
209+ Reflect . getMetadata ( INTERCEPTORS_METADATA , callback ) || [ ]
210+ ) ;
211+
212+ const resultInterceptors = interceptorsForController . filter ( ( i ) =>
213+ interceptorsForMethode . has ( i . constructor )
214+ ) ;
215+ controllerFromMap . set ( callback , resultInterceptors ) ;
216+ return resultInterceptors ;
217+ }
218+
123219 private replaceTmpIds < T extends ParamsForExecute [ 'params' ] > (
124220 inputParams : T ,
125221 tmpIdsMap : Record < string | number , string | number >
@@ -162,6 +258,7 @@ export class ExecuteService {
162258 }
163259 return acum ;
164260 } ,
261+ // @ts -ignore
165262 { ...relationships }
166263 ) ;
167264
0 commit comments