@congruent-stack/congruent-api 0.6.0 → 0.9.0-rc.0
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.
- package/dist/index.cjs +215 -121
- package/dist/index.d.cts +46 -50
- package/dist/index.d.mts +46 -50
- package/dist/index.mjs +214 -122
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -158,7 +158,7 @@ class MethodEndpointHandlerRegistryEntry {
|
|
|
158
158
|
callback(this);
|
|
159
159
|
return this;
|
|
160
160
|
}
|
|
161
|
-
_injection = (
|
|
161
|
+
_injection = (_diScope) => ({});
|
|
162
162
|
get injection() {
|
|
163
163
|
return this._injection;
|
|
164
164
|
}
|
|
@@ -166,28 +166,28 @@ class MethodEndpointHandlerRegistryEntry {
|
|
|
166
166
|
this._injection = injection;
|
|
167
167
|
return this;
|
|
168
168
|
}
|
|
169
|
-
async trigger(
|
|
169
|
+
async trigger(diScope, requestObject) {
|
|
170
170
|
if (!this._handler) {
|
|
171
171
|
throw new Error("Handler not set for this endpoint");
|
|
172
172
|
}
|
|
173
173
|
let badRequestResponse = null;
|
|
174
|
-
const headers = parseRequestDefinitionField(this._methodEndpoint.definition, "headers",
|
|
174
|
+
const headers = parseRequestDefinitionField(this._methodEndpoint.definition, "headers", requestObject);
|
|
175
175
|
if (isHttpResponseObject(headers)) {
|
|
176
176
|
badRequestResponse = headers;
|
|
177
177
|
return badRequestResponse;
|
|
178
178
|
}
|
|
179
|
-
const query = parseRequestDefinitionField(this._methodEndpoint.definition, "query",
|
|
179
|
+
const query = parseRequestDefinitionField(this._methodEndpoint.definition, "query", requestObject);
|
|
180
180
|
if (isHttpResponseObject(query)) {
|
|
181
181
|
badRequestResponse = query;
|
|
182
182
|
return badRequestResponse;
|
|
183
183
|
}
|
|
184
|
-
const body = parseRequestDefinitionField(this._methodEndpoint.definition, "body",
|
|
184
|
+
const body = parseRequestDefinitionField(this._methodEndpoint.definition, "body", requestObject);
|
|
185
185
|
if (isHttpResponseObject(body)) {
|
|
186
186
|
badRequestResponse = body;
|
|
187
187
|
return badRequestResponse;
|
|
188
188
|
}
|
|
189
189
|
const path = `/${this._methodEndpoint.pathSegments.map(
|
|
190
|
-
(segment) => segment.startsWith(":") ?
|
|
190
|
+
(segment) => segment.startsWith(":") ? requestObject.pathParams[segment.slice(1)] ?? "?" : segment
|
|
191
191
|
).join("/")}`;
|
|
192
192
|
return await this._handler({
|
|
193
193
|
method: this._methodEndpoint.method,
|
|
@@ -195,32 +195,45 @@ class MethodEndpointHandlerRegistryEntry {
|
|
|
195
195
|
genericPath: this._methodEndpoint.genericPath,
|
|
196
196
|
pathSegments: this._methodEndpoint.pathSegments,
|
|
197
197
|
headers,
|
|
198
|
-
pathParams:
|
|
198
|
+
pathParams: requestObject.pathParams,
|
|
199
199
|
query,
|
|
200
200
|
body,
|
|
201
|
-
injected: this._injection(
|
|
201
|
+
injected: this._injection(diScope)
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
|
-
function parseRequestDefinitionField(definition, key,
|
|
205
|
+
function parseRequestDefinitionField(definition, key, requestObject) {
|
|
206
206
|
if (definition[key]) {
|
|
207
|
-
if (!(key in
|
|
208
|
-
|
|
207
|
+
if (!(key in requestObject) || requestObject[key] === null || requestObject[key] === void 0) {
|
|
208
|
+
const result2 = definition[key].safeParse(requestObject[key]);
|
|
209
|
+
if (!result2.success) {
|
|
210
|
+
switch (definition[key].type) {
|
|
211
|
+
case "optional":
|
|
212
|
+
if (requestObject[key] === null) {
|
|
213
|
+
return void 0;
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
case "nullable":
|
|
217
|
+
if (requestObject[key] === void 0) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
209
222
|
return {
|
|
210
223
|
code: HttpStatusCode.BadRequest_400,
|
|
211
224
|
body: `'${key}' is required for this endpoint` + (key === "body" ? ", { 'Content-Type': 'application/json' } header might be missing" : "")
|
|
212
225
|
};
|
|
213
226
|
}
|
|
214
|
-
return
|
|
227
|
+
return result2.data;
|
|
215
228
|
}
|
|
216
|
-
const result = definition[key].safeParse(
|
|
229
|
+
const result = definition[key].safeParse(requestObject[key]);
|
|
217
230
|
if (!result.success) {
|
|
218
231
|
return {
|
|
219
232
|
code: HttpStatusCode.BadRequest_400,
|
|
220
233
|
body: result.error.issues
|
|
221
234
|
};
|
|
222
235
|
}
|
|
223
|
-
return result.data
|
|
236
|
+
return result.data;
|
|
224
237
|
}
|
|
225
238
|
return null;
|
|
226
239
|
}
|
|
@@ -235,6 +248,9 @@ function middleware(apiReg, path) {
|
|
|
235
248
|
}
|
|
236
249
|
class MiddlewareHandlersRegistryEntryInternal {
|
|
237
250
|
_dicontainer;
|
|
251
|
+
get dicontainer() {
|
|
252
|
+
return this._dicontainer;
|
|
253
|
+
}
|
|
238
254
|
_middlewareGenericPath;
|
|
239
255
|
get genericPath() {
|
|
240
256
|
return this._middlewareGenericPath;
|
|
@@ -265,39 +281,42 @@ class MiddlewareHandlersRegistryEntryInternal {
|
|
|
265
281
|
this._handler = handler;
|
|
266
282
|
}
|
|
267
283
|
_injection = (_dicontainer) => ({});
|
|
268
|
-
async trigger(
|
|
284
|
+
async trigger(diScope, requestObject, next) {
|
|
269
285
|
let badRequestResponse = null;
|
|
270
|
-
const headers = middlewareParseRequestDefinitionField(this._inputSchemas, "headers",
|
|
286
|
+
const headers = middlewareParseRequestDefinitionField(this._inputSchemas, "headers", requestObject);
|
|
271
287
|
if (isHttpResponseObject(headers)) {
|
|
272
288
|
badRequestResponse = headers;
|
|
273
289
|
return badRequestResponse;
|
|
274
290
|
}
|
|
275
|
-
const query = middlewareParseRequestDefinitionField(this._inputSchemas, "query",
|
|
291
|
+
const query = middlewareParseRequestDefinitionField(this._inputSchemas, "query", requestObject);
|
|
276
292
|
if (isHttpResponseObject(query)) {
|
|
277
293
|
badRequestResponse = query;
|
|
278
294
|
return badRequestResponse;
|
|
279
295
|
}
|
|
280
|
-
const body = middlewareParseRequestDefinitionField(this._inputSchemas, "body",
|
|
296
|
+
const body = middlewareParseRequestDefinitionField(this._inputSchemas, "body", requestObject);
|
|
281
297
|
if (isHttpResponseObject(body)) {
|
|
282
298
|
badRequestResponse = body;
|
|
283
299
|
return badRequestResponse;
|
|
284
300
|
}
|
|
285
301
|
const { method, pathSegments } = this._splitMiddlewarePath();
|
|
286
302
|
const path = `/${pathSegments.map(
|
|
287
|
-
(segment) => segment.startsWith(":") ?
|
|
303
|
+
(segment) => segment.startsWith(":") ? requestObject.pathParams[segment.slice(1)] ?? "?" : segment
|
|
288
304
|
).join("/")}`;
|
|
289
|
-
return await this._handler(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
305
|
+
return await this._handler(
|
|
306
|
+
{
|
|
307
|
+
method,
|
|
308
|
+
// TODO: might be empty, as middleware can be registered with path only, without method, possible fix: take it from express.request.method
|
|
309
|
+
path,
|
|
310
|
+
genericPath: this.genericPath,
|
|
311
|
+
pathSegments,
|
|
312
|
+
headers,
|
|
313
|
+
pathParams: requestObject.pathParams,
|
|
314
|
+
query,
|
|
315
|
+
body,
|
|
316
|
+
injected: this._injection(diScope)
|
|
317
|
+
},
|
|
318
|
+
next
|
|
319
|
+
);
|
|
301
320
|
}
|
|
302
321
|
}
|
|
303
322
|
class MiddlewareHandlersRegistryEntry {
|
|
@@ -307,7 +326,7 @@ class MiddlewareHandlersRegistryEntry {
|
|
|
307
326
|
this._registry = registry;
|
|
308
327
|
this._path = path;
|
|
309
328
|
}
|
|
310
|
-
_injection = (
|
|
329
|
+
_injection = (_diScope) => ({});
|
|
311
330
|
get injection() {
|
|
312
331
|
return this._injection;
|
|
313
332
|
}
|
|
@@ -332,8 +351,13 @@ class MiddlewareHandlersRegistry {
|
|
|
332
351
|
this.dicontainer = dicontainer;
|
|
333
352
|
this._onHandlerRegisteredCallback = callback;
|
|
334
353
|
}
|
|
354
|
+
_list = [];
|
|
355
|
+
get list() {
|
|
356
|
+
return this._list;
|
|
357
|
+
}
|
|
335
358
|
register(entry) {
|
|
336
359
|
if (this._onHandlerRegisteredCallback) {
|
|
360
|
+
this._list.push(entry);
|
|
337
361
|
this._onHandlerRegisteredCallback(entry);
|
|
338
362
|
}
|
|
339
363
|
}
|
|
@@ -342,25 +366,38 @@ class MiddlewareHandlersRegistry {
|
|
|
342
366
|
this._onHandlerRegisteredCallback = callback;
|
|
343
367
|
}
|
|
344
368
|
}
|
|
345
|
-
function middlewareParseRequestDefinitionField(inputSchemas, key,
|
|
369
|
+
function middlewareParseRequestDefinitionField(inputSchemas, key, requestObject) {
|
|
346
370
|
if (inputSchemas[key]) {
|
|
347
|
-
if (!(key in
|
|
348
|
-
|
|
371
|
+
if (!(key in requestObject) || requestObject[key] === null || requestObject[key] === void 0) {
|
|
372
|
+
const result2 = inputSchemas[key].safeParse(requestObject[key]);
|
|
373
|
+
if (!result2.success) {
|
|
374
|
+
switch (inputSchemas[key].type) {
|
|
375
|
+
case "optional":
|
|
376
|
+
if (requestObject[key] === null) {
|
|
377
|
+
return void 0;
|
|
378
|
+
}
|
|
379
|
+
break;
|
|
380
|
+
case "nullable":
|
|
381
|
+
if (requestObject[key] === void 0) {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
349
386
|
return {
|
|
350
387
|
code: HttpStatusCode.BadRequest_400,
|
|
351
388
|
body: `'${key}' is required for this endpoint` + (key === "body" ? ", { 'Content-Type': 'application/json' } header might be missing" : "")
|
|
352
389
|
};
|
|
353
390
|
}
|
|
354
|
-
return
|
|
391
|
+
return result2.data;
|
|
355
392
|
}
|
|
356
|
-
const result = inputSchemas[key].safeParse(
|
|
393
|
+
const result = inputSchemas[key].safeParse(requestObject[key]);
|
|
357
394
|
if (!result.success) {
|
|
358
395
|
return {
|
|
359
396
|
code: HttpStatusCode.BadRequest_400,
|
|
360
397
|
body: result.error.issues
|
|
361
398
|
};
|
|
362
399
|
}
|
|
363
|
-
return result.data
|
|
400
|
+
return result.data;
|
|
364
401
|
}
|
|
365
402
|
return null;
|
|
366
403
|
}
|
|
@@ -528,12 +565,12 @@ class InnerApiClient {
|
|
|
528
565
|
delete currObj[key];
|
|
529
566
|
InnerApiClient._initialize(client, val, clientGenericHandler);
|
|
530
567
|
} else if (val instanceof HttpMethodEndpoint) {
|
|
531
|
-
currObj[key] = (
|
|
568
|
+
currObj[key] = (requestObject) => {
|
|
532
569
|
const pathParams = { ...client.__CONTEXT__.pathParameters };
|
|
533
570
|
client.__CONTEXT__ = InnerApiClient._initNewContext();
|
|
534
|
-
const headers = clientParseRequestDefinitionField(val.definition, "headers",
|
|
535
|
-
const query = clientParseRequestDefinitionField(val.definition, "query",
|
|
536
|
-
const body = clientParseRequestDefinitionField(val.definition, "body",
|
|
571
|
+
const headers = clientParseRequestDefinitionField(val.definition, "headers", requestObject);
|
|
572
|
+
const query = clientParseRequestDefinitionField(val.definition, "query", requestObject);
|
|
573
|
+
const body = clientParseRequestDefinitionField(val.definition, "body", requestObject);
|
|
537
574
|
const path = `/${val.pathSegments.map(
|
|
538
575
|
(segment) => segment.startsWith(":") ? pathParams[segment.slice(1)] ?? "?" : segment
|
|
539
576
|
).join("/")}`;
|
|
@@ -555,107 +592,153 @@ class InnerApiClient {
|
|
|
555
592
|
}
|
|
556
593
|
}
|
|
557
594
|
const ApiClient = InnerApiClient;
|
|
558
|
-
function clientParseRequestDefinitionField(definition, key,
|
|
595
|
+
function clientParseRequestDefinitionField(definition, key, requestObject) {
|
|
559
596
|
if (definition[key]) {
|
|
560
|
-
if (!(key in
|
|
561
|
-
|
|
562
|
-
|
|
597
|
+
if (!(key in requestObject) || requestObject[key] === null || requestObject[key] === void 0) {
|
|
598
|
+
const result2 = definition[key].safeParse(requestObject[key]);
|
|
599
|
+
if (!result2.success) {
|
|
600
|
+
switch (definition[key].type) {
|
|
601
|
+
case "optional":
|
|
602
|
+
if (requestObject[key] === null) {
|
|
603
|
+
return void 0;
|
|
604
|
+
}
|
|
605
|
+
break;
|
|
606
|
+
case "nullable":
|
|
607
|
+
if (requestObject[key] === void 0) {
|
|
608
|
+
return null;
|
|
609
|
+
}
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
throw new Error(`'${key}' is required for this endpoint`);
|
|
563
613
|
}
|
|
564
|
-
return
|
|
614
|
+
return result2.data;
|
|
565
615
|
}
|
|
566
|
-
const result = definition[key].safeParse(
|
|
616
|
+
const result = definition[key].safeParse(requestObject[key]);
|
|
567
617
|
if (!result.success) {
|
|
568
618
|
throw new Error(`Validation for '${key}' failed`, { cause: result.error });
|
|
569
619
|
}
|
|
570
|
-
return result.data
|
|
620
|
+
return result.data;
|
|
571
621
|
}
|
|
572
622
|
return null;
|
|
573
623
|
}
|
|
574
624
|
|
|
575
|
-
class
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
625
|
+
class DIContainerBase {
|
|
626
|
+
_map = /* @__PURE__ */ new Map();
|
|
627
|
+
_singletonInstances = /* @__PURE__ */ new Map();
|
|
628
|
+
createScope() {
|
|
629
|
+
const proxy = new Proxy({
|
|
630
|
+
_map: this._map,
|
|
631
|
+
_singletonInstances: this._singletonInstances,
|
|
632
|
+
_scopedInstances: /* @__PURE__ */ new Map(),
|
|
633
|
+
_isBuildingSingleton: false
|
|
634
|
+
}, {
|
|
635
|
+
get: (target, prop) => {
|
|
636
|
+
if (prop.startsWith("get")) {
|
|
637
|
+
const serviceName = prop.slice(3);
|
|
638
|
+
if (target._map.has(serviceName)) {
|
|
639
|
+
const entry = target._map.get(serviceName);
|
|
640
|
+
switch (entry.lifetime) {
|
|
641
|
+
case "transient":
|
|
642
|
+
return () => {
|
|
643
|
+
if (target._isBuildingSingleton) {
|
|
644
|
+
throw new Error(`Cannot resolve transient service '${serviceName}' while building a singleton`);
|
|
645
|
+
}
|
|
646
|
+
return entry.factory(proxy);
|
|
647
|
+
};
|
|
648
|
+
case "scoped":
|
|
649
|
+
return () => {
|
|
650
|
+
if (target._isBuildingSingleton) {
|
|
651
|
+
throw new Error(`Cannot resolve scoped service '${serviceName}' while building a singleton`);
|
|
652
|
+
}
|
|
653
|
+
if (!target._scopedInstances.has(serviceName)) {
|
|
654
|
+
const instance = entry.factory(proxy);
|
|
655
|
+
target._scopedInstances.set(serviceName, instance);
|
|
656
|
+
}
|
|
657
|
+
return target._scopedInstances.get(serviceName);
|
|
658
|
+
};
|
|
659
|
+
case "singleton":
|
|
660
|
+
return () => {
|
|
661
|
+
if (!target._singletonInstances.has(serviceName)) {
|
|
662
|
+
target._isBuildingSingleton = true;
|
|
663
|
+
try {
|
|
664
|
+
const instance = entry.factory(proxy);
|
|
665
|
+
target._singletonInstances.set(serviceName, instance);
|
|
666
|
+
} finally {
|
|
667
|
+
target._isBuildingSingleton = false;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return target._singletonInstances.get(serviceName);
|
|
671
|
+
};
|
|
672
|
+
default:
|
|
673
|
+
throw new Error(`Unsupported lifetime: ${entry.lifetime}`);
|
|
674
|
+
}
|
|
591
675
|
} else {
|
|
592
676
|
throw new Error(`Service not registered: ${serviceName}`);
|
|
593
677
|
}
|
|
594
678
|
}
|
|
595
|
-
|
|
679
|
+
throw new Error(`Property access denied by Proxy: ${String(prop)}`);
|
|
596
680
|
}
|
|
597
681
|
});
|
|
598
|
-
return
|
|
682
|
+
return proxy;
|
|
599
683
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
this.
|
|
684
|
+
}
|
|
685
|
+
class DIContainer extends DIContainerBase {
|
|
686
|
+
register(serviceNameCapitalizedLiteral, factory, lifetime) {
|
|
687
|
+
const entry = { factory, lifetime };
|
|
688
|
+
this._map.set(serviceNameCapitalizedLiteral, entry);
|
|
605
689
|
return this;
|
|
606
690
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
*/
|
|
610
|
-
resolveByName(serviceName) {
|
|
611
|
-
const registration = this.registry.get(serviceName);
|
|
612
|
-
if (!registration) {
|
|
613
|
-
throw new Error(`Service not registered: ${serviceName}`);
|
|
614
|
-
}
|
|
615
|
-
if (registration.lifetime === "singleton") {
|
|
616
|
-
if (!this.singletons.has(serviceName)) {
|
|
617
|
-
const instance = registration.factory(this.proxy);
|
|
618
|
-
this.singletons.set(serviceName, instance);
|
|
619
|
-
}
|
|
620
|
-
return this.singletons.get(serviceName);
|
|
621
|
-
}
|
|
622
|
-
return registration.factory(this.proxy);
|
|
691
|
+
createTestClone() {
|
|
692
|
+
return new DIContainerTestClone(this);
|
|
623
693
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
return () => {
|
|
636
|
-
if (registration?.lifetime === "transient") {
|
|
637
|
-
return this.resolveByName(serviceName);
|
|
638
|
-
}
|
|
639
|
-
const cacheKey = `_cached_${serviceName}`;
|
|
640
|
-
if (!target[cacheKey]) {
|
|
641
|
-
target[cacheKey] = this.resolveByName(serviceName);
|
|
642
|
-
}
|
|
643
|
-
return target[cacheKey];
|
|
644
|
-
};
|
|
645
|
-
} else {
|
|
646
|
-
throw new Error(`Service not registered: ${serviceName}`);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
return Reflect.get(target, prop);
|
|
650
|
-
}
|
|
694
|
+
}
|
|
695
|
+
class DIContainerTestClone extends DIContainerBase {
|
|
696
|
+
constructor(original) {
|
|
697
|
+
super();
|
|
698
|
+
original["_map"].forEach((value, key) => {
|
|
699
|
+
this._map.set(key, {
|
|
700
|
+
factory: (_scope) => {
|
|
701
|
+
throw new Error(`Service registration not overridden: ${key}`);
|
|
702
|
+
},
|
|
703
|
+
lifetime: value.lifetime
|
|
704
|
+
});
|
|
651
705
|
});
|
|
652
706
|
}
|
|
653
|
-
|
|
654
|
-
const
|
|
655
|
-
|
|
707
|
+
override(serviceNameLiteral, factory) {
|
|
708
|
+
const registration = this._map.get(serviceNameLiteral);
|
|
709
|
+
if (!registration) {
|
|
710
|
+
throw new Error(`Service not registered: ${serviceNameLiteral}`);
|
|
711
|
+
}
|
|
712
|
+
this._map.set(serviceNameLiteral, { factory, lifetime: registration.lifetime });
|
|
713
|
+
return this;
|
|
656
714
|
}
|
|
657
715
|
}
|
|
658
716
|
|
|
717
|
+
function execMiddleware(diScope, list, input) {
|
|
718
|
+
const queue = [...list];
|
|
719
|
+
const next = async () => {
|
|
720
|
+
const current = queue.shift();
|
|
721
|
+
if (!current) {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
const result = await current.trigger(
|
|
725
|
+
diScope,
|
|
726
|
+
{
|
|
727
|
+
headers: input.headers,
|
|
728
|
+
pathParams: input.pathParams,
|
|
729
|
+
body: input.body,
|
|
730
|
+
query: input.query
|
|
731
|
+
},
|
|
732
|
+
next
|
|
733
|
+
);
|
|
734
|
+
if (result) {
|
|
735
|
+
return result;
|
|
736
|
+
}
|
|
737
|
+
return next();
|
|
738
|
+
};
|
|
739
|
+
return next();
|
|
740
|
+
}
|
|
741
|
+
|
|
659
742
|
function createInProcApiClient(contract, testContainer, registry) {
|
|
660
743
|
const testApiReg = createRegistry(testContainer, contract, {
|
|
661
744
|
handlerRegisteredCallback: (_entry) => {
|
|
@@ -663,6 +746,10 @@ function createInProcApiClient(contract, testContainer, registry) {
|
|
|
663
746
|
middlewareHandlerRegisteredCallback: (_entry) => {
|
|
664
747
|
}
|
|
665
748
|
});
|
|
749
|
+
registry._middlewareRegistry.list.forEach((mwEntry) => {
|
|
750
|
+
testApiReg._middlewareRegistry.register(mwEntry);
|
|
751
|
+
});
|
|
752
|
+
const mwReg = testApiReg._middlewareRegistry;
|
|
666
753
|
flatListAllRegistryEntries(registry).forEach((entry) => {
|
|
667
754
|
if (!entry.handler) {
|
|
668
755
|
return;
|
|
@@ -671,12 +758,17 @@ function createInProcApiClient(contract, testContainer, registry) {
|
|
|
671
758
|
rt.inject(entry.injection).register(entry.handler);
|
|
672
759
|
});
|
|
673
760
|
const client = createClient(contract, async (input) => {
|
|
761
|
+
const diScope = testContainer.createScope();
|
|
762
|
+
const haltExecResponse = await execMiddleware(diScope, mwReg.list, input);
|
|
763
|
+
if (haltExecResponse) {
|
|
764
|
+
return haltExecResponse;
|
|
765
|
+
}
|
|
674
766
|
const rt = route(testApiReg, `${input.method} ${input.genericPath}`);
|
|
675
|
-
const result = rt.trigger({
|
|
767
|
+
const result = await rt.trigger(diScope, {
|
|
676
768
|
headers: input.headers,
|
|
677
769
|
pathParams: input.pathParams,
|
|
678
|
-
body: input.body
|
|
679
|
-
query: input.query
|
|
770
|
+
body: input.body,
|
|
771
|
+
query: input.query
|
|
680
772
|
});
|
|
681
773
|
return result;
|
|
682
774
|
});
|
|
@@ -687,6 +779,8 @@ exports.ApiClient = ApiClient;
|
|
|
687
779
|
exports.ApiContract = ApiContract;
|
|
688
780
|
exports.ApiHandlersRegistry = ApiHandlersRegistry;
|
|
689
781
|
exports.DIContainer = DIContainer;
|
|
782
|
+
exports.DIContainerBase = DIContainerBase;
|
|
783
|
+
exports.DIContainerTestClone = DIContainerTestClone;
|
|
690
784
|
exports.HttpMethodEndpoint = HttpMethodEndpoint;
|
|
691
785
|
exports.HttpMethodEndpointResponse = HttpMethodEndpointResponse;
|
|
692
786
|
exports.HttpStatusCode = HttpStatusCode;
|