@@ -12,14 +12,15 @@ import {
12
12
} from '@nestjs/common/constants' ;
13
13
import { Module } from '@nestjs/core/injector/module' ;
14
14
import { ArgumentMetadata } from '@nestjs/common/interfaces/features/pipe-transform.interface' ;
15
- import { ModuleRef } from '@nestjs/core' ;
15
+ import { ApplicationConfig , ModuleRef , NestContainer } from '@nestjs/core' ;
16
16
import { DataSource } from 'typeorm' ;
17
17
18
- import { ParamsForExecute } from '../types' ;
18
+ import { MapControllerInterceptor , ParamsForExecute } from '../types' ;
19
19
import { CURRENT_DATA_SOURCE_TOKEN } from '../../../constants' ;
20
20
import {
21
21
ASYNC_ITERATOR_FACTORY ,
22
22
KEY_MAIN_INPUT_SCHEMA ,
23
+ MAP_CONTROLLER_INTERCEPTORS ,
23
24
OPTIONS ,
24
25
} from '../constants' ;
25
26
import { IterateFactory } from '../factory' ;
@@ -31,6 +32,13 @@ import {
31
32
ValidateQueryError ,
32
33
} from '../../../types' ;
33
34
import { 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' ;
34
42
35
43
export function isZodError (
36
44
param : string | unknown
@@ -46,11 +54,34 @@ export function isZodError(
46
54
@Injectable ( )
47
55
export class ExecuteService {
48
56
@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
+ } ;
50
62
@Inject ( ASYNC_ITERATOR_FACTORY ) private asyncIteratorFactory ! : IterateFactory <
51
63
ExecuteService [ 'runOneOperation' ]
52
64
> ;
53
65
@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 ( ) ;
54
85
55
86
async run ( params : ParamsForExecute [ ] , tmpIds : ( string | number ) [ ] ) {
56
87
if (
@@ -79,7 +110,7 @@ export class ExecuteService {
79
110
80
111
private async executeOperations (
81
112
params : ParamsForExecute [ ] ,
82
- tmpIds : ( string | number ) [ ]
113
+ tmpIds : ( string | number ) [ ] = [ ]
83
114
) {
84
115
const iterateParams = this . asyncIteratorFactory . createIterator (
85
116
params as Parameters < ExecuteService [ 'runOneOperation' ] > ,
@@ -101,9 +132,39 @@ export class ExecuteService {
101
132
const paramsForExecute = item as unknown as ParamsForExecute [ 'params' ] ;
102
133
103
134
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
+ }
104
144
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$ ) ;
107
168
108
169
if ( tmpIds [ i ] && result && ! Array . isArray ( result . data ) && result . data ) {
109
170
tmpIdsMap [ tmpIds [ i ] ] = result . data . id ;
@@ -120,6 +181,41 @@ export class ExecuteService {
120
181
return resultArray ;
121
182
}
122
183
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
+
123
219
private replaceTmpIds < T extends ParamsForExecute [ 'params' ] > (
124
220
inputParams : T ,
125
221
tmpIdsMap : Record < string | number , string | number >
@@ -162,6 +258,7 @@ export class ExecuteService {
162
258
}
163
259
return acum ;
164
260
} ,
261
+ // @ts -ignore
165
262
{ ...relationships }
166
263
) ;
167
264
0 commit comments