@congruent-stack/congruent-api 0.7.0 → 0.10.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 +550 -157
- package/dist/index.d.cts +252 -95
- package/dist/index.d.mts +252 -95
- package/dist/index.mjs +546 -158
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -19,6 +19,11 @@ class HttpMethodEndpoint {
|
|
|
19
19
|
}
|
|
20
20
|
return this._cachedGenericPath;
|
|
21
21
|
}
|
|
22
|
+
createPath(pathParams) {
|
|
23
|
+
return `/${this.pathSegments.map(
|
|
24
|
+
(segment) => segment.startsWith(":") ? pathParams[segment.slice(1)] ?? "?" : segment
|
|
25
|
+
).join("/")}`;
|
|
26
|
+
}
|
|
22
27
|
_method = null;
|
|
23
28
|
get method() {
|
|
24
29
|
return this._method;
|
|
@@ -112,6 +117,7 @@ var HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => {
|
|
|
112
117
|
HttpStatusCode2[HttpStatusCode2["Forbidden_403"] = 403] = "Forbidden_403";
|
|
113
118
|
HttpStatusCode2[HttpStatusCode2["NotFound_404"] = 404] = "NotFound_404";
|
|
114
119
|
HttpStatusCode2[HttpStatusCode2["Conflict_409"] = 409] = "Conflict_409";
|
|
120
|
+
HttpStatusCode2[HttpStatusCode2["UnprocessableEntity_422"] = 422] = "UnprocessableEntity_422";
|
|
115
121
|
HttpStatusCode2[HttpStatusCode2["InternalServerError_500"] = 500] = "InternalServerError_500";
|
|
116
122
|
HttpStatusCode2[HttpStatusCode2["NotImplemented_501"] = 501] = "NotImplemented_501";
|
|
117
123
|
HttpStatusCode2[HttpStatusCode2["BadGateway_502"] = 502] = "BadGateway_502";
|
|
@@ -140,6 +146,9 @@ class MethodEndpointHandlerRegistryEntry {
|
|
|
140
146
|
this._methodEndpoint = methodEndpoint;
|
|
141
147
|
this._dicontainer = dicontainer;
|
|
142
148
|
}
|
|
149
|
+
get genericPath() {
|
|
150
|
+
return this._methodEndpoint.genericPath;
|
|
151
|
+
}
|
|
143
152
|
_handler = null;
|
|
144
153
|
get handler() {
|
|
145
154
|
return this._handler;
|
|
@@ -149,6 +158,7 @@ class MethodEndpointHandlerRegistryEntry {
|
|
|
149
158
|
if (this._onHandlerRegisteredCallback) {
|
|
150
159
|
this._onHandlerRegisteredCallback(this);
|
|
151
160
|
}
|
|
161
|
+
return this;
|
|
152
162
|
}
|
|
153
163
|
_onHandlerRegisteredCallback = null;
|
|
154
164
|
_onHandlerRegistered(callback) {
|
|
@@ -158,7 +168,7 @@ class MethodEndpointHandlerRegistryEntry {
|
|
|
158
168
|
callback(this);
|
|
159
169
|
return this;
|
|
160
170
|
}
|
|
161
|
-
_injection = (
|
|
171
|
+
_injection = (_diScope) => ({});
|
|
162
172
|
get injection() {
|
|
163
173
|
return this._injection;
|
|
164
174
|
}
|
|
@@ -166,61 +176,152 @@ class MethodEndpointHandlerRegistryEntry {
|
|
|
166
176
|
this._injection = injection;
|
|
167
177
|
return this;
|
|
168
178
|
}
|
|
169
|
-
|
|
179
|
+
_decoratorFactories = [];
|
|
180
|
+
get decoratorFactories() {
|
|
181
|
+
return this._decoratorFactories;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
*
|
|
185
|
+
* @param decoratorFactory must be a function that takes exactly the DI scope type and returns an instance of a class that implements IEndpointHandlerDecorator
|
|
186
|
+
* @returns this
|
|
187
|
+
*
|
|
188
|
+
* Initially, the method was defined as:
|
|
189
|
+
* ```ts
|
|
190
|
+
* decorate<
|
|
191
|
+
* TDecoratorSchemas extends IDecoratorHandlerSchemas,
|
|
192
|
+
* TDecorator extends IEndpointHandlerDecorator<TDecoratorSchemas>
|
|
193
|
+
* > (
|
|
194
|
+
* decoratorFactory: IEndpointHandlerDecoratorFactory<TDecoratorSchemas, TDIContainer, TDecorator>
|
|
195
|
+
* ): this {
|
|
196
|
+
* this._decoratorFactories.push(decoratorFactory);
|
|
197
|
+
* return this;
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* and the type IEndpointHandlerDecoratorFactory was defined as:
|
|
202
|
+
* ```ts
|
|
203
|
+
* type IEndpointHandlerDecoratorFactory<
|
|
204
|
+
* TDecoratorSchemas extends IDecoratorHandlerSchemas,
|
|
205
|
+
* TDIContainer extends DIContainer,
|
|
206
|
+
* TDecorator extends IEndpointHandlerDecorator<TDecoratorSchemas>
|
|
207
|
+
* > = (diScope: ReturnType<TDIContainer['createScope']>) => TDecorator;
|
|
208
|
+
* ```
|
|
209
|
+
*
|
|
210
|
+
* However, TypeScript was incorrectly inferring the types when using the 'decorate' method.
|
|
211
|
+
* The end developer would have had to explicitly provide the generic types, which is not ideal.
|
|
212
|
+
*
|
|
213
|
+
* With the current definition, TypeScript can infer the types from the decoratorFactory parameter,
|
|
214
|
+
* making it easier to use.
|
|
215
|
+
*/
|
|
216
|
+
decorate(decoratorFactory, decoratingArgs) {
|
|
217
|
+
this._decoratorFactories.push((scope) => decoratorFactory(scope, decoratingArgs));
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
decorateWith(decoratorStaticMethodFactory, decoratingArgs) {
|
|
221
|
+
this._decoratorFactories.push((scope) => decoratorStaticMethodFactory.create(scope, decoratingArgs));
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
async trigger(diScope, requestObject) {
|
|
225
|
+
return this.triggerNoStaticTypeCheck(diScope, requestObject, { originalRequest: requestObject });
|
|
226
|
+
}
|
|
227
|
+
async exec(injected, requestObject) {
|
|
170
228
|
if (!this._handler) {
|
|
171
229
|
throw new Error("Handler not set for this endpoint");
|
|
172
230
|
}
|
|
173
231
|
let badRequestResponse = null;
|
|
174
|
-
const headers = parseRequestDefinitionField(this._methodEndpoint.definition, "headers",
|
|
232
|
+
const headers = parseRequestDefinitionField(this._methodEndpoint.definition, "headers", requestObject);
|
|
175
233
|
if (isHttpResponseObject(headers)) {
|
|
176
234
|
badRequestResponse = headers;
|
|
177
235
|
return badRequestResponse;
|
|
178
236
|
}
|
|
179
|
-
const query = parseRequestDefinitionField(this._methodEndpoint.definition, "query",
|
|
237
|
+
const query = parseRequestDefinitionField(this._methodEndpoint.definition, "query", requestObject);
|
|
180
238
|
if (isHttpResponseObject(query)) {
|
|
181
239
|
badRequestResponse = query;
|
|
182
240
|
return badRequestResponse;
|
|
183
241
|
}
|
|
184
|
-
const body = parseRequestDefinitionField(this._methodEndpoint.definition, "body",
|
|
242
|
+
const body = parseRequestDefinitionField(this._methodEndpoint.definition, "body", requestObject);
|
|
185
243
|
if (isHttpResponseObject(body)) {
|
|
186
244
|
badRequestResponse = body;
|
|
187
245
|
return badRequestResponse;
|
|
188
246
|
}
|
|
189
|
-
const path =
|
|
190
|
-
(segment) => segment.startsWith(":") ? data.pathParams[segment.slice(1)] ?? "?" : segment
|
|
191
|
-
).join("/")}`;
|
|
247
|
+
const path = this._methodEndpoint.createPath(requestObject.pathParams);
|
|
192
248
|
return await this._handler({
|
|
193
249
|
method: this._methodEndpoint.method,
|
|
194
250
|
path,
|
|
195
251
|
genericPath: this._methodEndpoint.genericPath,
|
|
196
252
|
pathSegments: this._methodEndpoint.pathSegments,
|
|
197
253
|
headers,
|
|
198
|
-
pathParams:
|
|
254
|
+
pathParams: requestObject.pathParams,
|
|
199
255
|
query,
|
|
200
|
-
body
|
|
201
|
-
|
|
202
|
-
|
|
256
|
+
body
|
|
257
|
+
}, injected);
|
|
258
|
+
}
|
|
259
|
+
async triggerNoStaticTypeCheck(diScope, requestObject, context) {
|
|
260
|
+
if (!this._handler) {
|
|
261
|
+
throw new Error("Handler not set for this endpoint");
|
|
262
|
+
}
|
|
263
|
+
let badRequestResponse = null;
|
|
264
|
+
const headers = parseRequestDefinitionField(this._methodEndpoint.definition, "headers", requestObject);
|
|
265
|
+
if (isHttpResponseObject(headers)) {
|
|
266
|
+
badRequestResponse = headers;
|
|
267
|
+
return badRequestResponse;
|
|
268
|
+
}
|
|
269
|
+
const query = parseRequestDefinitionField(this._methodEndpoint.definition, "query", requestObject);
|
|
270
|
+
if (isHttpResponseObject(query)) {
|
|
271
|
+
badRequestResponse = query;
|
|
272
|
+
return badRequestResponse;
|
|
273
|
+
}
|
|
274
|
+
const body = parseRequestDefinitionField(this._methodEndpoint.definition, "body", requestObject);
|
|
275
|
+
if (isHttpResponseObject(body)) {
|
|
276
|
+
badRequestResponse = body;
|
|
277
|
+
return badRequestResponse;
|
|
278
|
+
}
|
|
279
|
+
const path = this._methodEndpoint.createPath(requestObject.pathParams);
|
|
280
|
+
Object.assign(context, this._injection(diScope));
|
|
281
|
+
return await this._handler({
|
|
282
|
+
method: this._methodEndpoint.method,
|
|
283
|
+
path,
|
|
284
|
+
genericPath: this._methodEndpoint.genericPath,
|
|
285
|
+
pathSegments: this._methodEndpoint.pathSegments,
|
|
286
|
+
headers,
|
|
287
|
+
pathParams: requestObject.pathParams,
|
|
288
|
+
query,
|
|
289
|
+
body
|
|
290
|
+
}, context);
|
|
203
291
|
}
|
|
204
292
|
}
|
|
205
|
-
function parseRequestDefinitionField(definition, key,
|
|
293
|
+
function parseRequestDefinitionField(definition, key, requestObject) {
|
|
206
294
|
if (definition[key]) {
|
|
207
|
-
if (!(key in
|
|
208
|
-
|
|
295
|
+
if (!(key in requestObject) || requestObject[key] === null || requestObject[key] === void 0) {
|
|
296
|
+
const result2 = definition[key].safeParse(requestObject[key]);
|
|
297
|
+
if (!result2.success) {
|
|
298
|
+
switch (definition[key].type) {
|
|
299
|
+
case "optional":
|
|
300
|
+
if (requestObject[key] === null) {
|
|
301
|
+
return void 0;
|
|
302
|
+
}
|
|
303
|
+
break;
|
|
304
|
+
case "nullable":
|
|
305
|
+
if (requestObject[key] === void 0) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
209
310
|
return {
|
|
210
311
|
code: HttpStatusCode.BadRequest_400,
|
|
211
312
|
body: `'${key}' is required for this endpoint` + (key === "body" ? ", { 'Content-Type': 'application/json' } header might be missing" : "")
|
|
212
313
|
};
|
|
213
314
|
}
|
|
214
|
-
return
|
|
315
|
+
return result2.data;
|
|
215
316
|
}
|
|
216
|
-
const result = definition[key].safeParse(
|
|
317
|
+
const result = definition[key].safeParse(requestObject[key]);
|
|
217
318
|
if (!result.success) {
|
|
218
319
|
return {
|
|
219
320
|
code: HttpStatusCode.BadRequest_400,
|
|
220
321
|
body: result.error.issues
|
|
221
322
|
};
|
|
222
323
|
}
|
|
223
|
-
return result.data
|
|
324
|
+
return result.data;
|
|
224
325
|
}
|
|
225
326
|
return null;
|
|
226
327
|
}
|
|
@@ -235,11 +336,33 @@ function middleware(apiReg, path) {
|
|
|
235
336
|
}
|
|
236
337
|
class MiddlewareHandlersRegistryEntryInternal {
|
|
237
338
|
_dicontainer;
|
|
339
|
+
get dicontainer() {
|
|
340
|
+
return this._dicontainer;
|
|
341
|
+
}
|
|
238
342
|
_middlewareGenericPath;
|
|
239
343
|
get genericPath() {
|
|
240
344
|
return this._middlewareGenericPath;
|
|
241
345
|
}
|
|
242
|
-
|
|
346
|
+
_middlewarePathSegments;
|
|
347
|
+
get pathSegments() {
|
|
348
|
+
return this._middlewarePathSegments;
|
|
349
|
+
}
|
|
350
|
+
_middlewareMethod;
|
|
351
|
+
get method() {
|
|
352
|
+
return this._middlewareMethod;
|
|
353
|
+
}
|
|
354
|
+
_middlewareSchemas;
|
|
355
|
+
get middlewareSchemas() {
|
|
356
|
+
return this._middlewareSchemas;
|
|
357
|
+
}
|
|
358
|
+
_handler;
|
|
359
|
+
constructor(diContainer, middlewarePath, middlewareSchemas, decoratorFactories, injection, handler) {
|
|
360
|
+
this._dicontainer = diContainer;
|
|
361
|
+
this._middlewareGenericPath = middlewarePath;
|
|
362
|
+
this._middlewareSchemas = middlewareSchemas;
|
|
363
|
+
this._decoratorFactories.push(...decoratorFactories);
|
|
364
|
+
this._injection = injection;
|
|
365
|
+
this._handler = handler;
|
|
243
366
|
const splitResult = this._middlewareGenericPath.split(" ");
|
|
244
367
|
let method = "";
|
|
245
368
|
let pathSegments = [];
|
|
@@ -250,54 +373,56 @@ class MiddlewareHandlersRegistryEntryInternal {
|
|
|
250
373
|
}
|
|
251
374
|
pathSegments = splitResult[1].split("/").map((segment) => segment.trim()).filter((segment) => segment !== "");
|
|
252
375
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
pathSegments
|
|
256
|
-
};
|
|
376
|
+
this._middlewareMethod = method;
|
|
377
|
+
this._middlewarePathSegments = pathSegments;
|
|
257
378
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
this._dicontainer = diContainer;
|
|
262
|
-
this._middlewareGenericPath = middlewarePath;
|
|
263
|
-
this._inputSchemas = inputSchemas;
|
|
264
|
-
this._injection = injection;
|
|
265
|
-
this._handler = handler;
|
|
379
|
+
_decoratorFactories = [];
|
|
380
|
+
get decoratorFactories() {
|
|
381
|
+
return this._decoratorFactories;
|
|
266
382
|
}
|
|
267
383
|
_injection = (_dicontainer) => ({});
|
|
268
|
-
async trigger(
|
|
384
|
+
async trigger(diScope, requestObject, context) {
|
|
385
|
+
return this.triggerNoStaticTypeCheck(diScope, requestObject, context);
|
|
386
|
+
}
|
|
387
|
+
async triggerNoStaticTypeCheck(diScope, requestObject, context) {
|
|
269
388
|
let badRequestResponse = null;
|
|
270
|
-
const headers = middlewareParseRequestDefinitionField(this.
|
|
389
|
+
const headers = middlewareParseRequestDefinitionField(this._middlewareSchemas, "headers", requestObject);
|
|
271
390
|
if (isHttpResponseObject(headers)) {
|
|
272
391
|
badRequestResponse = headers;
|
|
273
392
|
return badRequestResponse;
|
|
274
393
|
}
|
|
275
|
-
const query = middlewareParseRequestDefinitionField(this.
|
|
394
|
+
const query = middlewareParseRequestDefinitionField(this._middlewareSchemas, "query", requestObject);
|
|
276
395
|
if (isHttpResponseObject(query)) {
|
|
277
396
|
badRequestResponse = query;
|
|
278
397
|
return badRequestResponse;
|
|
279
398
|
}
|
|
280
|
-
const body = middlewareParseRequestDefinitionField(this.
|
|
399
|
+
const body = middlewareParseRequestDefinitionField(this._middlewareSchemas, "body", requestObject);
|
|
281
400
|
if (isHttpResponseObject(body)) {
|
|
282
401
|
badRequestResponse = body;
|
|
283
402
|
return badRequestResponse;
|
|
284
403
|
}
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
404
|
+
const path = this.createPath(requestObject.pathParams);
|
|
405
|
+
Object.assign(context, this._injection(diScope));
|
|
406
|
+
return await this._handler(
|
|
407
|
+
{
|
|
408
|
+
method: this.method,
|
|
409
|
+
// TODO: might be empty, as middleware can be registered with path only, without method
|
|
410
|
+
path,
|
|
411
|
+
genericPath: this.genericPath,
|
|
412
|
+
pathSegments: this.pathSegments,
|
|
413
|
+
headers,
|
|
414
|
+
pathParams: requestObject.pathParams,
|
|
415
|
+
query,
|
|
416
|
+
body
|
|
417
|
+
},
|
|
418
|
+
context
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
createPath(pathParams) {
|
|
422
|
+
const path = `/${this.pathSegments.map(
|
|
423
|
+
(segment) => segment.startsWith(":") ? pathParams[segment.slice(1)] ?? "?" : segment
|
|
288
424
|
).join("/")}`;
|
|
289
|
-
return
|
|
290
|
-
method,
|
|
291
|
-
// TODO: might be empty, as middleware can be registered with path only, without method, possible fix: take it from express.request.method
|
|
292
|
-
path,
|
|
293
|
-
genericPath: this.genericPath,
|
|
294
|
-
pathSegments,
|
|
295
|
-
headers,
|
|
296
|
-
pathParams: data.pathParams,
|
|
297
|
-
query,
|
|
298
|
-
body,
|
|
299
|
-
injected: this._injection(this._dicontainer.createScope())
|
|
300
|
-
}, next);
|
|
425
|
+
return path;
|
|
301
426
|
}
|
|
302
427
|
}
|
|
303
428
|
class MiddlewareHandlersRegistryEntry {
|
|
@@ -307,7 +432,7 @@ class MiddlewareHandlersRegistryEntry {
|
|
|
307
432
|
this._registry = registry;
|
|
308
433
|
this._path = path;
|
|
309
434
|
}
|
|
310
|
-
_injection = (
|
|
435
|
+
_injection = (_diScope) => ({});
|
|
311
436
|
get injection() {
|
|
312
437
|
return this._injection;
|
|
313
438
|
}
|
|
@@ -315,16 +440,62 @@ class MiddlewareHandlersRegistryEntry {
|
|
|
315
440
|
this._injection = injection;
|
|
316
441
|
return this;
|
|
317
442
|
}
|
|
318
|
-
register(
|
|
443
|
+
register(middlewareSchemas, handler) {
|
|
319
444
|
const internalEntry = new MiddlewareHandlersRegistryEntryInternal(
|
|
320
445
|
this._registry.dicontainer,
|
|
321
446
|
this._path,
|
|
322
|
-
|
|
447
|
+
middlewareSchemas,
|
|
448
|
+
this._decoratorFactories,
|
|
323
449
|
this._injection,
|
|
324
450
|
handler
|
|
325
451
|
);
|
|
326
452
|
this._registry.register(internalEntry);
|
|
327
453
|
}
|
|
454
|
+
_decoratorFactories = [];
|
|
455
|
+
get decoratorFactories() {
|
|
456
|
+
return this._decoratorFactories;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
*
|
|
460
|
+
* @param decoratorFactory must be a function that takes exactly the DI scope type and returns an instance of a class that implements IEndpointHandlerDecorator
|
|
461
|
+
* @returns this
|
|
462
|
+
*
|
|
463
|
+
* Initially, the method was defined as:
|
|
464
|
+
* ```ts
|
|
465
|
+
* decorate<
|
|
466
|
+
* TDecoratorSchemas extends IDecoratorHandlerSchemas,
|
|
467
|
+
* TDecorator extends IEndpointHandlerDecorator<TDecoratorSchemas>
|
|
468
|
+
* > (
|
|
469
|
+
* decoratorFactory: IEndpointHandlerDecoratorFactory<TDecoratorSchemas, TDIContainer, TDecorator>
|
|
470
|
+
* ): this {
|
|
471
|
+
* this._decoratorFactories.push(decoratorFactory);
|
|
472
|
+
* return this;
|
|
473
|
+
* }
|
|
474
|
+
* ```
|
|
475
|
+
*
|
|
476
|
+
* and the type IEndpointHandlerDecoratorFactory was defined as:
|
|
477
|
+
* ```ts
|
|
478
|
+
* type IEndpointHandlerDecoratorFactory<
|
|
479
|
+
* TDecoratorSchemas extends IDecoratorHandlerSchemas,
|
|
480
|
+
* TDIContainer extends DIContainer,
|
|
481
|
+
* TDecorator extends IEndpointHandlerDecorator<TDecoratorSchemas>
|
|
482
|
+
* > = (diScope: ReturnType<TDIContainer['createScope']>) => TDecorator;
|
|
483
|
+
* ```
|
|
484
|
+
*
|
|
485
|
+
* However, TypeScript was incorrectly inferring the types when using the 'decorate' method.
|
|
486
|
+
* The end developer would have had to explicitly provide the generic types, which is not ideal.
|
|
487
|
+
*
|
|
488
|
+
* With the current definition, TypeScript can infer the types from the decoratorFactory parameter,
|
|
489
|
+
* making it easier to use.
|
|
490
|
+
*/
|
|
491
|
+
decorate(decoratorFactory) {
|
|
492
|
+
this._decoratorFactories.push(decoratorFactory);
|
|
493
|
+
return this;
|
|
494
|
+
}
|
|
495
|
+
decorateWith(decoratorStaticMethodFactory) {
|
|
496
|
+
this._decoratorFactories.push(decoratorStaticMethodFactory.create);
|
|
497
|
+
return this;
|
|
498
|
+
}
|
|
328
499
|
}
|
|
329
500
|
class MiddlewareHandlersRegistry {
|
|
330
501
|
dicontainer;
|
|
@@ -332,8 +503,13 @@ class MiddlewareHandlersRegistry {
|
|
|
332
503
|
this.dicontainer = dicontainer;
|
|
333
504
|
this._onHandlerRegisteredCallback = callback;
|
|
334
505
|
}
|
|
506
|
+
_list = [];
|
|
507
|
+
get list() {
|
|
508
|
+
return this._list;
|
|
509
|
+
}
|
|
335
510
|
register(entry) {
|
|
336
511
|
if (this._onHandlerRegisteredCallback) {
|
|
512
|
+
this._list.push(entry);
|
|
337
513
|
this._onHandlerRegisteredCallback(entry);
|
|
338
514
|
}
|
|
339
515
|
}
|
|
@@ -342,25 +518,38 @@ class MiddlewareHandlersRegistry {
|
|
|
342
518
|
this._onHandlerRegisteredCallback = callback;
|
|
343
519
|
}
|
|
344
520
|
}
|
|
345
|
-
function middlewareParseRequestDefinitionField(
|
|
346
|
-
if (
|
|
347
|
-
if (!(key in
|
|
348
|
-
|
|
521
|
+
function middlewareParseRequestDefinitionField(middlewareSchemas, key, requestObject) {
|
|
522
|
+
if (middlewareSchemas[key]) {
|
|
523
|
+
if (!(key in requestObject) || requestObject[key] === null || requestObject[key] === void 0) {
|
|
524
|
+
const result2 = middlewareSchemas[key].safeParse(requestObject[key]);
|
|
525
|
+
if (!result2.success) {
|
|
526
|
+
switch (middlewareSchemas[key].type) {
|
|
527
|
+
case "optional":
|
|
528
|
+
if (requestObject[key] === null) {
|
|
529
|
+
return void 0;
|
|
530
|
+
}
|
|
531
|
+
break;
|
|
532
|
+
case "nullable":
|
|
533
|
+
if (requestObject[key] === void 0) {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
349
538
|
return {
|
|
350
539
|
code: HttpStatusCode.BadRequest_400,
|
|
351
540
|
body: `'${key}' is required for this endpoint` + (key === "body" ? ", { 'Content-Type': 'application/json' } header might be missing" : "")
|
|
352
541
|
};
|
|
353
542
|
}
|
|
354
|
-
return
|
|
543
|
+
return result2.data;
|
|
355
544
|
}
|
|
356
|
-
const result =
|
|
545
|
+
const result = middlewareSchemas[key].safeParse(requestObject[key]);
|
|
357
546
|
if (!result.success) {
|
|
358
547
|
return {
|
|
359
548
|
code: HttpStatusCode.BadRequest_400,
|
|
360
549
|
body: result.error.issues
|
|
361
550
|
};
|
|
362
551
|
}
|
|
363
|
-
return result.data
|
|
552
|
+
return result.data;
|
|
364
553
|
}
|
|
365
554
|
return null;
|
|
366
555
|
}
|
|
@@ -484,6 +673,41 @@ function registerEntryHandler(endpointEntry, handler) {
|
|
|
484
673
|
endpointEntry.register(handler);
|
|
485
674
|
}
|
|
486
675
|
|
|
676
|
+
async function execHandlerChain(diScope, allHandlerEntries, input) {
|
|
677
|
+
const queue = [...allHandlerEntries];
|
|
678
|
+
let response = void 0;
|
|
679
|
+
const next = async () => {
|
|
680
|
+
if (response) {
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
const current = queue.shift();
|
|
684
|
+
if (!current) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (!input.genericPath.startsWith(current.genericPath)) {
|
|
688
|
+
await next();
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
const currResponse = await current.triggerNoStaticTypeCheck(
|
|
692
|
+
diScope,
|
|
693
|
+
input,
|
|
694
|
+
{
|
|
695
|
+
next
|
|
696
|
+
}
|
|
697
|
+
);
|
|
698
|
+
if (response) {
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
if (currResponse) {
|
|
702
|
+
response = currResponse;
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
await next();
|
|
706
|
+
};
|
|
707
|
+
await next();
|
|
708
|
+
return response;
|
|
709
|
+
}
|
|
710
|
+
|
|
487
711
|
function partialPathString(_apiReg, path) {
|
|
488
712
|
return path;
|
|
489
713
|
}
|
|
@@ -528,12 +752,12 @@ class InnerApiClient {
|
|
|
528
752
|
delete currObj[key];
|
|
529
753
|
InnerApiClient._initialize(client, val, clientGenericHandler);
|
|
530
754
|
} else if (val instanceof HttpMethodEndpoint) {
|
|
531
|
-
currObj[key] = (
|
|
755
|
+
currObj[key] = (requestObject) => {
|
|
532
756
|
const pathParams = { ...client.__CONTEXT__.pathParameters };
|
|
533
757
|
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",
|
|
758
|
+
const headers = clientParseRequestDefinitionField(val.definition, "headers", requestObject);
|
|
759
|
+
const query = clientParseRequestDefinitionField(val.definition, "query", requestObject);
|
|
760
|
+
const body = clientParseRequestDefinitionField(val.definition, "body", requestObject);
|
|
537
761
|
const path = `/${val.pathSegments.map(
|
|
538
762
|
(segment) => segment.startsWith(":") ? pathParams[segment.slice(1)] ?? "?" : segment
|
|
539
763
|
).join("/")}`;
|
|
@@ -555,138 +779,304 @@ class InnerApiClient {
|
|
|
555
779
|
}
|
|
556
780
|
}
|
|
557
781
|
const ApiClient = InnerApiClient;
|
|
558
|
-
function clientParseRequestDefinitionField(definition, key,
|
|
782
|
+
function clientParseRequestDefinitionField(definition, key, requestObject) {
|
|
559
783
|
if (definition[key]) {
|
|
560
|
-
if (!(key in
|
|
561
|
-
|
|
562
|
-
|
|
784
|
+
if (!(key in requestObject) || requestObject[key] === null || requestObject[key] === void 0) {
|
|
785
|
+
const result2 = definition[key].safeParse(requestObject[key]);
|
|
786
|
+
if (!result2.success) {
|
|
787
|
+
switch (definition[key].type) {
|
|
788
|
+
case "optional":
|
|
789
|
+
if (requestObject[key] === null) {
|
|
790
|
+
return void 0;
|
|
791
|
+
}
|
|
792
|
+
break;
|
|
793
|
+
case "nullable":
|
|
794
|
+
if (requestObject[key] === void 0) {
|
|
795
|
+
return null;
|
|
796
|
+
}
|
|
797
|
+
break;
|
|
798
|
+
}
|
|
799
|
+
throw new Error(`'${key}' is required for this endpoint`);
|
|
563
800
|
}
|
|
564
|
-
return
|
|
801
|
+
return result2.data;
|
|
565
802
|
}
|
|
566
|
-
const result = definition[key].safeParse(
|
|
803
|
+
const result = definition[key].safeParse(requestObject[key]);
|
|
567
804
|
if (!result.success) {
|
|
568
805
|
throw new Error(`Validation for '${key}' failed`, { cause: result.error });
|
|
569
806
|
}
|
|
570
|
-
return result.data
|
|
807
|
+
return result.data;
|
|
571
808
|
}
|
|
572
809
|
return null;
|
|
573
810
|
}
|
|
574
811
|
|
|
575
|
-
class
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
812
|
+
class DIContainerBase {
|
|
813
|
+
_map = /* @__PURE__ */ new Map();
|
|
814
|
+
_singletonInstances = /* @__PURE__ */ new Map();
|
|
815
|
+
createScope() {
|
|
816
|
+
const proxy = new Proxy({
|
|
817
|
+
_map: this._map,
|
|
818
|
+
_singletonInstances: this._singletonInstances,
|
|
819
|
+
_scopedInstances: /* @__PURE__ */ new Map(),
|
|
820
|
+
_isBuildingSingleton: false
|
|
821
|
+
}, {
|
|
822
|
+
get: (target, prop) => {
|
|
823
|
+
if (prop.startsWith("get")) {
|
|
824
|
+
const serviceName = prop.slice(3);
|
|
825
|
+
if (target._map.has(serviceName)) {
|
|
826
|
+
const entry = target._map.get(serviceName);
|
|
827
|
+
switch (entry.lifetime) {
|
|
828
|
+
case "transient":
|
|
829
|
+
return () => {
|
|
830
|
+
if (target._isBuildingSingleton) {
|
|
831
|
+
throw new Error(`Cannot resolve transient service '${serviceName}' while building a singleton`);
|
|
832
|
+
}
|
|
833
|
+
return entry.factory(proxy);
|
|
834
|
+
};
|
|
835
|
+
case "scoped":
|
|
836
|
+
return () => {
|
|
837
|
+
if (target._isBuildingSingleton) {
|
|
838
|
+
throw new Error(`Cannot resolve scoped service '${serviceName}' while building a singleton`);
|
|
839
|
+
}
|
|
840
|
+
if (!target._scopedInstances.has(serviceName)) {
|
|
841
|
+
const instance = entry.factory(proxy);
|
|
842
|
+
target._scopedInstances.set(serviceName, instance);
|
|
843
|
+
}
|
|
844
|
+
return target._scopedInstances.get(serviceName);
|
|
845
|
+
};
|
|
846
|
+
case "singleton":
|
|
847
|
+
return () => {
|
|
848
|
+
if (!target._singletonInstances.has(serviceName)) {
|
|
849
|
+
target._isBuildingSingleton = true;
|
|
850
|
+
try {
|
|
851
|
+
const instance = entry.factory(proxy);
|
|
852
|
+
target._singletonInstances.set(serviceName, instance);
|
|
853
|
+
} finally {
|
|
854
|
+
target._isBuildingSingleton = false;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
return target._singletonInstances.get(serviceName);
|
|
858
|
+
};
|
|
859
|
+
default:
|
|
860
|
+
throw new Error(`Unsupported lifetime: ${entry.lifetime}`);
|
|
861
|
+
}
|
|
591
862
|
} else {
|
|
592
863
|
throw new Error(`Service not registered: ${serviceName}`);
|
|
593
864
|
}
|
|
594
865
|
}
|
|
595
|
-
|
|
866
|
+
throw new Error(`Property access denied by Proxy: ${String(prop)}`);
|
|
596
867
|
}
|
|
597
868
|
});
|
|
598
|
-
return
|
|
869
|
+
return proxy;
|
|
599
870
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
this.
|
|
871
|
+
}
|
|
872
|
+
class DIContainer extends DIContainerBase {
|
|
873
|
+
register(serviceNameCapitalizedLiteral, factory, lifetime) {
|
|
874
|
+
const entry = { factory, lifetime };
|
|
875
|
+
this._map.set(serviceNameCapitalizedLiteral, entry);
|
|
605
876
|
return this;
|
|
606
877
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
878
|
+
createTestClone() {
|
|
879
|
+
return new DIContainerTestClone(this);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
class DIContainerTestClone extends DIContainerBase {
|
|
883
|
+
constructor(original) {
|
|
884
|
+
super();
|
|
885
|
+
original["_map"].forEach((value, key) => {
|
|
886
|
+
this._map.set(key, {
|
|
887
|
+
factory: (_scope) => {
|
|
888
|
+
throw new Error(`Service registration not overridden: ${key}`);
|
|
889
|
+
},
|
|
890
|
+
lifetime: value.lifetime
|
|
891
|
+
});
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
override(serviceNameLiteral, factory) {
|
|
895
|
+
const registration = this._map.get(serviceNameLiteral);
|
|
612
896
|
if (!registration) {
|
|
613
|
-
throw new Error(`Service not registered: ${
|
|
897
|
+
throw new Error(`Service not registered: ${serviceNameLiteral}`);
|
|
614
898
|
}
|
|
615
|
-
|
|
616
|
-
|
|
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);
|
|
899
|
+
this._map.set(serviceNameLiteral, { factory, lifetime: registration.lifetime });
|
|
900
|
+
return this;
|
|
623
901
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
async function triggerEndpointDecoratorNoStaticTypeCheck(endpoint, decorator, requestObject, context) {
|
|
905
|
+
let badRequestResponse = null;
|
|
906
|
+
const headers = decoratorParseRequestDefinitionField(endpoint.definition, "headers", requestObject);
|
|
907
|
+
if (isHttpResponseObject(headers)) {
|
|
908
|
+
badRequestResponse = headers;
|
|
909
|
+
return badRequestResponse;
|
|
910
|
+
}
|
|
911
|
+
const query = decoratorParseRequestDefinitionField(endpoint.definition, "query", requestObject);
|
|
912
|
+
if (isHttpResponseObject(query)) {
|
|
913
|
+
badRequestResponse = query;
|
|
914
|
+
return badRequestResponse;
|
|
915
|
+
}
|
|
916
|
+
const body = decoratorParseRequestDefinitionField(endpoint.definition, "body", requestObject);
|
|
917
|
+
if (isHttpResponseObject(body)) {
|
|
918
|
+
badRequestResponse = body;
|
|
919
|
+
return badRequestResponse;
|
|
920
|
+
}
|
|
921
|
+
const path = endpoint.createPath(requestObject.pathParams);
|
|
922
|
+
return decorator.handle({
|
|
923
|
+
...requestObject,
|
|
924
|
+
method: endpoint.method,
|
|
925
|
+
genericPath: endpoint.genericPath,
|
|
926
|
+
path,
|
|
927
|
+
pathSegments: endpoint.pathSegments
|
|
928
|
+
}, context);
|
|
929
|
+
}
|
|
930
|
+
async function triggerMiddlewareDecoratorNoStaticTypeCheck(middlewareEntry, decorator, requestObject, context) {
|
|
931
|
+
let badRequestResponse = null;
|
|
932
|
+
const headers = decoratorParseRequestDefinitionField(middlewareEntry.middlewareSchemas, "headers", requestObject);
|
|
933
|
+
if (isHttpResponseObject(headers)) {
|
|
934
|
+
badRequestResponse = headers;
|
|
935
|
+
return badRequestResponse;
|
|
936
|
+
}
|
|
937
|
+
const query = decoratorParseRequestDefinitionField(middlewareEntry.middlewareSchemas, "query", requestObject);
|
|
938
|
+
if (isHttpResponseObject(query)) {
|
|
939
|
+
badRequestResponse = query;
|
|
940
|
+
return badRequestResponse;
|
|
941
|
+
}
|
|
942
|
+
const body = decoratorParseRequestDefinitionField(middlewareEntry.middlewareSchemas, "body", requestObject);
|
|
943
|
+
if (isHttpResponseObject(body)) {
|
|
944
|
+
badRequestResponse = body;
|
|
945
|
+
return badRequestResponse;
|
|
946
|
+
}
|
|
947
|
+
const path = middlewareEntry.createPath(requestObject.pathParams);
|
|
948
|
+
return decorator.handle({
|
|
949
|
+
...requestObject,
|
|
950
|
+
method: middlewareEntry.method,
|
|
951
|
+
// TODO: might be empty, as middleware can be registered with path only, without method
|
|
952
|
+
genericPath: middlewareEntry.genericPath,
|
|
953
|
+
path,
|
|
954
|
+
pathSegments: middlewareEntry.pathSegments
|
|
955
|
+
}, context);
|
|
956
|
+
}
|
|
957
|
+
function decoratorParseRequestDefinitionField(decoratorSchemas, key, requestObject) {
|
|
958
|
+
if (decoratorSchemas[key]) {
|
|
959
|
+
if (!(key in requestObject) || requestObject[key] === null || requestObject[key] === void 0) {
|
|
960
|
+
const result2 = decoratorSchemas[key].safeParse(requestObject[key]);
|
|
961
|
+
if (!result2.success) {
|
|
962
|
+
switch (decoratorSchemas[key].type) {
|
|
963
|
+
case "optional":
|
|
964
|
+
if (requestObject[key] === null) {
|
|
965
|
+
return void 0;
|
|
966
|
+
}
|
|
967
|
+
break;
|
|
968
|
+
case "nullable":
|
|
969
|
+
if (requestObject[key] === void 0) {
|
|
970
|
+
return null;
|
|
971
|
+
}
|
|
972
|
+
break;
|
|
648
973
|
}
|
|
649
|
-
return
|
|
974
|
+
return {
|
|
975
|
+
code: HttpStatusCode.BadRequest_400,
|
|
976
|
+
body: `'${key}' is required for this endpoint` + (key === "body" ? ", { 'Content-Type': 'application/json' } header might be missing" : "")
|
|
977
|
+
};
|
|
650
978
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
979
|
+
return result2.data;
|
|
980
|
+
}
|
|
981
|
+
const result = decoratorSchemas[key].safeParse(requestObject[key]);
|
|
982
|
+
if (!result.success) {
|
|
983
|
+
return {
|
|
984
|
+
code: HttpStatusCode.BadRequest_400,
|
|
985
|
+
body: result.error.issues
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
return result.data;
|
|
656
989
|
}
|
|
990
|
+
return null;
|
|
657
991
|
}
|
|
658
992
|
|
|
659
|
-
function createInProcApiClient(contract, testContainer, registry) {
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
993
|
+
function createInProcApiClient(contract, testContainer, registry, options) {
|
|
994
|
+
const mwHandlers = [];
|
|
995
|
+
const mwReg = registry._middlewareRegistry;
|
|
996
|
+
const mwNdx = 0;
|
|
997
|
+
for (const mwEntry of mwReg.list) {
|
|
998
|
+
if (!options?.filterMiddleware) {
|
|
999
|
+
addMiddlewareDecorators(mwHandlers, mwEntry);
|
|
1000
|
+
mwHandlers.push(mwEntry);
|
|
1001
|
+
continue;
|
|
664
1002
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
return;
|
|
1003
|
+
const isIncluded = options.filterMiddleware(mwEntry.genericPath, mwNdx);
|
|
1004
|
+
if (!isIncluded) {
|
|
1005
|
+
continue;
|
|
669
1006
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
}
|
|
1007
|
+
addMiddlewareDecorators(mwHandlers, mwEntry);
|
|
1008
|
+
mwHandlers.push(mwEntry);
|
|
1009
|
+
}
|
|
673
1010
|
const client = createClient(contract, async (input) => {
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
1011
|
+
if (options?.enhanceRequest) {
|
|
1012
|
+
input = options.enhanceRequest(input);
|
|
1013
|
+
}
|
|
1014
|
+
const diScope = testContainer.createScope();
|
|
1015
|
+
const allHandlerEntries = [...mwHandlers];
|
|
1016
|
+
const endpointHandlerEntry = route(registry, `${input.method} ${input.genericPath}`);
|
|
1017
|
+
if (!endpointHandlerEntry.handler) {
|
|
1018
|
+
throw new Error(`No handler registered for ${input.method} ${input.genericPath}`);
|
|
1019
|
+
}
|
|
1020
|
+
endpointHandlerEntry.decoratorFactories.forEach((decoratorFactory) => {
|
|
1021
|
+
allHandlerEntries.push({
|
|
1022
|
+
genericPath: endpointHandlerEntry.genericPath,
|
|
1023
|
+
triggerNoStaticTypeCheck: async (diScope2, requestObject, context) => {
|
|
1024
|
+
const decorator = decoratorFactory(diScope2);
|
|
1025
|
+
return await triggerEndpointDecoratorNoStaticTypeCheck(
|
|
1026
|
+
endpointHandlerEntry.methodEndpoint,
|
|
1027
|
+
decorator,
|
|
1028
|
+
requestObject,
|
|
1029
|
+
context
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
});
|
|
680
1033
|
});
|
|
681
|
-
|
|
1034
|
+
if (options?.mockEndpointResponse) {
|
|
1035
|
+
const mockResponse = options.mockEndpointResponse(input.genericPath, input.method, diScope);
|
|
1036
|
+
if (mockResponse) {
|
|
1037
|
+
allHandlerEntries.push({
|
|
1038
|
+
genericPath: endpointHandlerEntry.genericPath,
|
|
1039
|
+
triggerNoStaticTypeCheck: async (_diScope, _requestObject, _next) => {
|
|
1040
|
+
return mockResponse;
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
} else {
|
|
1044
|
+
allHandlerEntries.push(endpointHandlerEntry);
|
|
1045
|
+
}
|
|
1046
|
+
} else {
|
|
1047
|
+
allHandlerEntries.push(endpointHandlerEntry);
|
|
1048
|
+
}
|
|
1049
|
+
const response = await execHandlerChain(diScope, allHandlerEntries, input);
|
|
1050
|
+
if (!response) {
|
|
1051
|
+
throw new Error(`No response from ${input.method} ${input.genericPath}`);
|
|
1052
|
+
}
|
|
1053
|
+
return response;
|
|
682
1054
|
});
|
|
683
1055
|
return client;
|
|
684
1056
|
}
|
|
1057
|
+
function addMiddlewareDecorators(mwHandlers, mwEntry) {
|
|
1058
|
+
mwEntry.decoratorFactories.forEach((decoratorFactory) => {
|
|
1059
|
+
mwHandlers.push({
|
|
1060
|
+
genericPath: mwEntry.genericPath,
|
|
1061
|
+
triggerNoStaticTypeCheck: async (diScope, requestObject, context) => {
|
|
1062
|
+
const decorator = decoratorFactory(diScope);
|
|
1063
|
+
return await triggerMiddlewareDecoratorNoStaticTypeCheck(
|
|
1064
|
+
mwEntry,
|
|
1065
|
+
decorator,
|
|
1066
|
+
requestObject,
|
|
1067
|
+
context
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
});
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
685
1073
|
|
|
686
1074
|
exports.ApiClient = ApiClient;
|
|
687
1075
|
exports.ApiContract = ApiContract;
|
|
688
1076
|
exports.ApiHandlersRegistry = ApiHandlersRegistry;
|
|
689
1077
|
exports.DIContainer = DIContainer;
|
|
1078
|
+
exports.DIContainerBase = DIContainerBase;
|
|
1079
|
+
exports.DIContainerTestClone = DIContainerTestClone;
|
|
690
1080
|
exports.HttpMethodEndpoint = HttpMethodEndpoint;
|
|
691
1081
|
exports.HttpMethodEndpointResponse = HttpMethodEndpointResponse;
|
|
692
1082
|
exports.HttpStatusCode = HttpStatusCode;
|
|
@@ -699,6 +1089,7 @@ exports.createClient = createClient;
|
|
|
699
1089
|
exports.createInProcApiClient = createInProcApiClient;
|
|
700
1090
|
exports.createRegistry = createRegistry;
|
|
701
1091
|
exports.endpoint = endpoint;
|
|
1092
|
+
exports.execHandlerChain = execHandlerChain;
|
|
702
1093
|
exports.flatListAllRegistryEntries = flatListAllRegistryEntries;
|
|
703
1094
|
exports.isHttpResponseObject = isHttpResponseObject;
|
|
704
1095
|
exports.isHttpStatusCode = isHttpStatusCode;
|
|
@@ -708,3 +1099,5 @@ exports.partialPathString = partialPathString;
|
|
|
708
1099
|
exports.register = register;
|
|
709
1100
|
exports.response = response;
|
|
710
1101
|
exports.route = route;
|
|
1102
|
+
exports.triggerEndpointDecoratorNoStaticTypeCheck = triggerEndpointDecoratorNoStaticTypeCheck;
|
|
1103
|
+
exports.triggerMiddlewareDecoratorNoStaticTypeCheck = triggerMiddlewareDecoratorNoStaticTypeCheck;
|