@lokalise/api-contracts 6.6.0 → 6.8.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/HttpStatusCodes.d.ts +2 -0
- package/dist/HttpStatusCodes.js +3 -1
- package/dist/HttpStatusCodes.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/new/constants.d.ts +1 -0
- package/dist/new/constants.js +2 -0
- package/dist/new/constants.js.map +1 -0
- package/dist/new/contractResponse.d.ts +46 -0
- package/dist/new/contractResponse.js +57 -0
- package/dist/new/contractResponse.js.map +1 -0
- package/dist/new/defineApiContract.d.ts +44 -0
- package/dist/new/defineApiContract.js +80 -0
- package/dist/new/defineApiContract.js.map +1 -0
- package/dist/new/inferTypes.d.ts +82 -0
- package/dist/new/inferTypes.js +2 -0
- package/dist/new/inferTypes.js.map +1 -0
- package/dist/sse/dualModeContracts.d.ts +2 -2
- package/dist/sse/sseContractBuilders.d.ts +12 -12
- package/dist/sse/sseContracts.d.ts +2 -2
- package/dist/typeUtils.d.ts +15 -0
- package/dist/typeUtils.js +2 -0
- package/dist/typeUtils.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1,3 @@
|
|
|
1
1
|
export type HttpStatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511;
|
|
2
|
+
export declare const SUCCESSFUL_HTTP_STATUS_CODES: readonly [200, 201, 202, 203, 204, 205, 206, 207, 208, 226];
|
|
3
|
+
export type SuccessfulHttpStatusCode = (typeof SUCCESSFUL_HTTP_STATUS_CODES)[number];
|
package/dist/HttpStatusCodes.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpStatusCodes.js","sourceRoot":"","sources":["../src/HttpStatusCodes.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"HttpStatusCodes.js","sourceRoot":"","sources":["../src/HttpStatusCodes.ts"],"names":[],"mappings":"AAiEA,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACxC,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export * from './apiContracts.ts';
|
|
2
2
|
export * from './contractBuilder.ts';
|
|
3
3
|
export * from './HttpStatusCodes.ts';
|
|
4
|
+
export * from './new/constants.ts';
|
|
5
|
+
export * from './new/contractResponse.ts';
|
|
6
|
+
export * from './new/defineApiContract.ts';
|
|
7
|
+
export * from './new/inferTypes.ts';
|
|
4
8
|
export * from './pathUtils.ts';
|
|
5
9
|
export * from './rest/restContractBuilder.ts';
|
|
6
10
|
export * from './sse/dualModeContracts.ts';
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,10 @@ export * from "./apiContracts.js";
|
|
|
2
2
|
// Universal contract builder
|
|
3
3
|
export * from "./contractBuilder.js";
|
|
4
4
|
export * from "./HttpStatusCodes.js";
|
|
5
|
+
export * from "./new/constants.js";
|
|
6
|
+
export * from "./new/contractResponse.js";
|
|
7
|
+
export * from "./new/defineApiContract.js";
|
|
8
|
+
export * from "./new/inferTypes.js";
|
|
5
9
|
export * from "./pathUtils.js";
|
|
6
10
|
export * from "./rest/restContractBuilder.js";
|
|
7
11
|
// Dual-mode (hybrid) contracts
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,6BAA6B;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,+BAA+B,CAAA;AAC7C,+BAA+B;AAC/B,cAAc,4BAA4B,CAAA;AAC1C,oBAAoB;AACpB,cAAc,8BAA8B,CAAA;AAC5C,gBAAgB;AAChB,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,6BAA6B;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,2BAA2B,CAAA;AACzC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,+BAA+B,CAAA;AAC7C,+BAA+B;AAC/B,cAAc,4BAA4B,CAAA;AAC1C,oBAAoB;AACpB,cAAc,8BAA8B,CAAA;AAC5C,gBAAgB;AAChB,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ContractNoBody: unique symbol;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/new/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { z } from 'zod/v4';
|
|
2
|
+
import type { HttpStatusCode } from '../HttpStatusCodes.ts';
|
|
3
|
+
import { ContractNoBody } from './constants.ts';
|
|
4
|
+
export type TypedTextResponse = {
|
|
5
|
+
readonly _tag: 'TextResponse';
|
|
6
|
+
readonly contentType: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const textResponse: (contentType: string) => TypedTextResponse;
|
|
9
|
+
export declare const isTextResponse: (value: ApiContractResponse) => value is TypedTextResponse;
|
|
10
|
+
export type TypedBlobResponse = {
|
|
11
|
+
readonly _tag: 'BlobResponse';
|
|
12
|
+
readonly contentType: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const blobResponse: (contentType: string) => TypedBlobResponse;
|
|
15
|
+
export declare const isBlobResponse: (value: ApiContractResponse) => value is TypedBlobResponse;
|
|
16
|
+
export type SseSchemaByEventName = Record<string, z.ZodType>;
|
|
17
|
+
export type TypedSseResponse<T extends SseSchemaByEventName = SseSchemaByEventName> = {
|
|
18
|
+
readonly _tag: 'SseResponse';
|
|
19
|
+
readonly schemaByEventName: T;
|
|
20
|
+
};
|
|
21
|
+
export declare const sseResponse: <T extends SseSchemaByEventName>(schemaByEventName: T) => TypedSseResponse<T>;
|
|
22
|
+
export declare const isSseResponse: (value: ApiContractResponse) => value is TypedSseResponse;
|
|
23
|
+
export type TypedJsonResponse = z.ZodType;
|
|
24
|
+
export type TypedApiContractResponse = TypedJsonResponse | TypedTextResponse | TypedBlobResponse | TypedSseResponse;
|
|
25
|
+
export type AnyOfResponses<T extends TypedApiContractResponse = TypedApiContractResponse> = {
|
|
26
|
+
readonly _tag: 'AnyOfResponses';
|
|
27
|
+
readonly responses: T[];
|
|
28
|
+
};
|
|
29
|
+
export declare const anyOfResponses: <T extends TypedApiContractResponse>(responses: T[]) => AnyOfResponses<T>;
|
|
30
|
+
export declare const isAnyOfResponses: (value: ApiContractResponse) => value is AnyOfResponses;
|
|
31
|
+
export type ApiContractResponse = typeof ContractNoBody | TypedApiContractResponse | AnyOfResponses;
|
|
32
|
+
export type ResponsesByStatusCode = Partial<Record<HttpStatusCode, ApiContractResponse>>;
|
|
33
|
+
export type ResponseKind = {
|
|
34
|
+
kind: 'noContent';
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'text';
|
|
37
|
+
} | {
|
|
38
|
+
kind: 'blob';
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'json';
|
|
41
|
+
schema: z.ZodType;
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'sse';
|
|
44
|
+
schemaByEventName: SseSchemaByEventName;
|
|
45
|
+
};
|
|
46
|
+
export declare const resolveContractResponse: (schemaEntry: ApiContractResponse, contentType: string | undefined) => ResponseKind | null;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ContractNoBody } from "./constants.js";
|
|
2
|
+
export const textResponse = (contentType) => ({
|
|
3
|
+
_tag: 'TextResponse',
|
|
4
|
+
contentType,
|
|
5
|
+
});
|
|
6
|
+
export const isTextResponse = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'TextResponse';
|
|
7
|
+
export const blobResponse = (contentType) => ({
|
|
8
|
+
_tag: 'BlobResponse',
|
|
9
|
+
contentType,
|
|
10
|
+
});
|
|
11
|
+
export const isBlobResponse = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'BlobResponse';
|
|
12
|
+
export const sseResponse = (schemaByEventName) => ({
|
|
13
|
+
_tag: 'SseResponse',
|
|
14
|
+
schemaByEventName,
|
|
15
|
+
});
|
|
16
|
+
export const isSseResponse = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'SseResponse';
|
|
17
|
+
export const anyOfResponses = (responses) => ({
|
|
18
|
+
_tag: 'AnyOfResponses',
|
|
19
|
+
responses,
|
|
20
|
+
});
|
|
21
|
+
export const isAnyOfResponses = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'AnyOfResponses';
|
|
22
|
+
const matchTypedResponse = (entry, contentType) => {
|
|
23
|
+
if (isTextResponse(entry)) {
|
|
24
|
+
return contentType.includes(entry.contentType) ? { kind: 'text' } : null;
|
|
25
|
+
}
|
|
26
|
+
if (isBlobResponse(entry)) {
|
|
27
|
+
return contentType.includes(entry.contentType) ? { kind: 'blob' } : null;
|
|
28
|
+
}
|
|
29
|
+
if (isSseResponse(entry)) {
|
|
30
|
+
return contentType.includes('text/event-stream')
|
|
31
|
+
? { kind: 'sse', schemaByEventName: entry.schemaByEventName }
|
|
32
|
+
: null;
|
|
33
|
+
}
|
|
34
|
+
if (contentType.includes('application/json')) {
|
|
35
|
+
return { kind: 'json', schema: entry };
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
export const resolveContractResponse = (schemaEntry, contentType) => {
|
|
40
|
+
if (schemaEntry === ContractNoBody) {
|
|
41
|
+
return { kind: 'noContent' };
|
|
42
|
+
}
|
|
43
|
+
if (!contentType) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
if (isAnyOfResponses(schemaEntry)) {
|
|
47
|
+
for (const item of schemaEntry.responses) {
|
|
48
|
+
const resolved = matchTypedResponse(item, contentType);
|
|
49
|
+
if (resolved) {
|
|
50
|
+
return resolved;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return matchTypedResponse(schemaEntry, contentType);
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=contractResponse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contractResponse.js","sourceRoot":"","sources":["../../src/new/contractResponse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import type { CommonRouteDefinitionMetadata, InferSchemaOutput, RoutePathResolver } from '../apiContracts.ts';
|
|
3
|
+
import type { Exactly } from '../typeUtils.ts';
|
|
4
|
+
import { ContractNoBody } from './constants.ts';
|
|
5
|
+
import { type ResponsesByStatusCode, type SseSchemaByEventName } from './contractResponse.ts';
|
|
6
|
+
export type RequestPathParamsSchema = z.ZodObject;
|
|
7
|
+
export type CommonApiContract = {
|
|
8
|
+
pathResolver: RoutePathResolver<any>;
|
|
9
|
+
requestPathParamsSchema?: RequestPathParamsSchema;
|
|
10
|
+
requestQuerySchema?: z.ZodType;
|
|
11
|
+
requestHeaderSchema?: z.ZodType;
|
|
12
|
+
responseHeaderSchema?: z.ZodType;
|
|
13
|
+
responsesByStatusCode: ResponsesByStatusCode;
|
|
14
|
+
metadata?: CommonRouteDefinitionMetadata;
|
|
15
|
+
summary?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
tags?: readonly string[];
|
|
18
|
+
};
|
|
19
|
+
export type GetApiContract = CommonApiContract & {
|
|
20
|
+
method: 'get';
|
|
21
|
+
requestBodySchema?: never;
|
|
22
|
+
};
|
|
23
|
+
export type DeleteApiContract = CommonApiContract & {
|
|
24
|
+
method: 'delete';
|
|
25
|
+
requestBodySchema?: never;
|
|
26
|
+
};
|
|
27
|
+
export type PayloadApiContract = CommonApiContract & {
|
|
28
|
+
method: 'post' | 'put' | 'patch';
|
|
29
|
+
requestBodySchema: typeof ContractNoBody | z.ZodType;
|
|
30
|
+
};
|
|
31
|
+
export type ApiContract = GetApiContract | DeleteApiContract | PayloadApiContract;
|
|
32
|
+
type TypedPathApiContract<T extends RequestPathParamsSchema> = Omit<ApiContract, 'pathResolver' | 'requestPathParamsSchema'> & {
|
|
33
|
+
pathResolver: RoutePathResolver<InferSchemaOutput<T>>;
|
|
34
|
+
requestPathParamsSchema?: T;
|
|
35
|
+
};
|
|
36
|
+
export declare const defineApiContract: <PathParamsSchema extends RequestPathParamsSchema, const Contract extends TypedPathApiContract<PathParamsSchema>>(contract: Exactly<Contract, TypedPathApiContract<PathParamsSchema>> & {
|
|
37
|
+
requestPathParamsSchema?: PathParamsSchema;
|
|
38
|
+
}) => Contract;
|
|
39
|
+
export declare const mapApiContractToPath: (routeConfig: ApiContract) => string;
|
|
40
|
+
export declare const describeApiContract: (routeConfig: ApiContract) => string;
|
|
41
|
+
export declare const getSseSchemaByEventName: (routeConfig: ApiContract) => SseSchemaByEventName | null;
|
|
42
|
+
export declare const getSuccessResponseSchema: (routeConfig: ApiContract) => z.ZodType | null;
|
|
43
|
+
export declare const getIsEmptyResponseExpected: (routeConfig: ApiContract) => boolean;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { SUCCESSFUL_HTTP_STATUS_CODES } from "../HttpStatusCodes.js";
|
|
3
|
+
import { ContractNoBody } from "./constants.js";
|
|
4
|
+
import { isAnyOfResponses, isBlobResponse, isSseResponse, isTextResponse, } from "./contractResponse.js";
|
|
5
|
+
export const defineApiContract = (contract) => contract;
|
|
6
|
+
export const mapApiContractToPath = (routeConfig) => {
|
|
7
|
+
if (!routeConfig.requestPathParamsSchema) {
|
|
8
|
+
return routeConfig.pathResolver(undefined);
|
|
9
|
+
}
|
|
10
|
+
const resolverParams = Object.keys(routeConfig.requestPathParamsSchema.shape).reduce((acc, key) => {
|
|
11
|
+
acc[key] = `:${key}`;
|
|
12
|
+
return acc;
|
|
13
|
+
}, {});
|
|
14
|
+
return routeConfig.pathResolver(resolverParams);
|
|
15
|
+
};
|
|
16
|
+
export const describeApiContract = (routeConfig) => {
|
|
17
|
+
return `${routeConfig.method.toUpperCase()} ${mapApiContractToPath(routeConfig)}`;
|
|
18
|
+
};
|
|
19
|
+
export const getSseSchemaByEventName = (routeConfig) => {
|
|
20
|
+
const result = {};
|
|
21
|
+
for (const value of Object.values(routeConfig.responsesByStatusCode)) {
|
|
22
|
+
if (isSseResponse(value)) {
|
|
23
|
+
Object.assign(result, value.schemaByEventName);
|
|
24
|
+
}
|
|
25
|
+
else if (isAnyOfResponses(value)) {
|
|
26
|
+
for (const response of value.responses) {
|
|
27
|
+
if (isSseResponse(response)) {
|
|
28
|
+
Object.assign(result, response.schemaByEventName);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
34
|
+
};
|
|
35
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: it is acceptable
|
|
36
|
+
export const getSuccessResponseSchema = (routeConfig) => {
|
|
37
|
+
const schemas = [];
|
|
38
|
+
let hasDirectNonJsonEntry = false;
|
|
39
|
+
for (const code of SUCCESSFUL_HTTP_STATUS_CODES) {
|
|
40
|
+
const value = routeConfig.responsesByStatusCode[code];
|
|
41
|
+
if (!value) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (isAnyOfResponses(value)) {
|
|
45
|
+
for (const response of value.responses) {
|
|
46
|
+
if (!isSseResponse(response) && !isTextResponse(response) && !isBlobResponse(response)) {
|
|
47
|
+
schemas.push(response);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (value === ContractNoBody ||
|
|
52
|
+
isSseResponse(value) ||
|
|
53
|
+
isTextResponse(value) ||
|
|
54
|
+
isBlobResponse(value)) {
|
|
55
|
+
hasDirectNonJsonEntry = true;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
schemas.push(value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (schemas.length > 1) {
|
|
62
|
+
return z.union(schemas);
|
|
63
|
+
}
|
|
64
|
+
if (schemas.length === 1) {
|
|
65
|
+
return schemas[0];
|
|
66
|
+
}
|
|
67
|
+
return hasDirectNonJsonEntry ? z.never() : null;
|
|
68
|
+
};
|
|
69
|
+
export const getIsEmptyResponseExpected = (routeConfig) => {
|
|
70
|
+
let isEmptyResponseExpected = true;
|
|
71
|
+
for (const code of SUCCESSFUL_HTTP_STATUS_CODES) {
|
|
72
|
+
const value = routeConfig.responsesByStatusCode[code];
|
|
73
|
+
if (value && value !== ContractNoBody) {
|
|
74
|
+
isEmptyResponseExpected = false;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return isEmptyResponseExpected;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=defineApiContract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineApiContract.js","sourceRoot":"","sources":["../../src/new/defineApiContract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAM1B,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAA;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,cAAc,GAGf,MAAM,uBAAuB,CAAA;AA4C9B,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAI/B,QAEC,EACS,EAAE,CAAC,QAAQ,CAAA;AAEvB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,WAAwB,EAAU,EAAE;IACvE,IAAI,CAAC,WAAW,CAAC,uBAAuB,EAAE,CAAC;QACzC,OAAO,WAAW,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC,MAAM,CAElF,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACb,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,CAAA;QAEpB,OAAO,GAAG,CAAA;IACZ,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,WAAW,CAAC,YAAY,CAAC,cAAc,CAAC,CAAA;AACjD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,WAAwB,EAAU,EAAE;IACtE,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,oBAAoB,CAAC,WAAW,CAAC,EAAE,CAAA;AACnF,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,WAAwB,EAA+B,EAAE;IAC/F,MAAM,MAAM,GAAyB,EAAE,CAAA;IAEvC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACrE,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA;QAChD,CAAC;aAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACvC,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAA;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;AACvD,CAAC,CAAA;AAED,gFAAgF;AAChF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,WAAwB,EAAoB,EAAE;IACrF,MAAM,OAAO,GAAgB,EAAE,CAAA;IAC/B,IAAI,qBAAqB,GAAG,KAAK,CAAA;IAEjC,KAAK,MAAM,IAAI,IAAI,4BAA4B,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,WAAW,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;QAErD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAQ;QACV,CAAC;QAED,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACvC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACvF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;gBACxB,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IACL,KAAK,KAAK,cAAc;YACxB,aAAa,CAAC,KAAK,CAAC;YACpB,cAAc,CAAC,KAAK,CAAC;YACrB,cAAc,CAAC,KAAK,CAAC,EACrB,CAAC;YACD,qBAAqB,GAAG,IAAI,CAAA;QAC9B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACzB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,CAAC,CAAE,CAAA;IACpB,CAAC;IACD,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACjD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,WAAwB,EAAW,EAAE;IAC9E,IAAI,uBAAuB,GAAG,IAAI,CAAA;IAElC,KAAK,MAAM,IAAI,IAAI,4BAA4B,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,WAAW,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;QAErD,IAAI,KAAK,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;YACtC,uBAAuB,GAAG,KAAK,CAAA;YAC/B,MAAK;QACP,CAAC;IACH,CAAC;IAED,OAAO,uBAAuB,CAAA;AAChC,CAAC,CAAA"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { z } from 'zod/v4';
|
|
2
|
+
import type { SuccessfulHttpStatusCode } from '../HttpStatusCodes.ts';
|
|
3
|
+
import type { IsUnion, ValueOf } from '../typeUtils.ts';
|
|
4
|
+
import type { ContractNoBody } from './constants.ts';
|
|
5
|
+
import type { ResponsesByStatusCode } from './contractResponse.ts';
|
|
6
|
+
type ExtractSuccessResponses<T extends ResponsesByStatusCode> = ValueOf<T, Extract<keyof T, SuccessfulHttpStatusCode>>;
|
|
7
|
+
/**
|
|
8
|
+
* Returns true if all success responses have no body (ContractNoBody or no success status codes defined).
|
|
9
|
+
*/
|
|
10
|
+
export type IsNoBodySuccessResponse<T extends ResponsesByStatusCode> = [
|
|
11
|
+
ExtractSuccessResponses<T>
|
|
12
|
+
] extends [typeof ContractNoBody | undefined] ? true : false;
|
|
13
|
+
type UnpackAnyOf<T> = T extends {
|
|
14
|
+
_tag: 'AnyOfResponses';
|
|
15
|
+
responses: Array<infer Item>;
|
|
16
|
+
} ? Item : T;
|
|
17
|
+
type FlatSuccessResponses<T extends ResponsesByStatusCode> = UnpackAnyOf<ExtractSuccessResponses<T>>;
|
|
18
|
+
/**
|
|
19
|
+
* Returns true if any success status code entry is TypedSseResponse,
|
|
20
|
+
* or an AnyOfResponses containing a TypedSseResponse.
|
|
21
|
+
*/
|
|
22
|
+
export type HasAnySseSuccessResponse<T extends ResponsesByStatusCode> = Extract<FlatSuccessResponses<T>, {
|
|
23
|
+
_tag: 'SseResponse';
|
|
24
|
+
}> extends never ? false : true;
|
|
25
|
+
type SseSchemaOf<T> = T extends {
|
|
26
|
+
_tag: 'SseResponse';
|
|
27
|
+
schemaByEventName: infer S;
|
|
28
|
+
} ? S : never;
|
|
29
|
+
/**
|
|
30
|
+
* Extracts the merged SSE event schema map from a responsesByStatusCode map.
|
|
31
|
+
* Returns the union of all `schemaByEventName` objects from TypedSseResponse entries,
|
|
32
|
+
* including those nested inside AnyOfResponses.
|
|
33
|
+
*/
|
|
34
|
+
export type InferSseSuccessResponses<T extends ResponsesByStatusCode> = SseSchemaOf<FlatSuccessResponses<T>>;
|
|
35
|
+
/**
|
|
36
|
+
* Returns true if any success status code entry is a JSON Zod schema,
|
|
37
|
+
* or an AnyOfResponses containing one.
|
|
38
|
+
*/
|
|
39
|
+
export type HasAnyJsonSuccessResponse<T extends ResponsesByStatusCode> = Extract<FlatSuccessResponses<T>, z.ZodType> extends never ? false : true;
|
|
40
|
+
type JsonSchemaOf<T> = T extends z.ZodType ? T : never;
|
|
41
|
+
/**
|
|
42
|
+
* Extracts the union of JSON Zod schemas from all success responses,
|
|
43
|
+
* including those nested inside AnyOfResponses. Text, Blob, and SSE responses are excluded.
|
|
44
|
+
*/
|
|
45
|
+
export type InferJsonSuccessResponses<T extends ResponsesByStatusCode> = JsonSchemaOf<FlatSuccessResponses<T>>;
|
|
46
|
+
type NonSseBodyOf<T> = T extends {
|
|
47
|
+
_tag: 'SseResponse';
|
|
48
|
+
} ? never : T extends {
|
|
49
|
+
_tag: 'BlobResponse';
|
|
50
|
+
} ? Blob : T extends {
|
|
51
|
+
_tag: 'TextResponse';
|
|
52
|
+
} ? string : T extends z.ZodType ? z.output<T> : undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Infers the TypeScript output type of all non-SSE success responses.
|
|
55
|
+
* JSON schemas → z.output<T>. TextResponse → string. BlobResponse → Blob.
|
|
56
|
+
* ContractNoBody → undefined. SseResponse → never (excluded).
|
|
57
|
+
* AnyOfResponses are unpacked before mapping.
|
|
58
|
+
*/
|
|
59
|
+
export type InferNonSseSuccessResponses<T extends ResponsesByStatusCode> = NonSseBodyOf<FlatSuccessResponses<T>>;
|
|
60
|
+
/**
|
|
61
|
+
* Discriminated union of SSE events inferred from a schemaByEventName map.
|
|
62
|
+
* Each event is `{ event: EventName, data: z.output<Schema> }`.
|
|
63
|
+
*/
|
|
64
|
+
export type SseEventOf<S> = {
|
|
65
|
+
[K in keyof S]: K extends string ? {
|
|
66
|
+
event: K;
|
|
67
|
+
data: S[K] extends z.ZodType ? z.output<S[K]> : never;
|
|
68
|
+
} : never;
|
|
69
|
+
}[keyof S];
|
|
70
|
+
/**
|
|
71
|
+
* True when the contract has both SSE and non-SSE success responses (dual-mode).
|
|
72
|
+
*/
|
|
73
|
+
export type IsDualModeSse<T extends ResponsesByStatusCode> = HasAnySseSuccessResponse<T> extends true ? IsUnion<AvailableResponseModes<T>> extends true ? true : false : false;
|
|
74
|
+
/**
|
|
75
|
+
* Union of response mode literals available for a given responsesByStatusCode map.
|
|
76
|
+
*/
|
|
77
|
+
export type AvailableResponseModes<T extends ResponsesByStatusCode> = (HasAnyJsonSuccessResponse<T> extends true ? 'json' : never) | (HasAnySseSuccessResponse<T> extends true ? 'sse' : never) | (Extract<FlatSuccessResponses<T>, {
|
|
78
|
+
_tag: 'BlobResponse';
|
|
79
|
+
}> extends never ? never : 'blob') | (Extract<FlatSuccessResponses<T>, {
|
|
80
|
+
_tag: 'TextResponse';
|
|
81
|
+
}> extends never ? never : 'text') | (Extract<FlatSuccessResponses<T>, typeof ContractNoBody> extends never ? never : 'noContent');
|
|
82
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inferTypes.js","sourceRoot":"","sources":["../../src/new/inferTypes.ts"],"names":[],"mappings":""}
|
|
@@ -17,9 +17,9 @@ import type { SSEEventSchemas } from './sseTypes.ts';
|
|
|
17
17
|
* @template ResponseHeaders - Response headers schema (for sync mode)
|
|
18
18
|
* @template ResponseSchemasByStatusCode - Alternative response schemas by HTTP status code
|
|
19
19
|
*/
|
|
20
|
-
export type DualModeContractDefinition<Method extends SSEMethod = SSEMethod, Params extends z.ZodTypeAny =
|
|
20
|
+
export type DualModeContractDefinition<Method extends SSEMethod = SSEMethod, Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, Body extends z.ZodTypeAny | undefined = undefined, SyncResponse extends z.ZodTypeAny = z.ZodTypeAny, Events extends SSEEventSchemas = SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
21
21
|
method: Method;
|
|
22
|
-
pathResolver: RoutePathResolver<z.infer<Params
|
|
22
|
+
pathResolver: Params extends z.ZodTypeAny ? RoutePathResolver<z.infer<Params>> : () => string;
|
|
23
23
|
requestPathParamsSchema?: Params;
|
|
24
24
|
requestQuerySchema?: Query;
|
|
25
25
|
requestHeaderSchema?: RequestHeaders;
|
|
@@ -8,9 +8,9 @@ import type { SSEEventSchemas } from './sseTypes.ts';
|
|
|
8
8
|
* Configuration for building a GET SSE route.
|
|
9
9
|
* Forbids requestBodySchema for GET variants.
|
|
10
10
|
*/
|
|
11
|
-
export type SSEGetContractConfig<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
11
|
+
export type SSEGetContractConfig<Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, Events extends SSEEventSchemas = SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
12
12
|
method: 'get';
|
|
13
|
-
pathResolver: RoutePathResolver<z.infer<Params
|
|
13
|
+
pathResolver: Params extends z.ZodTypeAny ? RoutePathResolver<z.infer<Params>> : () => string;
|
|
14
14
|
requestPathParamsSchema?: Params;
|
|
15
15
|
requestQuerySchema?: Query;
|
|
16
16
|
requestHeaderSchema?: RequestHeaders;
|
|
@@ -40,9 +40,9 @@ export type SSEGetContractConfig<Params extends z.ZodTypeAny, Query extends z.Zo
|
|
|
40
40
|
* Configuration for building a POST/PUT/PATCH SSE route with request body.
|
|
41
41
|
* Requires requestBodySchema for payload variants.
|
|
42
42
|
*/
|
|
43
|
-
export type SSEPayloadContractConfig<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Body extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
43
|
+
export type SSEPayloadContractConfig<Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, Body extends z.ZodTypeAny = z.ZodTypeAny, Events extends SSEEventSchemas = SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
44
44
|
method: 'post' | 'put' | 'patch';
|
|
45
|
-
pathResolver: RoutePathResolver<z.infer<Params
|
|
45
|
+
pathResolver: Params extends z.ZodTypeAny ? RoutePathResolver<z.infer<Params>> : () => string;
|
|
46
46
|
requestPathParamsSchema?: Params;
|
|
47
47
|
requestQuerySchema?: Query;
|
|
48
48
|
requestHeaderSchema?: RequestHeaders;
|
|
@@ -72,9 +72,9 @@ export type SSEPayloadContractConfig<Params extends z.ZodTypeAny, Query extends
|
|
|
72
72
|
* Configuration for building a GET dual-mode route.
|
|
73
73
|
* Requires successResponseBodySchema, forbids requestBodySchema.
|
|
74
74
|
*/
|
|
75
|
-
export type DualModeGetContractConfig<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, JsonResponse extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
75
|
+
export type DualModeGetContractConfig<Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, JsonResponse extends z.ZodTypeAny = z.ZodTypeAny, Events extends SSEEventSchemas = SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
76
76
|
method: 'get';
|
|
77
|
-
pathResolver: RoutePathResolver<z.infer<Params
|
|
77
|
+
pathResolver: Params extends z.ZodTypeAny ? RoutePathResolver<z.infer<Params>> : () => string;
|
|
78
78
|
requestPathParamsSchema?: Params;
|
|
79
79
|
requestQuerySchema?: Query;
|
|
80
80
|
requestHeaderSchema?: RequestHeaders;
|
|
@@ -117,9 +117,9 @@ export type DualModeGetContractConfig<Params extends z.ZodTypeAny, Query extends
|
|
|
117
117
|
* Configuration for building a POST/PUT/PATCH dual-mode route with request body.
|
|
118
118
|
* Requires both requestBodySchema and successResponseBodySchema.
|
|
119
119
|
*/
|
|
120
|
-
export type DualModePayloadContractConfig<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Body extends z.ZodTypeAny, JsonResponse extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
120
|
+
export type DualModePayloadContractConfig<Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, Body extends z.ZodTypeAny = z.ZodTypeAny, JsonResponse extends z.ZodTypeAny = z.ZodTypeAny, Events extends SSEEventSchemas = SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
121
121
|
method: 'post' | 'put' | 'patch';
|
|
122
|
-
pathResolver: RoutePathResolver<z.infer<Params
|
|
122
|
+
pathResolver: Params extends z.ZodTypeAny ? RoutePathResolver<z.infer<Params>> : () => string;
|
|
123
123
|
requestPathParamsSchema?: Params;
|
|
124
124
|
requestQuerySchema?: Query;
|
|
125
125
|
requestHeaderSchema?: RequestHeaders;
|
|
@@ -158,7 +158,7 @@ export type DualModePayloadContractConfig<Params extends z.ZodTypeAny, Query ext
|
|
|
158
158
|
summary?: string;
|
|
159
159
|
tags?: readonly string[];
|
|
160
160
|
};
|
|
161
|
-
export declare function buildSseContract<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, JsonResponse extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: DualModeGetContractConfig<Params, Query, RequestHeaders, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>): DualModeContractDefinition<'get', Params, Query, RequestHeaders, undefined, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>;
|
|
162
|
-
export declare function buildSseContract<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: SSEGetContractConfig<Params, Query, RequestHeaders, Events, ResponseSchemasByStatusCode>): SSEContractDefinition<'get', Params, Query, RequestHeaders, undefined, Events, ResponseSchemasByStatusCode>;
|
|
163
|
-
export declare function buildSseContract<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Body extends z.ZodTypeAny, JsonResponse extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: DualModePayloadContractConfig<Params, Query, RequestHeaders, Body, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>): DualModeContractDefinition<'post' | 'put' | 'patch', Params, Query, RequestHeaders, Body, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>;
|
|
164
|
-
export declare function buildSseContract<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Body extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: SSEPayloadContractConfig<Params, Query, RequestHeaders, Body, Events, ResponseSchemasByStatusCode>): SSEContractDefinition<'post' | 'put' | 'patch', Params, Query, RequestHeaders, Body, Events, ResponseSchemasByStatusCode>;
|
|
161
|
+
export declare function buildSseContract<Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, JsonResponse extends z.ZodTypeAny = z.ZodTypeAny, Events extends SSEEventSchemas = SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: DualModeGetContractConfig<Params, Query, RequestHeaders, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>): DualModeContractDefinition<'get', Params, Query, RequestHeaders, undefined, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>;
|
|
162
|
+
export declare function buildSseContract<Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, Events extends SSEEventSchemas = SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: SSEGetContractConfig<Params, Query, RequestHeaders, Events, ResponseSchemasByStatusCode>): SSEContractDefinition<'get', Params, Query, RequestHeaders, undefined, Events, ResponseSchemasByStatusCode>;
|
|
163
|
+
export declare function buildSseContract<Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, Body extends z.ZodTypeAny = z.ZodTypeAny, JsonResponse extends z.ZodTypeAny = z.ZodTypeAny, Events extends SSEEventSchemas = SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: DualModePayloadContractConfig<Params, Query, RequestHeaders, Body, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>): DualModeContractDefinition<'post' | 'put' | 'patch', Params, Query, RequestHeaders, Body, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>;
|
|
164
|
+
export declare function buildSseContract<Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, Body extends z.ZodTypeAny = z.ZodTypeAny, Events extends SSEEventSchemas = SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: SSEPayloadContractConfig<Params, Query, RequestHeaders, Body, Events, ResponseSchemasByStatusCode>): SSEContractDefinition<'post' | 'put' | 'patch', Params, Query, RequestHeaders, Body, Events, ResponseSchemasByStatusCode>;
|
|
@@ -19,13 +19,13 @@ export type SSEMethod = 'get' | 'post' | 'put' | 'patch';
|
|
|
19
19
|
* @template Events - Map of event name to event data schema
|
|
20
20
|
* @template ResponseSchemasByStatusCode - Error response schemas by HTTP status code
|
|
21
21
|
*/
|
|
22
|
-
export type SSEContractDefinition<Method extends SSEMethod = SSEMethod, Params extends z.ZodTypeAny =
|
|
22
|
+
export type SSEContractDefinition<Method extends SSEMethod = SSEMethod, Params extends z.ZodTypeAny | undefined = undefined, Query extends z.ZodTypeAny | undefined = undefined, RequestHeaders extends z.ZodTypeAny | undefined = undefined, Body extends z.ZodTypeAny | undefined = undefined, Events extends SSEEventSchemas = SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined> = {
|
|
23
23
|
method: Method;
|
|
24
24
|
/**
|
|
25
25
|
* Type-safe path resolver function.
|
|
26
26
|
* Receives typed params and returns the URL path string.
|
|
27
27
|
*/
|
|
28
|
-
pathResolver: RoutePathResolver<z.infer<Params
|
|
28
|
+
pathResolver: Params extends z.ZodTypeAny ? RoutePathResolver<z.infer<Params>> : () => string;
|
|
29
29
|
requestPathParamsSchema?: Params;
|
|
30
30
|
requestQuerySchema?: Query;
|
|
31
31
|
requestHeaderSchema?: RequestHeaders;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true when T is a union with more than one member.
|
|
3
|
+
*/
|
|
4
|
+
export type IsUnion<T, U = T> = (T extends unknown ? ([U] extends [T] ? 0 : 1) : never) extends 0 ? false : true;
|
|
5
|
+
/**
|
|
6
|
+
* Helper to prevent extra keys. If T has keys not in U, it forces an error.
|
|
7
|
+
*/
|
|
8
|
+
export type Exactly<T, U> = T & {
|
|
9
|
+
[K in keyof T]: K extends keyof U ? T[K] : never;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Extracts a union of value types from an object type.
|
|
13
|
+
* Optionally constrained to a subset of keys via ValueType.
|
|
14
|
+
*/
|
|
15
|
+
export type ValueOf<ObjectType, ValueType extends keyof ObjectType = keyof ObjectType> = ObjectType[ValueType];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeUtils.js","sourceRoot":"","sources":["../src/typeUtils.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lokalise/api-contracts",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.8.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist"
|
|
6
6
|
],
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"zod": ">=3.25.56"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@biomejs/biome": "^2.
|
|
48
|
+
"@biomejs/biome": "^2.4.7",
|
|
49
49
|
"@lokalise/biome-config": "^3.1.0",
|
|
50
50
|
"@lokalise/tsconfig": "^3.1.0",
|
|
51
51
|
"@vitest/coverage-v8": "^4.0.18",
|