@congruent-stack/congruent-api 0.12.2 → 0.14.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 +107 -9
- package/dist/index.d.cts +72 -16
- package/dist/index.d.mts +72 -16
- package/dist/index.mjs +106 -10
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
var mini = require('zod/v4/mini');
|
|
5
|
+
|
|
3
6
|
function endpoint(definition) {
|
|
4
7
|
return new HttpMethodEndpoint(definition);
|
|
5
8
|
}
|
|
@@ -321,9 +324,19 @@ function parseRequestDefinitionField(definition, key, requestObject) {
|
|
|
321
324
|
}
|
|
322
325
|
break;
|
|
323
326
|
}
|
|
327
|
+
const errors = [`'${key}' is required for this endpoint`];
|
|
328
|
+
if (key === "body") {
|
|
329
|
+
errors.push("{ 'Content-Type': 'application/json' } header might be missing");
|
|
330
|
+
}
|
|
324
331
|
return {
|
|
325
332
|
code: HttpStatusCode.BadRequest_400,
|
|
326
|
-
|
|
333
|
+
headers: {
|
|
334
|
+
"x-failed-validation-sections": key
|
|
335
|
+
},
|
|
336
|
+
body: {
|
|
337
|
+
errors
|
|
338
|
+
// treeifyError return type like structure, but here we just return simple error messages
|
|
339
|
+
}
|
|
327
340
|
};
|
|
328
341
|
}
|
|
329
342
|
return result2.data;
|
|
@@ -332,7 +345,10 @@ function parseRequestDefinitionField(definition, key, requestObject) {
|
|
|
332
345
|
if (!result.success) {
|
|
333
346
|
return {
|
|
334
347
|
code: HttpStatusCode.BadRequest_400,
|
|
335
|
-
|
|
348
|
+
headers: {
|
|
349
|
+
"x-failed-validation-sections": key
|
|
350
|
+
},
|
|
351
|
+
body: zod.treeifyError(result.error)
|
|
336
352
|
};
|
|
337
353
|
}
|
|
338
354
|
return result.data;
|
|
@@ -563,9 +579,19 @@ function middlewareParseRequestDefinitionField(middlewareSchemas, key, requestOb
|
|
|
563
579
|
}
|
|
564
580
|
break;
|
|
565
581
|
}
|
|
582
|
+
const errors = [`'${key}' is required for this endpoint`];
|
|
583
|
+
if (key === "body") {
|
|
584
|
+
errors.push("{ 'Content-Type': 'application/json' } header might be missing");
|
|
585
|
+
}
|
|
566
586
|
return {
|
|
567
587
|
code: HttpStatusCode.BadRequest_400,
|
|
568
|
-
|
|
588
|
+
headers: {
|
|
589
|
+
"x-failed-validation-sections": key
|
|
590
|
+
},
|
|
591
|
+
body: {
|
|
592
|
+
errors
|
|
593
|
+
// treeifyError return type like structure, but here we just return simple error messages
|
|
594
|
+
}
|
|
569
595
|
};
|
|
570
596
|
}
|
|
571
597
|
return result2.data;
|
|
@@ -574,7 +600,10 @@ function middlewareParseRequestDefinitionField(middlewareSchemas, key, requestOb
|
|
|
574
600
|
if (!result.success) {
|
|
575
601
|
return {
|
|
576
602
|
code: HttpStatusCode.BadRequest_400,
|
|
577
|
-
|
|
603
|
+
headers: {
|
|
604
|
+
"x-failed-validation-sections": key
|
|
605
|
+
},
|
|
606
|
+
body: zod.treeifyError(result.error)
|
|
578
607
|
};
|
|
579
608
|
}
|
|
580
609
|
return result.data;
|
|
@@ -740,6 +769,15 @@ function partialPathString(_apiReg, path) {
|
|
|
740
769
|
return path;
|
|
741
770
|
}
|
|
742
771
|
|
|
772
|
+
var RequestFailureCode = /* @__PURE__ */ ((RequestFailureCode2) => {
|
|
773
|
+
RequestFailureCode2[RequestFailureCode2["ErrorThrown"] = -1] = "ErrorThrown";
|
|
774
|
+
RequestFailureCode2[RequestFailureCode2["SchemaValidationFailed"] = -2] = "SchemaValidationFailed";
|
|
775
|
+
return RequestFailureCode2;
|
|
776
|
+
})(RequestFailureCode || {});
|
|
777
|
+
function isRequestFailureSchemaValidationFailedOutput(output) {
|
|
778
|
+
return typeof output === "object" && output !== null && "code" in output && output.code === -2 /* SchemaValidationFailed */;
|
|
779
|
+
}
|
|
780
|
+
|
|
743
781
|
function createClient(contract, clientGenericHandler) {
|
|
744
782
|
const apiClient = new ApiClient(contract, clientGenericHandler);
|
|
745
783
|
return apiClient;
|
|
@@ -783,9 +821,22 @@ class InnerApiClient {
|
|
|
783
821
|
currObj[key] = (requestObject) => {
|
|
784
822
|
const pathParams = { ...client.__CONTEXT__.pathParameters };
|
|
785
823
|
client.__CONTEXT__ = InnerApiClient._initNewContext();
|
|
824
|
+
let schemaValidationRequestFailureOutput = null;
|
|
786
825
|
const headers = clientParseRequestDefinitionField(val.definition, "headers", requestObject);
|
|
826
|
+
if (isRequestFailureSchemaValidationFailedOutput(headers)) {
|
|
827
|
+
schemaValidationRequestFailureOutput = headers;
|
|
828
|
+
return schemaValidationRequestFailureOutput;
|
|
829
|
+
}
|
|
787
830
|
const query = clientParseRequestDefinitionField(val.definition, "query", requestObject);
|
|
831
|
+
if (isRequestFailureSchemaValidationFailedOutput(query)) {
|
|
832
|
+
schemaValidationRequestFailureOutput = query;
|
|
833
|
+
return schemaValidationRequestFailureOutput;
|
|
834
|
+
}
|
|
788
835
|
const body = clientParseRequestDefinitionField(val.definition, "body", requestObject);
|
|
836
|
+
if (isRequestFailureSchemaValidationFailedOutput(body)) {
|
|
837
|
+
schemaValidationRequestFailureOutput = body;
|
|
838
|
+
return schemaValidationRequestFailureOutput;
|
|
839
|
+
}
|
|
789
840
|
const path = `/${val.pathSegments.map(
|
|
790
841
|
(segment) => segment.startsWith(":") ? pathParams[segment.slice(1)] ?? "?" : segment
|
|
791
842
|
).join("/")}`;
|
|
@@ -824,13 +875,32 @@ function clientParseRequestDefinitionField(definition, key, requestObject) {
|
|
|
824
875
|
}
|
|
825
876
|
break;
|
|
826
877
|
}
|
|
827
|
-
|
|
878
|
+
const errors = [`'${key}' is required for this endpoint`];
|
|
879
|
+
if (key === "body") {
|
|
880
|
+
errors.push("{ 'Content-Type': 'application/json' } header might be missing");
|
|
881
|
+
}
|
|
882
|
+
return {
|
|
883
|
+
code: RequestFailureCode.SchemaValidationFailed,
|
|
884
|
+
headers: {
|
|
885
|
+
"x-failed-validation-sections": key
|
|
886
|
+
},
|
|
887
|
+
body: {
|
|
888
|
+
errors
|
|
889
|
+
// treeifyError return type like structure, but here we just return simple error messages
|
|
890
|
+
}
|
|
891
|
+
};
|
|
828
892
|
}
|
|
829
893
|
return result2.data;
|
|
830
894
|
}
|
|
831
895
|
const result = definition[key].safeParse(requestObject[key]);
|
|
832
896
|
if (!result.success) {
|
|
833
|
-
|
|
897
|
+
return {
|
|
898
|
+
code: RequestFailureCode.SchemaValidationFailed,
|
|
899
|
+
headers: {
|
|
900
|
+
"x-failed-validation-sections": key
|
|
901
|
+
},
|
|
902
|
+
body: mini.treeifyError(result.error)
|
|
903
|
+
};
|
|
834
904
|
}
|
|
835
905
|
return result.data;
|
|
836
906
|
}
|
|
@@ -905,6 +975,15 @@ class DIContainer extends DIContainerBase {
|
|
|
905
975
|
this._map.set(serviceNameCapitalizedLiteral, entry);
|
|
906
976
|
return this;
|
|
907
977
|
}
|
|
978
|
+
registerTransient(serviceNameCapitalizedLiteral, factory) {
|
|
979
|
+
return this.register(serviceNameCapitalizedLiteral, factory, "transient");
|
|
980
|
+
}
|
|
981
|
+
registerScoped(serviceNameCapitalizedLiteral, factory) {
|
|
982
|
+
return this.register(serviceNameCapitalizedLiteral, factory, "scoped");
|
|
983
|
+
}
|
|
984
|
+
registerSingleton(serviceNameCapitalizedLiteral, factory) {
|
|
985
|
+
return this.register(serviceNameCapitalizedLiteral, factory, "singleton");
|
|
986
|
+
}
|
|
908
987
|
createTestClone() {
|
|
909
988
|
return new DIContainerTestClone(this);
|
|
910
989
|
}
|
|
@@ -950,7 +1029,11 @@ async function triggerEndpointDecoratorNoStaticTypeCheck(endpoint, decorator, re
|
|
|
950
1029
|
}
|
|
951
1030
|
const path = endpoint.createPath(requestObject.pathParams);
|
|
952
1031
|
return decorator.handle({
|
|
953
|
-
|
|
1032
|
+
//...requestObject,
|
|
1033
|
+
headers,
|
|
1034
|
+
query,
|
|
1035
|
+
body,
|
|
1036
|
+
pathParams: requestObject.pathParams,
|
|
954
1037
|
method: endpoint.method,
|
|
955
1038
|
genericPath: endpoint.genericPath,
|
|
956
1039
|
path,
|
|
@@ -1001,9 +1084,19 @@ function decoratorParseRequestDefinitionField(decoratorSchemas, key, requestObje
|
|
|
1001
1084
|
}
|
|
1002
1085
|
break;
|
|
1003
1086
|
}
|
|
1087
|
+
const errors = [`'${key}' is required for this endpoint`];
|
|
1088
|
+
if (key === "body") {
|
|
1089
|
+
errors.push("{ 'Content-Type': 'application/json' } header might be missing");
|
|
1090
|
+
}
|
|
1004
1091
|
return {
|
|
1005
1092
|
code: HttpStatusCode.BadRequest_400,
|
|
1006
|
-
|
|
1093
|
+
headers: {
|
|
1094
|
+
"x-failed-validation-sections": key
|
|
1095
|
+
},
|
|
1096
|
+
body: {
|
|
1097
|
+
errors
|
|
1098
|
+
// treeifyError return type like structure, but here we just return simple error messages
|
|
1099
|
+
}
|
|
1007
1100
|
};
|
|
1008
1101
|
}
|
|
1009
1102
|
return result2.data;
|
|
@@ -1012,7 +1105,10 @@ function decoratorParseRequestDefinitionField(decoratorSchemas, key, requestObje
|
|
|
1012
1105
|
if (!result.success) {
|
|
1013
1106
|
return {
|
|
1014
1107
|
code: HttpStatusCode.BadRequest_400,
|
|
1015
|
-
|
|
1108
|
+
headers: {
|
|
1109
|
+
"x-failed-validation-sections": key
|
|
1110
|
+
},
|
|
1111
|
+
body: zod.treeifyError(result.error)
|
|
1016
1112
|
};
|
|
1017
1113
|
}
|
|
1018
1114
|
return result.data;
|
|
@@ -1114,6 +1210,7 @@ exports.MethodEndpointHandlerRegistryEntry = MethodEndpointHandlerRegistryEntry;
|
|
|
1114
1210
|
exports.MiddlewareHandlersRegistry = MiddlewareHandlersRegistry;
|
|
1115
1211
|
exports.MiddlewareHandlersRegistryEntry = MiddlewareHandlersRegistryEntry;
|
|
1116
1212
|
exports.MiddlewareHandlersRegistryEntryInternal = MiddlewareHandlersRegistryEntryInternal;
|
|
1213
|
+
exports.RequestFailureCode = RequestFailureCode;
|
|
1117
1214
|
exports.apiContract = apiContract;
|
|
1118
1215
|
exports.createClient = createClient;
|
|
1119
1216
|
exports.createInProcApiClient = createInProcApiClient;
|
|
@@ -1123,6 +1220,7 @@ exports.execHandlerChain = execHandlerChain;
|
|
|
1123
1220
|
exports.flatListAllRegistryEntries = flatListAllRegistryEntries;
|
|
1124
1221
|
exports.isHttpResponseObject = isHttpResponseObject;
|
|
1125
1222
|
exports.isHttpStatusCode = isHttpStatusCode;
|
|
1223
|
+
exports.isRequestFailureSchemaValidationFailedOutput = isRequestFailureSchemaValidationFailedOutput;
|
|
1126
1224
|
exports.middleware = middleware;
|
|
1127
1225
|
exports.partial = partial;
|
|
1128
1226
|
exports.partialPathString = partialPathString;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import z, { z as z$1 } from 'zod';
|
|
1
|
+
import z, { z as z$1, treeifyError } from 'zod';
|
|
2
2
|
|
|
3
3
|
type StringLiteral<T extends string> = string extends T ? never : T;
|
|
4
4
|
type CapitalizedStringLiteral<T extends string> = string extends T ? never : T extends `${Uppercase<infer F>}${infer _}` ? F extends Lowercase<F> ? never : T : `❌ ERROR: Must start with uppercase letter`;
|
|
@@ -16,6 +16,9 @@ declare class DIContainerBase<R extends DIRegistry> {
|
|
|
16
16
|
}
|
|
17
17
|
declare class DIContainer<R extends DIRegistry = {}> extends DIContainerBase<R> {
|
|
18
18
|
register<K extends string, T>(serviceNameCapitalizedLiteral: CapitalizedStringLiteral<K>, factory: (scope: DIScope<R>) => T, lifetime: DILifetime): DIContainer<R & Record<K, DIRegistryEntry<T>>>;
|
|
19
|
+
registerTransient<K extends string, T>(serviceNameCapitalizedLiteral: CapitalizedStringLiteral<K>, factory: (scope: DIScope<R>) => T): DIContainer<R & Record<K, DIRegistryEntry<T>>>;
|
|
20
|
+
registerScoped<K extends string, T>(serviceNameCapitalizedLiteral: CapitalizedStringLiteral<K>, factory: (scope: DIScope<R>) => T): DIContainer<R & Record<K, DIRegistryEntry<T>>>;
|
|
21
|
+
registerSingleton<K extends string, T>(serviceNameCapitalizedLiteral: CapitalizedStringLiteral<K>, factory: (scope: DIScope<R>) => T): DIContainer<R & Record<K, DIRegistryEntry<T>>>;
|
|
19
22
|
createTestClone(): DIContainerTestClone<R, this>;
|
|
20
23
|
}
|
|
21
24
|
declare class DIContainerTestClone<R extends DIRegistry, TDIContainer extends DIContainer<R>> extends DIContainerBase<R> {
|
|
@@ -145,9 +148,30 @@ interface ICanTriggerAsync {
|
|
|
145
148
|
get genericPath(): string;
|
|
146
149
|
}
|
|
147
150
|
|
|
151
|
+
type _JoinSections<A extends string, B extends string> = [
|
|
152
|
+
A
|
|
153
|
+
] extends [never] ? B : [B] extends [never] ? A : `${A},${B}`;
|
|
154
|
+
type _DefinedSection<T, K extends string> = Exclude<T, undefined> extends never ? never : K;
|
|
155
|
+
type _FailedValidationSectionsImpl<P extends string, H extends string, Q extends string, B extends string> = P | H | Q | B | _JoinSections<P, H> | _JoinSections<P, Q> | _JoinSections<P, B> | _JoinSections<H, Q> | _JoinSections<H, B> | _JoinSections<Q, B> | _JoinSections<_JoinSections<P, H>, Q> | _JoinSections<_JoinSections<P, H>, B> | _JoinSections<_JoinSections<P, Q>, B> | _JoinSections<_JoinSections<H, Q>, B> | _JoinSections<_JoinSections<_JoinSections<P, H>, Q>, B>;
|
|
156
|
+
type FailedValidationSections<T extends {
|
|
157
|
+
headers?: any;
|
|
158
|
+
query?: any;
|
|
159
|
+
body?: any;
|
|
160
|
+
}> = _FailedValidationSectionsImpl<'path-segments', _DefinedSection<T['headers'], 'headers'>, _DefinedSection<T['query'], 'query'>, _DefinedSection<T['body'], 'body'>>;
|
|
161
|
+
|
|
148
162
|
type HttpMethodEndpointHandlerOutput<TEndpointDefinition extends IHttpMethodEndpointDefinition> = {
|
|
149
163
|
[THttpStatusCode in keyof TEndpointDefinition['responses'] & HttpStatusCode]: TEndpointDefinition['responses'][THttpStatusCode] extends HttpMethodEndpointResponse<THttpStatusCode, infer TRespDef> ? CreateHandlerOutput<THttpStatusCode, TRespDef> : never;
|
|
150
|
-
}[keyof TEndpointDefinition['responses'] & HttpStatusCode]
|
|
164
|
+
}[keyof TEndpointDefinition['responses'] & HttpStatusCode] | {
|
|
165
|
+
code: HttpStatusCode.BadRequest_400;
|
|
166
|
+
headers: {
|
|
167
|
+
"x-failed-validation-sections": FailedValidationSections<TEndpointDefinition>;
|
|
168
|
+
};
|
|
169
|
+
body: ReturnType<typeof treeifyError<Exclude<TEndpointDefinition['headers'] | TEndpointDefinition['query'] | TEndpointDefinition['body'], undefined>>>;
|
|
170
|
+
} | {
|
|
171
|
+
code: HttpStatusCode.InternalServerError_500;
|
|
172
|
+
headers?: unknown;
|
|
173
|
+
body?: {};
|
|
174
|
+
};
|
|
151
175
|
type CreateHandlerOutput<THttpStatusCode extends HttpStatusCode, TRespDef> = TRespDef extends {
|
|
152
176
|
headers: z$1.ZodType;
|
|
153
177
|
body: z$1.ZodType;
|
|
@@ -182,10 +206,6 @@ type HttpResponseObject = {
|
|
|
182
206
|
headers?: any;
|
|
183
207
|
body?: any;
|
|
184
208
|
};
|
|
185
|
-
type BadRequestValidationErrorResponse = {
|
|
186
|
-
code: HttpStatusCode.BadRequest_400;
|
|
187
|
-
body: z$1.core.$ZodIssue[] | string;
|
|
188
|
-
};
|
|
189
209
|
declare function isHttpResponseObject(obj: any): obj is HttpResponseObject;
|
|
190
210
|
|
|
191
211
|
declare const __overlap__error__: unique symbol;
|
|
@@ -211,8 +231,29 @@ type DecoratorHandlerContext = {
|
|
|
211
231
|
originalRequest: any;
|
|
212
232
|
};
|
|
213
233
|
|
|
234
|
+
type InferInputProp<T extends IHttpMethodEndpointDefinition, P extends keyof T> = T[P] extends z$1.ZodType<any, any> ? Record<P, z$1.input<T[P]>> : {};
|
|
235
|
+
type Merge3<A, B, C> = A & B & C;
|
|
236
|
+
type HttpMethodCallInput<T extends IHttpMethodEndpointDefinition> = Merge3<InferInputProp<T, "headers">, InferInputProp<T, "query">, InferInputProp<T, "body">> extends infer M ? keyof M extends never ? never : M : never;
|
|
237
|
+
declare enum RequestFailureCode {
|
|
238
|
+
ErrorThrown = -1,
|
|
239
|
+
SchemaValidationFailed = -2
|
|
240
|
+
}
|
|
241
|
+
type RequestFailureErrorThrownOutput = {
|
|
242
|
+
code: RequestFailureCode.ErrorThrown;
|
|
243
|
+
body: Error;
|
|
244
|
+
};
|
|
245
|
+
type RequestFailureSchemaValidationFailedOutput<TEndpointDefinition extends IHttpMethodEndpointDefinition> = {
|
|
246
|
+
code: RequestFailureCode.SchemaValidationFailed;
|
|
247
|
+
headers: {
|
|
248
|
+
"x-failed-validation-sections": FailedValidationSections<TEndpointDefinition>;
|
|
249
|
+
};
|
|
250
|
+
body: ReturnType<typeof treeifyError<Exclude<TEndpointDefinition['headers'] | TEndpointDefinition['query'] | TEndpointDefinition['body'], undefined>>>;
|
|
251
|
+
};
|
|
252
|
+
declare function isRequestFailureSchemaValidationFailedOutput<TEndpointDefinition extends IHttpMethodEndpointDefinition>(output: any): output is RequestFailureSchemaValidationFailedOutput<TEndpointDefinition>;
|
|
253
|
+
type HttpMethodCallFunc<TEndpointDefinition extends IHttpMethodEndpointDefinition> = HttpMethodCallInput<TEndpointDefinition> extends never ? () => Promise<HttpMethodEndpointHandlerOutput<TEndpointDefinition>> : (input: HttpMethodCallInput<TEndpointDefinition>) => Promise<HttpMethodEndpointHandlerOutput<TEndpointDefinition> | RequestFailureErrorThrownOutput | RequestFailureSchemaValidationFailedOutput<TEndpointDefinition>>;
|
|
254
|
+
|
|
214
255
|
type HttpMethodEndpointHandler<TDef extends IHttpMethodEndpointDefinition, TPathParams extends string, TInjected> = (input: HttpMethodEndpointHandlerInput<TDef, TPathParams>, context: EndpointHandlerContext<TInjected>) => Promise<HttpMethodEndpointHandlerOutput<TDef>>;
|
|
215
|
-
type ClientHttpMethodEndpointHandler = (input: ClientHttpMethodEndpointHandlerInput) => Promise<ClientHttpMethodEndpointHandlerOutput>;
|
|
256
|
+
type ClientHttpMethodEndpointHandler = (input: ClientHttpMethodEndpointHandlerInput) => Promise<ClientHttpMethodEndpointHandlerOutput | RequestFailureErrorThrownOutput>;
|
|
216
257
|
|
|
217
258
|
type MiddlewareHandlerSchemas = {
|
|
218
259
|
headers?: z$1.ZodType;
|
|
@@ -232,7 +273,17 @@ type MiddlewareHandlerInput<TPathParams extends string, TMiddlewareSchemas exten
|
|
|
232
273
|
};
|
|
233
274
|
type MiddlewareHandlerOutput<TMiddlewareSchemas extends MiddlewareHandlerSchemas> = void | {
|
|
234
275
|
[THttpStatusCode in keyof TMiddlewareSchemas['responses'] & HttpStatusCode]: TMiddlewareSchemas['responses'][THttpStatusCode] extends HttpMethodEndpointResponse<THttpStatusCode, infer TRespDef> ? CreateHandlerOutput<THttpStatusCode, TRespDef> : never;
|
|
235
|
-
}[keyof TMiddlewareSchemas['responses'] & HttpStatusCode]
|
|
276
|
+
}[keyof TMiddlewareSchemas['responses'] & HttpStatusCode] | {
|
|
277
|
+
code: HttpStatusCode.BadRequest_400;
|
|
278
|
+
headers: {
|
|
279
|
+
"x-failed-validation-sections": FailedValidationSections<TMiddlewareSchemas>;
|
|
280
|
+
};
|
|
281
|
+
body: ReturnType<typeof treeifyError<Exclude<TMiddlewareSchemas['headers'] | TMiddlewareSchemas['query'] | TMiddlewareSchemas['body'], undefined>>>;
|
|
282
|
+
} | {
|
|
283
|
+
code: HttpStatusCode.InternalServerError_500;
|
|
284
|
+
headers?: unknown;
|
|
285
|
+
body?: unknown;
|
|
286
|
+
};
|
|
236
287
|
type MiddlewareHandlerInputInternal = {
|
|
237
288
|
method: HttpMethod;
|
|
238
289
|
pathSegments: readonly string[];
|
|
@@ -342,7 +393,17 @@ type DecoratorHandlerInput<TDecoratorSchemas extends IDecoratorHandlerSchemas> =
|
|
|
342
393
|
};
|
|
343
394
|
type DecoratorHandlerOutput<TDecoratorSchemas extends IDecoratorHandlerSchemas> = void | {
|
|
344
395
|
[THttpStatusCode in keyof TDecoratorSchemas['responses'] & HttpStatusCode]: TDecoratorSchemas['responses'][THttpStatusCode] extends HttpMethodEndpointResponse<THttpStatusCode, infer TRespDef> ? CreateHandlerOutput<THttpStatusCode, TRespDef> : never;
|
|
345
|
-
}[keyof TDecoratorSchemas['responses'] & HttpStatusCode]
|
|
396
|
+
}[keyof TDecoratorSchemas['responses'] & HttpStatusCode] | {
|
|
397
|
+
code: HttpStatusCode.BadRequest_400;
|
|
398
|
+
headers: {
|
|
399
|
+
"x-failed-validation-sections": FailedValidationSections<TDecoratorSchemas>;
|
|
400
|
+
};
|
|
401
|
+
body: ReturnType<typeof treeifyError<Exclude<TDecoratorSchemas['headers'] | TDecoratorSchemas['query'] | TDecoratorSchemas['body'], undefined>>>;
|
|
402
|
+
} | {
|
|
403
|
+
code: HttpStatusCode.InternalServerError_500;
|
|
404
|
+
headers?: unknown;
|
|
405
|
+
body?: unknown;
|
|
406
|
+
};
|
|
346
407
|
interface IEndpointHandlerDecorator<TDecoratorSchemas extends IDecoratorHandlerSchemas> {
|
|
347
408
|
handle(input: DecoratorHandlerInput<TDecoratorSchemas>, context: DecoratorHandlerContext): Promise<DecoratorHandlerOutput<TDecoratorSchemas>>;
|
|
348
409
|
}
|
|
@@ -417,7 +478,7 @@ declare class MethodEndpointHandlerRegistryEntry<TDef extends IHttpMethodEndpoin
|
|
|
417
478
|
pathParams: TypedPathParams<TPathParams>;
|
|
418
479
|
query: TDef['query'] extends z.ZodType ? z.output<TDef['query']> : null;
|
|
419
480
|
body: TDef['body'] extends z.ZodType ? z.output<TDef['body']> : null;
|
|
420
|
-
}): Promise<HttpMethodEndpointHandlerOutput<TDef
|
|
481
|
+
}): Promise<HttpMethodEndpointHandlerOutput<TDef>>;
|
|
421
482
|
triggerNoStaticTypeCheck(diScope: DIScope<any>, requestObject: HttpRequestObject, context: EndpointHandlerContext<any>): Promise<any>;
|
|
422
483
|
}
|
|
423
484
|
|
|
@@ -484,11 +545,6 @@ declare function register<const TDef extends IHttpMethodEndpointDefinition & Val
|
|
|
484
545
|
|
|
485
546
|
declare function execHandlerChain(diScope: DIScope<any>, allHandlerEntries: ICanTriggerAsync[], input: ClientHttpMethodEndpointHandlerInput): Promise<any>;
|
|
486
547
|
|
|
487
|
-
type InferInputProp<T extends IHttpMethodEndpointDefinition, P extends keyof T> = T[P] extends z$1.ZodType<any, any> ? Record<P, z$1.input<T[P]>> : {};
|
|
488
|
-
type Merge3<A, B, C> = A & B & C;
|
|
489
|
-
type HttpMethodCallInput<T extends IHttpMethodEndpointDefinition> = Merge3<InferInputProp<T, "headers">, InferInputProp<T, "query">, InferInputProp<T, "body">> extends infer M ? keyof M extends never ? never : M : never;
|
|
490
|
-
type HttpMethodCallFunc<T extends IHttpMethodEndpointDefinition> = HttpMethodCallInput<T> extends never ? () => Promise<HttpMethodEndpointHandlerOutput<T>> : (input: HttpMethodCallInput<T>) => Promise<HttpMethodEndpointHandlerOutput<T>>;
|
|
491
|
-
|
|
492
548
|
declare function createClient<TDef extends IApiContractDefinition & ValidateApiContractDefinition<TDef>>(contract: ApiContract<TDef>, clientGenericHandler: ClientHttpMethodEndpointHandler): ApiClient<TDef>;
|
|
493
549
|
type PathParamFunc<TDef> = (value: string | number) => TDef;
|
|
494
550
|
interface IClientContext {
|
|
@@ -512,4 +568,4 @@ interface InProcApiClientOptions<TDef extends IApiContractDefinition & ValidateA
|
|
|
512
568
|
}
|
|
513
569
|
declare function createInProcApiClient<TDef extends IApiContractDefinition & ValidateApiContractDefinition<TDef>, TDIContainer extends DIContainer, TDIContainerTestClone extends DIContainerTestClone<any, TDIContainer>>(contract: ApiContract<TDef>, testContainer: TDIContainerTestClone, registry: ApiHandlersRegistry<TDef, TDIContainer>, options?: InProcApiClientOptions<TDef, TDIContainer>): ApiClient<TDef>;
|
|
514
570
|
|
|
515
|
-
export { ApiClient, type ApiClientDef, ApiContract, ApiHandlersRegistry, type ApiHandlersRegistryDef, type
|
|
571
|
+
export { ApiClient, type ApiClientDef, ApiContract, ApiHandlersRegistry, type ApiHandlersRegistryDef, type CapitalizedStringLiteral, type ClientHttpMethodEndpointHandler, type ClientHttpMethodEndpointHandlerInput, type ClientHttpMethodEndpointHandlerOutput, type CreateHandlerOutput, DIContainer, DIContainerBase, DIContainerTestClone, type DILifetime, type DIRegistry, type DIRegistryEntry, type DIScope, type DecoratorHandlerContext, type DecoratorHandlerInput, type DecoratorHandlerOutput, type EndpointHandlerContext, type EndpointHandlerContextOverlapGuard, type EndpointHandlerDecoratorFactory, type ExtractConcatenatedParamNamesFromMethodFirstPath, type ExtractConcatenatedParamNamesFromPath, type ExtractConcatenatedParamNamesFromPathSegments, type ExtractEndpointFromPath, type GenericOnHandlerRegisteredCallback, type HttpMethod, type HttpMethodCallFunc, type HttpMethodCallInput, HttpMethodEndpoint, type HttpMethodEndpointHandler, type HttpMethodEndpointHandlerInput, type HttpMethodEndpointHandlerOutput, HttpMethodEndpointResponse, type HttpMethodEndpointResponses, type HttpRequestObject, type HttpResponseObject, HttpStatusCode, type IApiContractDefinition, type IClientContext, type IDecoratorHandlerSchemas, type IEndpointHandlerDecorator, type IHttpMethodEndpointDefinition, type IHttpMethodEndpointResponseDefinition, type IRegistrySettings, type InProcApiClientOptions, type LowerCasedHttpMethod, MethodEndpointHandlerRegistryEntry, type MethodFirstPath, type MiddlewareHandler, type MiddlewareHandlerContext, type MiddlewareHandlerContextOverlapGuard, type MiddlewareHandlerInput, type MiddlewareHandlerInputInternal, type MiddlewareHandlerInternal, type MiddlewareHandlerOutput, type MiddlewareHandlerSchemas, MiddlewareHandlersRegistry, MiddlewareHandlersRegistryEntry, MiddlewareHandlersRegistryEntryInternal, type MiddlewarePath, type OnHandlerRegisteredCallback, type OnMiddlewareHandlerRegisteredCallback, type PartialPath, type PartialPathResult, type PathParamFunc, type PrepareRegistryEntryCallback, RequestFailureCode, type RequestFailureErrorThrownOutput, type RequestFailureSchemaValidationFailedOutput, type StringLiteral, type TypedPathParams, type ValidateApiContractDefinition, type ValidateHttpMethodEndpointDefinition, apiContract, createClient, createInProcApiClient, createRegistry, endpoint, execHandlerChain, flatListAllRegistryEntries, isHttpResponseObject, isHttpStatusCode, isRequestFailureSchemaValidationFailedOutput, middleware, partial, partialPathString, register, response, route, triggerEndpointDecoratorNoStaticTypeCheck, triggerMiddlewareDecoratorNoStaticTypeCheck };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import z, { z as z$1 } from 'zod';
|
|
1
|
+
import z, { z as z$1, treeifyError } from 'zod';
|
|
2
2
|
|
|
3
3
|
type StringLiteral<T extends string> = string extends T ? never : T;
|
|
4
4
|
type CapitalizedStringLiteral<T extends string> = string extends T ? never : T extends `${Uppercase<infer F>}${infer _}` ? F extends Lowercase<F> ? never : T : `❌ ERROR: Must start with uppercase letter`;
|
|
@@ -16,6 +16,9 @@ declare class DIContainerBase<R extends DIRegistry> {
|
|
|
16
16
|
}
|
|
17
17
|
declare class DIContainer<R extends DIRegistry = {}> extends DIContainerBase<R> {
|
|
18
18
|
register<K extends string, T>(serviceNameCapitalizedLiteral: CapitalizedStringLiteral<K>, factory: (scope: DIScope<R>) => T, lifetime: DILifetime): DIContainer<R & Record<K, DIRegistryEntry<T>>>;
|
|
19
|
+
registerTransient<K extends string, T>(serviceNameCapitalizedLiteral: CapitalizedStringLiteral<K>, factory: (scope: DIScope<R>) => T): DIContainer<R & Record<K, DIRegistryEntry<T>>>;
|
|
20
|
+
registerScoped<K extends string, T>(serviceNameCapitalizedLiteral: CapitalizedStringLiteral<K>, factory: (scope: DIScope<R>) => T): DIContainer<R & Record<K, DIRegistryEntry<T>>>;
|
|
21
|
+
registerSingleton<K extends string, T>(serviceNameCapitalizedLiteral: CapitalizedStringLiteral<K>, factory: (scope: DIScope<R>) => T): DIContainer<R & Record<K, DIRegistryEntry<T>>>;
|
|
19
22
|
createTestClone(): DIContainerTestClone<R, this>;
|
|
20
23
|
}
|
|
21
24
|
declare class DIContainerTestClone<R extends DIRegistry, TDIContainer extends DIContainer<R>> extends DIContainerBase<R> {
|
|
@@ -145,9 +148,30 @@ interface ICanTriggerAsync {
|
|
|
145
148
|
get genericPath(): string;
|
|
146
149
|
}
|
|
147
150
|
|
|
151
|
+
type _JoinSections<A extends string, B extends string> = [
|
|
152
|
+
A
|
|
153
|
+
] extends [never] ? B : [B] extends [never] ? A : `${A},${B}`;
|
|
154
|
+
type _DefinedSection<T, K extends string> = Exclude<T, undefined> extends never ? never : K;
|
|
155
|
+
type _FailedValidationSectionsImpl<P extends string, H extends string, Q extends string, B extends string> = P | H | Q | B | _JoinSections<P, H> | _JoinSections<P, Q> | _JoinSections<P, B> | _JoinSections<H, Q> | _JoinSections<H, B> | _JoinSections<Q, B> | _JoinSections<_JoinSections<P, H>, Q> | _JoinSections<_JoinSections<P, H>, B> | _JoinSections<_JoinSections<P, Q>, B> | _JoinSections<_JoinSections<H, Q>, B> | _JoinSections<_JoinSections<_JoinSections<P, H>, Q>, B>;
|
|
156
|
+
type FailedValidationSections<T extends {
|
|
157
|
+
headers?: any;
|
|
158
|
+
query?: any;
|
|
159
|
+
body?: any;
|
|
160
|
+
}> = _FailedValidationSectionsImpl<'path-segments', _DefinedSection<T['headers'], 'headers'>, _DefinedSection<T['query'], 'query'>, _DefinedSection<T['body'], 'body'>>;
|
|
161
|
+
|
|
148
162
|
type HttpMethodEndpointHandlerOutput<TEndpointDefinition extends IHttpMethodEndpointDefinition> = {
|
|
149
163
|
[THttpStatusCode in keyof TEndpointDefinition['responses'] & HttpStatusCode]: TEndpointDefinition['responses'][THttpStatusCode] extends HttpMethodEndpointResponse<THttpStatusCode, infer TRespDef> ? CreateHandlerOutput<THttpStatusCode, TRespDef> : never;
|
|
150
|
-
}[keyof TEndpointDefinition['responses'] & HttpStatusCode]
|
|
164
|
+
}[keyof TEndpointDefinition['responses'] & HttpStatusCode] | {
|
|
165
|
+
code: HttpStatusCode.BadRequest_400;
|
|
166
|
+
headers: {
|
|
167
|
+
"x-failed-validation-sections": FailedValidationSections<TEndpointDefinition>;
|
|
168
|
+
};
|
|
169
|
+
body: ReturnType<typeof treeifyError<Exclude<TEndpointDefinition['headers'] | TEndpointDefinition['query'] | TEndpointDefinition['body'], undefined>>>;
|
|
170
|
+
} | {
|
|
171
|
+
code: HttpStatusCode.InternalServerError_500;
|
|
172
|
+
headers?: unknown;
|
|
173
|
+
body?: {};
|
|
174
|
+
};
|
|
151
175
|
type CreateHandlerOutput<THttpStatusCode extends HttpStatusCode, TRespDef> = TRespDef extends {
|
|
152
176
|
headers: z$1.ZodType;
|
|
153
177
|
body: z$1.ZodType;
|
|
@@ -182,10 +206,6 @@ type HttpResponseObject = {
|
|
|
182
206
|
headers?: any;
|
|
183
207
|
body?: any;
|
|
184
208
|
};
|
|
185
|
-
type BadRequestValidationErrorResponse = {
|
|
186
|
-
code: HttpStatusCode.BadRequest_400;
|
|
187
|
-
body: z$1.core.$ZodIssue[] | string;
|
|
188
|
-
};
|
|
189
209
|
declare function isHttpResponseObject(obj: any): obj is HttpResponseObject;
|
|
190
210
|
|
|
191
211
|
declare const __overlap__error__: unique symbol;
|
|
@@ -211,8 +231,29 @@ type DecoratorHandlerContext = {
|
|
|
211
231
|
originalRequest: any;
|
|
212
232
|
};
|
|
213
233
|
|
|
234
|
+
type InferInputProp<T extends IHttpMethodEndpointDefinition, P extends keyof T> = T[P] extends z$1.ZodType<any, any> ? Record<P, z$1.input<T[P]>> : {};
|
|
235
|
+
type Merge3<A, B, C> = A & B & C;
|
|
236
|
+
type HttpMethodCallInput<T extends IHttpMethodEndpointDefinition> = Merge3<InferInputProp<T, "headers">, InferInputProp<T, "query">, InferInputProp<T, "body">> extends infer M ? keyof M extends never ? never : M : never;
|
|
237
|
+
declare enum RequestFailureCode {
|
|
238
|
+
ErrorThrown = -1,
|
|
239
|
+
SchemaValidationFailed = -2
|
|
240
|
+
}
|
|
241
|
+
type RequestFailureErrorThrownOutput = {
|
|
242
|
+
code: RequestFailureCode.ErrorThrown;
|
|
243
|
+
body: Error;
|
|
244
|
+
};
|
|
245
|
+
type RequestFailureSchemaValidationFailedOutput<TEndpointDefinition extends IHttpMethodEndpointDefinition> = {
|
|
246
|
+
code: RequestFailureCode.SchemaValidationFailed;
|
|
247
|
+
headers: {
|
|
248
|
+
"x-failed-validation-sections": FailedValidationSections<TEndpointDefinition>;
|
|
249
|
+
};
|
|
250
|
+
body: ReturnType<typeof treeifyError<Exclude<TEndpointDefinition['headers'] | TEndpointDefinition['query'] | TEndpointDefinition['body'], undefined>>>;
|
|
251
|
+
};
|
|
252
|
+
declare function isRequestFailureSchemaValidationFailedOutput<TEndpointDefinition extends IHttpMethodEndpointDefinition>(output: any): output is RequestFailureSchemaValidationFailedOutput<TEndpointDefinition>;
|
|
253
|
+
type HttpMethodCallFunc<TEndpointDefinition extends IHttpMethodEndpointDefinition> = HttpMethodCallInput<TEndpointDefinition> extends never ? () => Promise<HttpMethodEndpointHandlerOutput<TEndpointDefinition>> : (input: HttpMethodCallInput<TEndpointDefinition>) => Promise<HttpMethodEndpointHandlerOutput<TEndpointDefinition> | RequestFailureErrorThrownOutput | RequestFailureSchemaValidationFailedOutput<TEndpointDefinition>>;
|
|
254
|
+
|
|
214
255
|
type HttpMethodEndpointHandler<TDef extends IHttpMethodEndpointDefinition, TPathParams extends string, TInjected> = (input: HttpMethodEndpointHandlerInput<TDef, TPathParams>, context: EndpointHandlerContext<TInjected>) => Promise<HttpMethodEndpointHandlerOutput<TDef>>;
|
|
215
|
-
type ClientHttpMethodEndpointHandler = (input: ClientHttpMethodEndpointHandlerInput) => Promise<ClientHttpMethodEndpointHandlerOutput>;
|
|
256
|
+
type ClientHttpMethodEndpointHandler = (input: ClientHttpMethodEndpointHandlerInput) => Promise<ClientHttpMethodEndpointHandlerOutput | RequestFailureErrorThrownOutput>;
|
|
216
257
|
|
|
217
258
|
type MiddlewareHandlerSchemas = {
|
|
218
259
|
headers?: z$1.ZodType;
|
|
@@ -232,7 +273,17 @@ type MiddlewareHandlerInput<TPathParams extends string, TMiddlewareSchemas exten
|
|
|
232
273
|
};
|
|
233
274
|
type MiddlewareHandlerOutput<TMiddlewareSchemas extends MiddlewareHandlerSchemas> = void | {
|
|
234
275
|
[THttpStatusCode in keyof TMiddlewareSchemas['responses'] & HttpStatusCode]: TMiddlewareSchemas['responses'][THttpStatusCode] extends HttpMethodEndpointResponse<THttpStatusCode, infer TRespDef> ? CreateHandlerOutput<THttpStatusCode, TRespDef> : never;
|
|
235
|
-
}[keyof TMiddlewareSchemas['responses'] & HttpStatusCode]
|
|
276
|
+
}[keyof TMiddlewareSchemas['responses'] & HttpStatusCode] | {
|
|
277
|
+
code: HttpStatusCode.BadRequest_400;
|
|
278
|
+
headers: {
|
|
279
|
+
"x-failed-validation-sections": FailedValidationSections<TMiddlewareSchemas>;
|
|
280
|
+
};
|
|
281
|
+
body: ReturnType<typeof treeifyError<Exclude<TMiddlewareSchemas['headers'] | TMiddlewareSchemas['query'] | TMiddlewareSchemas['body'], undefined>>>;
|
|
282
|
+
} | {
|
|
283
|
+
code: HttpStatusCode.InternalServerError_500;
|
|
284
|
+
headers?: unknown;
|
|
285
|
+
body?: unknown;
|
|
286
|
+
};
|
|
236
287
|
type MiddlewareHandlerInputInternal = {
|
|
237
288
|
method: HttpMethod;
|
|
238
289
|
pathSegments: readonly string[];
|
|
@@ -342,7 +393,17 @@ type DecoratorHandlerInput<TDecoratorSchemas extends IDecoratorHandlerSchemas> =
|
|
|
342
393
|
};
|
|
343
394
|
type DecoratorHandlerOutput<TDecoratorSchemas extends IDecoratorHandlerSchemas> = void | {
|
|
344
395
|
[THttpStatusCode in keyof TDecoratorSchemas['responses'] & HttpStatusCode]: TDecoratorSchemas['responses'][THttpStatusCode] extends HttpMethodEndpointResponse<THttpStatusCode, infer TRespDef> ? CreateHandlerOutput<THttpStatusCode, TRespDef> : never;
|
|
345
|
-
}[keyof TDecoratorSchemas['responses'] & HttpStatusCode]
|
|
396
|
+
}[keyof TDecoratorSchemas['responses'] & HttpStatusCode] | {
|
|
397
|
+
code: HttpStatusCode.BadRequest_400;
|
|
398
|
+
headers: {
|
|
399
|
+
"x-failed-validation-sections": FailedValidationSections<TDecoratorSchemas>;
|
|
400
|
+
};
|
|
401
|
+
body: ReturnType<typeof treeifyError<Exclude<TDecoratorSchemas['headers'] | TDecoratorSchemas['query'] | TDecoratorSchemas['body'], undefined>>>;
|
|
402
|
+
} | {
|
|
403
|
+
code: HttpStatusCode.InternalServerError_500;
|
|
404
|
+
headers?: unknown;
|
|
405
|
+
body?: unknown;
|
|
406
|
+
};
|
|
346
407
|
interface IEndpointHandlerDecorator<TDecoratorSchemas extends IDecoratorHandlerSchemas> {
|
|
347
408
|
handle(input: DecoratorHandlerInput<TDecoratorSchemas>, context: DecoratorHandlerContext): Promise<DecoratorHandlerOutput<TDecoratorSchemas>>;
|
|
348
409
|
}
|
|
@@ -417,7 +478,7 @@ declare class MethodEndpointHandlerRegistryEntry<TDef extends IHttpMethodEndpoin
|
|
|
417
478
|
pathParams: TypedPathParams<TPathParams>;
|
|
418
479
|
query: TDef['query'] extends z.ZodType ? z.output<TDef['query']> : null;
|
|
419
480
|
body: TDef['body'] extends z.ZodType ? z.output<TDef['body']> : null;
|
|
420
|
-
}): Promise<HttpMethodEndpointHandlerOutput<TDef
|
|
481
|
+
}): Promise<HttpMethodEndpointHandlerOutput<TDef>>;
|
|
421
482
|
triggerNoStaticTypeCheck(diScope: DIScope<any>, requestObject: HttpRequestObject, context: EndpointHandlerContext<any>): Promise<any>;
|
|
422
483
|
}
|
|
423
484
|
|
|
@@ -484,11 +545,6 @@ declare function register<const TDef extends IHttpMethodEndpointDefinition & Val
|
|
|
484
545
|
|
|
485
546
|
declare function execHandlerChain(diScope: DIScope<any>, allHandlerEntries: ICanTriggerAsync[], input: ClientHttpMethodEndpointHandlerInput): Promise<any>;
|
|
486
547
|
|
|
487
|
-
type InferInputProp<T extends IHttpMethodEndpointDefinition, P extends keyof T> = T[P] extends z$1.ZodType<any, any> ? Record<P, z$1.input<T[P]>> : {};
|
|
488
|
-
type Merge3<A, B, C> = A & B & C;
|
|
489
|
-
type HttpMethodCallInput<T extends IHttpMethodEndpointDefinition> = Merge3<InferInputProp<T, "headers">, InferInputProp<T, "query">, InferInputProp<T, "body">> extends infer M ? keyof M extends never ? never : M : never;
|
|
490
|
-
type HttpMethodCallFunc<T extends IHttpMethodEndpointDefinition> = HttpMethodCallInput<T> extends never ? () => Promise<HttpMethodEndpointHandlerOutput<T>> : (input: HttpMethodCallInput<T>) => Promise<HttpMethodEndpointHandlerOutput<T>>;
|
|
491
|
-
|
|
492
548
|
declare function createClient<TDef extends IApiContractDefinition & ValidateApiContractDefinition<TDef>>(contract: ApiContract<TDef>, clientGenericHandler: ClientHttpMethodEndpointHandler): ApiClient<TDef>;
|
|
493
549
|
type PathParamFunc<TDef> = (value: string | number) => TDef;
|
|
494
550
|
interface IClientContext {
|
|
@@ -512,4 +568,4 @@ interface InProcApiClientOptions<TDef extends IApiContractDefinition & ValidateA
|
|
|
512
568
|
}
|
|
513
569
|
declare function createInProcApiClient<TDef extends IApiContractDefinition & ValidateApiContractDefinition<TDef>, TDIContainer extends DIContainer, TDIContainerTestClone extends DIContainerTestClone<any, TDIContainer>>(contract: ApiContract<TDef>, testContainer: TDIContainerTestClone, registry: ApiHandlersRegistry<TDef, TDIContainer>, options?: InProcApiClientOptions<TDef, TDIContainer>): ApiClient<TDef>;
|
|
514
570
|
|
|
515
|
-
export { ApiClient, type ApiClientDef, ApiContract, ApiHandlersRegistry, type ApiHandlersRegistryDef, type
|
|
571
|
+
export { ApiClient, type ApiClientDef, ApiContract, ApiHandlersRegistry, type ApiHandlersRegistryDef, type CapitalizedStringLiteral, type ClientHttpMethodEndpointHandler, type ClientHttpMethodEndpointHandlerInput, type ClientHttpMethodEndpointHandlerOutput, type CreateHandlerOutput, DIContainer, DIContainerBase, DIContainerTestClone, type DILifetime, type DIRegistry, type DIRegistryEntry, type DIScope, type DecoratorHandlerContext, type DecoratorHandlerInput, type DecoratorHandlerOutput, type EndpointHandlerContext, type EndpointHandlerContextOverlapGuard, type EndpointHandlerDecoratorFactory, type ExtractConcatenatedParamNamesFromMethodFirstPath, type ExtractConcatenatedParamNamesFromPath, type ExtractConcatenatedParamNamesFromPathSegments, type ExtractEndpointFromPath, type GenericOnHandlerRegisteredCallback, type HttpMethod, type HttpMethodCallFunc, type HttpMethodCallInput, HttpMethodEndpoint, type HttpMethodEndpointHandler, type HttpMethodEndpointHandlerInput, type HttpMethodEndpointHandlerOutput, HttpMethodEndpointResponse, type HttpMethodEndpointResponses, type HttpRequestObject, type HttpResponseObject, HttpStatusCode, type IApiContractDefinition, type IClientContext, type IDecoratorHandlerSchemas, type IEndpointHandlerDecorator, type IHttpMethodEndpointDefinition, type IHttpMethodEndpointResponseDefinition, type IRegistrySettings, type InProcApiClientOptions, type LowerCasedHttpMethod, MethodEndpointHandlerRegistryEntry, type MethodFirstPath, type MiddlewareHandler, type MiddlewareHandlerContext, type MiddlewareHandlerContextOverlapGuard, type MiddlewareHandlerInput, type MiddlewareHandlerInputInternal, type MiddlewareHandlerInternal, type MiddlewareHandlerOutput, type MiddlewareHandlerSchemas, MiddlewareHandlersRegistry, MiddlewareHandlersRegistryEntry, MiddlewareHandlersRegistryEntryInternal, type MiddlewarePath, type OnHandlerRegisteredCallback, type OnMiddlewareHandlerRegisteredCallback, type PartialPath, type PartialPathResult, type PathParamFunc, type PrepareRegistryEntryCallback, RequestFailureCode, type RequestFailureErrorThrownOutput, type RequestFailureSchemaValidationFailedOutput, type StringLiteral, type TypedPathParams, type ValidateApiContractDefinition, type ValidateHttpMethodEndpointDefinition, apiContract, createClient, createInProcApiClient, createRegistry, endpoint, execHandlerChain, flatListAllRegistryEntries, isHttpResponseObject, isHttpStatusCode, isRequestFailureSchemaValidationFailedOutput, middleware, partial, partialPathString, register, response, route, triggerEndpointDecoratorNoStaticTypeCheck, triggerMiddlewareDecoratorNoStaticTypeCheck };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { treeifyError } from 'zod';
|
|
2
|
+
import { treeifyError as treeifyError$1 } from 'zod/v4/mini';
|
|
3
|
+
|
|
1
4
|
function endpoint(definition) {
|
|
2
5
|
return new HttpMethodEndpoint(definition);
|
|
3
6
|
}
|
|
@@ -319,9 +322,19 @@ function parseRequestDefinitionField(definition, key, requestObject) {
|
|
|
319
322
|
}
|
|
320
323
|
break;
|
|
321
324
|
}
|
|
325
|
+
const errors = [`'${key}' is required for this endpoint`];
|
|
326
|
+
if (key === "body") {
|
|
327
|
+
errors.push("{ 'Content-Type': 'application/json' } header might be missing");
|
|
328
|
+
}
|
|
322
329
|
return {
|
|
323
330
|
code: HttpStatusCode.BadRequest_400,
|
|
324
|
-
|
|
331
|
+
headers: {
|
|
332
|
+
"x-failed-validation-sections": key
|
|
333
|
+
},
|
|
334
|
+
body: {
|
|
335
|
+
errors
|
|
336
|
+
// treeifyError return type like structure, but here we just return simple error messages
|
|
337
|
+
}
|
|
325
338
|
};
|
|
326
339
|
}
|
|
327
340
|
return result2.data;
|
|
@@ -330,7 +343,10 @@ function parseRequestDefinitionField(definition, key, requestObject) {
|
|
|
330
343
|
if (!result.success) {
|
|
331
344
|
return {
|
|
332
345
|
code: HttpStatusCode.BadRequest_400,
|
|
333
|
-
|
|
346
|
+
headers: {
|
|
347
|
+
"x-failed-validation-sections": key
|
|
348
|
+
},
|
|
349
|
+
body: treeifyError(result.error)
|
|
334
350
|
};
|
|
335
351
|
}
|
|
336
352
|
return result.data;
|
|
@@ -561,9 +577,19 @@ function middlewareParseRequestDefinitionField(middlewareSchemas, key, requestOb
|
|
|
561
577
|
}
|
|
562
578
|
break;
|
|
563
579
|
}
|
|
580
|
+
const errors = [`'${key}' is required for this endpoint`];
|
|
581
|
+
if (key === "body") {
|
|
582
|
+
errors.push("{ 'Content-Type': 'application/json' } header might be missing");
|
|
583
|
+
}
|
|
564
584
|
return {
|
|
565
585
|
code: HttpStatusCode.BadRequest_400,
|
|
566
|
-
|
|
586
|
+
headers: {
|
|
587
|
+
"x-failed-validation-sections": key
|
|
588
|
+
},
|
|
589
|
+
body: {
|
|
590
|
+
errors
|
|
591
|
+
// treeifyError return type like structure, but here we just return simple error messages
|
|
592
|
+
}
|
|
567
593
|
};
|
|
568
594
|
}
|
|
569
595
|
return result2.data;
|
|
@@ -572,7 +598,10 @@ function middlewareParseRequestDefinitionField(middlewareSchemas, key, requestOb
|
|
|
572
598
|
if (!result.success) {
|
|
573
599
|
return {
|
|
574
600
|
code: HttpStatusCode.BadRequest_400,
|
|
575
|
-
|
|
601
|
+
headers: {
|
|
602
|
+
"x-failed-validation-sections": key
|
|
603
|
+
},
|
|
604
|
+
body: treeifyError(result.error)
|
|
576
605
|
};
|
|
577
606
|
}
|
|
578
607
|
return result.data;
|
|
@@ -738,6 +767,15 @@ function partialPathString(_apiReg, path) {
|
|
|
738
767
|
return path;
|
|
739
768
|
}
|
|
740
769
|
|
|
770
|
+
var RequestFailureCode = /* @__PURE__ */ ((RequestFailureCode2) => {
|
|
771
|
+
RequestFailureCode2[RequestFailureCode2["ErrorThrown"] = -1] = "ErrorThrown";
|
|
772
|
+
RequestFailureCode2[RequestFailureCode2["SchemaValidationFailed"] = -2] = "SchemaValidationFailed";
|
|
773
|
+
return RequestFailureCode2;
|
|
774
|
+
})(RequestFailureCode || {});
|
|
775
|
+
function isRequestFailureSchemaValidationFailedOutput(output) {
|
|
776
|
+
return typeof output === "object" && output !== null && "code" in output && output.code === -2 /* SchemaValidationFailed */;
|
|
777
|
+
}
|
|
778
|
+
|
|
741
779
|
function createClient(contract, clientGenericHandler) {
|
|
742
780
|
const apiClient = new ApiClient(contract, clientGenericHandler);
|
|
743
781
|
return apiClient;
|
|
@@ -781,9 +819,22 @@ class InnerApiClient {
|
|
|
781
819
|
currObj[key] = (requestObject) => {
|
|
782
820
|
const pathParams = { ...client.__CONTEXT__.pathParameters };
|
|
783
821
|
client.__CONTEXT__ = InnerApiClient._initNewContext();
|
|
822
|
+
let schemaValidationRequestFailureOutput = null;
|
|
784
823
|
const headers = clientParseRequestDefinitionField(val.definition, "headers", requestObject);
|
|
824
|
+
if (isRequestFailureSchemaValidationFailedOutput(headers)) {
|
|
825
|
+
schemaValidationRequestFailureOutput = headers;
|
|
826
|
+
return schemaValidationRequestFailureOutput;
|
|
827
|
+
}
|
|
785
828
|
const query = clientParseRequestDefinitionField(val.definition, "query", requestObject);
|
|
829
|
+
if (isRequestFailureSchemaValidationFailedOutput(query)) {
|
|
830
|
+
schemaValidationRequestFailureOutput = query;
|
|
831
|
+
return schemaValidationRequestFailureOutput;
|
|
832
|
+
}
|
|
786
833
|
const body = clientParseRequestDefinitionField(val.definition, "body", requestObject);
|
|
834
|
+
if (isRequestFailureSchemaValidationFailedOutput(body)) {
|
|
835
|
+
schemaValidationRequestFailureOutput = body;
|
|
836
|
+
return schemaValidationRequestFailureOutput;
|
|
837
|
+
}
|
|
787
838
|
const path = `/${val.pathSegments.map(
|
|
788
839
|
(segment) => segment.startsWith(":") ? pathParams[segment.slice(1)] ?? "?" : segment
|
|
789
840
|
).join("/")}`;
|
|
@@ -822,13 +873,32 @@ function clientParseRequestDefinitionField(definition, key, requestObject) {
|
|
|
822
873
|
}
|
|
823
874
|
break;
|
|
824
875
|
}
|
|
825
|
-
|
|
876
|
+
const errors = [`'${key}' is required for this endpoint`];
|
|
877
|
+
if (key === "body") {
|
|
878
|
+
errors.push("{ 'Content-Type': 'application/json' } header might be missing");
|
|
879
|
+
}
|
|
880
|
+
return {
|
|
881
|
+
code: RequestFailureCode.SchemaValidationFailed,
|
|
882
|
+
headers: {
|
|
883
|
+
"x-failed-validation-sections": key
|
|
884
|
+
},
|
|
885
|
+
body: {
|
|
886
|
+
errors
|
|
887
|
+
// treeifyError return type like structure, but here we just return simple error messages
|
|
888
|
+
}
|
|
889
|
+
};
|
|
826
890
|
}
|
|
827
891
|
return result2.data;
|
|
828
892
|
}
|
|
829
893
|
const result = definition[key].safeParse(requestObject[key]);
|
|
830
894
|
if (!result.success) {
|
|
831
|
-
|
|
895
|
+
return {
|
|
896
|
+
code: RequestFailureCode.SchemaValidationFailed,
|
|
897
|
+
headers: {
|
|
898
|
+
"x-failed-validation-sections": key
|
|
899
|
+
},
|
|
900
|
+
body: treeifyError$1(result.error)
|
|
901
|
+
};
|
|
832
902
|
}
|
|
833
903
|
return result.data;
|
|
834
904
|
}
|
|
@@ -903,6 +973,15 @@ class DIContainer extends DIContainerBase {
|
|
|
903
973
|
this._map.set(serviceNameCapitalizedLiteral, entry);
|
|
904
974
|
return this;
|
|
905
975
|
}
|
|
976
|
+
registerTransient(serviceNameCapitalizedLiteral, factory) {
|
|
977
|
+
return this.register(serviceNameCapitalizedLiteral, factory, "transient");
|
|
978
|
+
}
|
|
979
|
+
registerScoped(serviceNameCapitalizedLiteral, factory) {
|
|
980
|
+
return this.register(serviceNameCapitalizedLiteral, factory, "scoped");
|
|
981
|
+
}
|
|
982
|
+
registerSingleton(serviceNameCapitalizedLiteral, factory) {
|
|
983
|
+
return this.register(serviceNameCapitalizedLiteral, factory, "singleton");
|
|
984
|
+
}
|
|
906
985
|
createTestClone() {
|
|
907
986
|
return new DIContainerTestClone(this);
|
|
908
987
|
}
|
|
@@ -948,7 +1027,11 @@ async function triggerEndpointDecoratorNoStaticTypeCheck(endpoint, decorator, re
|
|
|
948
1027
|
}
|
|
949
1028
|
const path = endpoint.createPath(requestObject.pathParams);
|
|
950
1029
|
return decorator.handle({
|
|
951
|
-
|
|
1030
|
+
//...requestObject,
|
|
1031
|
+
headers,
|
|
1032
|
+
query,
|
|
1033
|
+
body,
|
|
1034
|
+
pathParams: requestObject.pathParams,
|
|
952
1035
|
method: endpoint.method,
|
|
953
1036
|
genericPath: endpoint.genericPath,
|
|
954
1037
|
path,
|
|
@@ -999,9 +1082,19 @@ function decoratorParseRequestDefinitionField(decoratorSchemas, key, requestObje
|
|
|
999
1082
|
}
|
|
1000
1083
|
break;
|
|
1001
1084
|
}
|
|
1085
|
+
const errors = [`'${key}' is required for this endpoint`];
|
|
1086
|
+
if (key === "body") {
|
|
1087
|
+
errors.push("{ 'Content-Type': 'application/json' } header might be missing");
|
|
1088
|
+
}
|
|
1002
1089
|
return {
|
|
1003
1090
|
code: HttpStatusCode.BadRequest_400,
|
|
1004
|
-
|
|
1091
|
+
headers: {
|
|
1092
|
+
"x-failed-validation-sections": key
|
|
1093
|
+
},
|
|
1094
|
+
body: {
|
|
1095
|
+
errors
|
|
1096
|
+
// treeifyError return type like structure, but here we just return simple error messages
|
|
1097
|
+
}
|
|
1005
1098
|
};
|
|
1006
1099
|
}
|
|
1007
1100
|
return result2.data;
|
|
@@ -1010,7 +1103,10 @@ function decoratorParseRequestDefinitionField(decoratorSchemas, key, requestObje
|
|
|
1010
1103
|
if (!result.success) {
|
|
1011
1104
|
return {
|
|
1012
1105
|
code: HttpStatusCode.BadRequest_400,
|
|
1013
|
-
|
|
1106
|
+
headers: {
|
|
1107
|
+
"x-failed-validation-sections": key
|
|
1108
|
+
},
|
|
1109
|
+
body: treeifyError(result.error)
|
|
1014
1110
|
};
|
|
1015
1111
|
}
|
|
1016
1112
|
return result.data;
|
|
@@ -1099,4 +1195,4 @@ function addMiddlewareDecorators(mwHandlers, mwEntry) {
|
|
|
1099
1195
|
});
|
|
1100
1196
|
}
|
|
1101
1197
|
|
|
1102
|
-
export { ApiClient, ApiContract, ApiHandlersRegistry, DIContainer, DIContainerBase, DIContainerTestClone, HttpMethodEndpoint, HttpMethodEndpointResponse, HttpStatusCode, MethodEndpointHandlerRegistryEntry, MiddlewareHandlersRegistry, MiddlewareHandlersRegistryEntry, MiddlewareHandlersRegistryEntryInternal, apiContract, createClient, createInProcApiClient, createRegistry, endpoint, execHandlerChain, flatListAllRegistryEntries, isHttpResponseObject, isHttpStatusCode, middleware, partial, partialPathString, register, response, route, triggerEndpointDecoratorNoStaticTypeCheck, triggerMiddlewareDecoratorNoStaticTypeCheck };
|
|
1198
|
+
export { ApiClient, ApiContract, ApiHandlersRegistry, DIContainer, DIContainerBase, DIContainerTestClone, HttpMethodEndpoint, HttpMethodEndpointResponse, HttpStatusCode, MethodEndpointHandlerRegistryEntry, MiddlewareHandlersRegistry, MiddlewareHandlersRegistryEntry, MiddlewareHandlersRegistryEntryInternal, RequestFailureCode, apiContract, createClient, createInProcApiClient, createRegistry, endpoint, execHandlerChain, flatListAllRegistryEntries, isHttpResponseObject, isHttpStatusCode, isRequestFailureSchemaValidationFailedOutput, middleware, partial, partialPathString, register, response, route, triggerEndpointDecoratorNoStaticTypeCheck, triggerMiddlewareDecoratorNoStaticTypeCheck };
|