@lokalise/api-contracts 6.3.0 → 6.5.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/README.md CHANGED
@@ -8,6 +8,69 @@ This reduces amount of assumptions FE needs to make about the behaviour of BE, r
8
8
  written on FE, and makes the code more type-safe (as path parameter setting is handled by logic exposed by BE, in a
9
9
  type-safe way).
10
10
 
11
+ ## Universal Contract Builder
12
+
13
+ Use `buildContract` as a single entry point for creating any type of API contract. It automatically delegates to the appropriate specialized builder based on the configuration:
14
+
15
+ | `sseEvents` | Contract Type |
16
+ |-------------|---------------|
17
+ | ❌ | REST contract (GET, POST, PUT, PATCH, DELETE) |
18
+ | ✅ | SSE or Dual-mode contract |
19
+
20
+ ```ts
21
+ import { buildContract } from '@lokalise/api-contracts'
22
+ import { z } from 'zod'
23
+
24
+ // REST GET route
25
+ const getUsers = buildContract({
26
+ successResponseBodySchema: z.array(userSchema),
27
+ pathResolver: () => '/api/users',
28
+ })
29
+
30
+ // REST POST route
31
+ const createUser = buildContract({
32
+ method: 'post',
33
+ requestBodySchema: createUserSchema,
34
+ successResponseBodySchema: userSchema,
35
+ pathResolver: () => '/api/users',
36
+ })
37
+
38
+ // REST DELETE route
39
+ const deleteUser = buildContract({
40
+ method: 'delete',
41
+ requestPathParamsSchema: z.object({ userId: z.string() }),
42
+ pathResolver: (params) => `/api/users/${params.userId}`,
43
+ })
44
+
45
+ // SSE-only streaming endpoint
46
+ const notifications = buildContract({
47
+ pathResolver: () => '/api/notifications/stream',
48
+ params: z.object({}),
49
+ query: z.object({}),
50
+ requestHeaders: z.object({}),
51
+ sseEvents: {
52
+ notification: z.object({ id: z.string(), message: z.string() }),
53
+ },
54
+ })
55
+
56
+ // Dual-mode endpoint (supports both JSON and SSE)
57
+ const chatCompletion = buildContract({
58
+ method: 'post',
59
+ pathResolver: () => '/api/chat/completions',
60
+ params: z.object({}),
61
+ query: z.object({}),
62
+ requestHeaders: z.object({}),
63
+ requestBody: z.object({ message: z.string() }),
64
+ syncResponseBody: z.object({ reply: z.string() }),
65
+ sseEvents: {
66
+ chunk: z.object({ delta: z.string() }),
67
+ done: z.object({ usage: z.object({ tokens: z.number() }) }),
68
+ },
69
+ })
70
+ ```
71
+
72
+ You can also use the specialized builders directly (`buildRestContract`, `buildSseContract`) if you prefer explicit control over contract types.
73
+
11
74
  ## REST Contracts
12
75
 
13
76
  Use `buildRestContract` to create REST API contracts. The contract type is automatically determined based on the configuration:
@@ -0,0 +1,84 @@
1
+ import type { z } from 'zod/v4';
2
+ import type { DeleteRouteDefinition, GetRouteDefinition, PayloadRouteDefinition } from './apiContracts.ts';
3
+ import type { HttpStatusCode } from './HttpStatusCodes.ts';
4
+ import { type DeleteContractConfig, type GetContractConfig, type PayloadContractConfig } from './rest/restContractBuilder.ts';
5
+ import type { DualModeContractDefinition } from './sse/dualModeContracts.ts';
6
+ import { type DualModeGetContractConfig, type DualModePayloadContractConfig, type SSEGetContractConfig, type SSEPayloadContractConfig } from './sse/sseContractBuilders.ts';
7
+ import type { SSEContractDefinition } from './sse/sseContracts.ts';
8
+ import type { SSEEventSchemas } from './sse/sseTypes.ts';
9
+ /**
10
+ * Universal contract builder that creates either REST or SSE contracts based on configuration.
11
+ *
12
+ * This is a unified entry point that delegates to:
13
+ * - `buildRestContract` when no `serverSentEventSchemas` is provided
14
+ * - `buildSseContract` when `serverSentEventSchemas` is provided
15
+ *
16
+ * ## Contract Type Detection
17
+ *
18
+ * | `serverSentEventSchemas` | `successResponseBodySchema` | `requestBodySchema` | Result |
19
+ * |--------------------|----------------------------|---------------------|--------|
20
+ * | ❌ | - | ❌ | REST GET |
21
+ * | ❌ | - | ✅ (method: post/put/patch) | REST Payload |
22
+ * | ❌ | - | ❌ (method: delete) | REST DELETE |
23
+ * | ✅ | ❌ | ❌ | SSE-only GET |
24
+ * | ✅ | ❌ | ✅ | SSE-only POST/PUT/PATCH |
25
+ * | ✅ | ✅ | ❌ | Dual-mode GET |
26
+ * | ✅ | ✅ | ✅ | Dual-mode POST/PUT/PATCH |
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // REST GET route
31
+ * const getUsers = buildContract({
32
+ * successResponseBodySchema: z.array(userSchema),
33
+ * pathResolver: () => '/api/users',
34
+ * })
35
+ *
36
+ * // REST POST route
37
+ * const createUser = buildContract({
38
+ * method: 'post',
39
+ * requestBodySchema: createUserSchema,
40
+ * successResponseBodySchema: userSchema,
41
+ * pathResolver: () => '/api/users',
42
+ * })
43
+ *
44
+ * // REST DELETE route
45
+ * const deleteUser = buildContract({
46
+ * method: 'delete',
47
+ * pathResolver: (params) => `/api/users/${params.userId}`,
48
+ * requestPathParamsSchema: z.object({ userId: z.string() }),
49
+ * })
50
+ *
51
+ * // SSE-only streaming endpoint
52
+ * const notifications = buildContract({
53
+ * pathResolver: () => '/api/notifications/stream',
54
+ * requestPathParamsSchema: z.object({}),
55
+ * requestQuerySchema: z.object({}),
56
+ * requestHeaderSchema: z.object({}),
57
+ * serverSentEventSchemas: {
58
+ * notification: z.object({ id: z.string(), message: z.string() }),
59
+ * },
60
+ * })
61
+ *
62
+ * // Dual-mode endpoint (supports both JSON and SSE)
63
+ * const chatCompletion = buildContract({
64
+ * method: 'post',
65
+ * pathResolver: () => '/api/chat/completions',
66
+ * requestPathParamsSchema: z.object({}),
67
+ * requestQuerySchema: z.object({}),
68
+ * requestHeaderSchema: z.object({}),
69
+ * requestBodySchema: z.object({ message: z.string() }),
70
+ * successResponseBodySchema: z.object({ reply: z.string() }),
71
+ * serverSentEventSchemas: {
72
+ * chunk: z.object({ delta: z.string() }),
73
+ * done: z.object({ usage: z.object({ tokens: z.number() }) }),
74
+ * },
75
+ * })
76
+ * ```
77
+ */
78
+ export declare function buildContract<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: GetContractConfig<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): GetRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
79
+ export declare function buildContract<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = true, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: DeleteContractConfig<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): DeleteRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
80
+ export declare function buildContract<RequestBodySchema extends z.Schema | undefined = undefined, SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: PayloadContractConfig<RequestBodySchema, SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): PayloadRouteDefinition<RequestBodySchema, SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
81
+ export declare function buildContract<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>;
82
+ export declare function buildContract<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>;
83
+ export declare function buildContract<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>;
84
+ export declare function buildContract<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>;
@@ -0,0 +1,17 @@
1
+ import { buildRestContract, } from "./rest/restContractBuilder.js";
2
+ import { buildSseContract, } from "./sse/sseContractBuilders.js";
3
+ // ============================================================================
4
+ // Implementation
5
+ // ============================================================================
6
+ export function buildContract(
7
+ // biome-ignore lint/suspicious/noExplicitAny: Union of all config types
8
+ config) {
9
+ const hasSseEvents = 'serverSentEventSchemas' in config && config.serverSentEventSchemas !== undefined;
10
+ if (hasSseEvents) {
11
+ // Delegate to SSE contract builder
12
+ return buildSseContract(config);
13
+ }
14
+ // Delegate to REST contract builder
15
+ return buildRestContract(config);
16
+ }
17
+ //# sourceMappingURL=contractBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contractBuilder.js","sourceRoot":"","sources":["../src/contractBuilder.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,iBAAiB,GAIlB,MAAM,+BAA+B,CAAA;AAEtC,OAAO,EACL,gBAAgB,GAKjB,MAAM,8BAA8B,CAAA;AAqTrC,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,UAAU,aAAa;AAC3B,wEAAwE;AACxE,MAAW;IAGX,MAAM,YAAY,GAChB,wBAAwB,IAAI,MAAM,IAAI,MAAM,CAAC,sBAAsB,KAAK,SAAS,CAAA;IAEnF,IAAI,YAAY,EAAE,CAAC;QACjB,mCAAmC;QACnC,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAA;IACjC,CAAC;IAED,oCAAoC;IACpC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAA;AAClC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './apiContracts.ts';
2
+ export * from './contractBuilder.ts';
2
3
  export * from './HttpStatusCodes.ts';
3
4
  export * from './pathUtils.ts';
4
5
  export * from './rest/restContractBuilder.ts';
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from "./apiContracts.js";
2
+ // Universal contract builder
3
+ export * from "./contractBuilder.js";
2
4
  export * from "./HttpStatusCodes.js";
3
5
  export * from "./pathUtils.js";
4
6
  export * from "./rest/restContractBuilder.js";
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,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,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"}
@@ -8,6 +8,8 @@ import type { HttpStatusCode } from '../HttpStatusCodes.ts';
8
8
  export type GetContractConfig<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = Omit<CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'method'> & {
9
9
  method?: never;
10
10
  requestBodySchema?: never;
11
+ /** Discriminator to distinguish from SSE contracts in buildContract */
12
+ serverSentEventSchemas?: never;
11
13
  };
12
14
  /**
13
15
  * Configuration for building a DELETE route.
@@ -16,6 +18,8 @@ export type GetContractConfig<SuccessResponseBodySchema extends z.Schema | undef
16
18
  export type DeleteContractConfig<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = true, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = Omit<CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'method'> & {
17
19
  method: 'delete';
18
20
  requestBodySchema?: never;
21
+ /** Discriminator to distinguish from SSE contracts in buildContract */
22
+ serverSentEventSchemas?: never;
19
23
  };
20
24
  /**
21
25
  * Configuration for building a payload route (POST, PUT, PATCH).
@@ -24,6 +28,8 @@ export type DeleteContractConfig<SuccessResponseBodySchema extends z.Schema | un
24
28
  export type PayloadContractConfig<RequestBodySchema extends z.Schema | undefined = undefined, SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode> & {
25
29
  method: 'post' | 'put' | 'patch';
26
30
  requestBodySchema: RequestBodySchema;
31
+ /** Discriminator to distinguish from SSE contracts in buildContract */
32
+ serverSentEventSchemas?: never;
27
33
  };
28
34
  /**
29
35
  * Builds REST API contracts with automatic type inference.
@@ -1 +1 @@
1
- {"version":3,"file":"restContractBuilder.js","sourceRoot":"","sources":["../../src/rest/restContractBuilder.ts"],"names":[],"mappings":"AAyRA,iBAAiB;AACjB,MAAM,UAAU,iBAAiB,CAC/B,MAKsE;IAGtE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC5B,MAAM,OAAO,GAAG,mBAAmB,IAAI,MAAM,IAAI,MAAM,CAAC,iBAAiB,KAAK,SAAS,CAAA;IAEvF,oEAAoE;IACpE,MAAM,aAAa,GAAG,MAAM,KAAK,QAAQ,CAAA;IACzC,MAAM,8BAA8B,GAAG,aAAa,CAAA;IAEpD,MAAM,UAAU,GAAG;QACjB,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,IAAI,8BAA8B;QACzF,yBAAyB,EAAE,MAAM,CAAC,yBAAyB,IAAI,KAAK;QACpE,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;QACjD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB;QACvD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,yBAAyB,EAAE,MAAM,CAAC,yBAAyB;QAC3D,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,2BAA2B,EAAE,MAAM,CAAC,2BAA2B;QAC/D,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;KAClB,CAAA;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,iCAAiC;QACjC,OAAO;YACL,GAAG,UAAU;YACb,MAAM,EAAE,MAAkC;YAC1C,qFAAqF;YACrF,iBAAiB,EAAG,MAAqC,CAAC,iBAAiB;SAC5E,CAAA;IACH,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,eAAe;QACf,OAAO;YACL,GAAG,UAAU;YACb,MAAM,EAAE,QAAiB;SAC1B,CAAA;IACH,CAAC;IAED,sBAAsB;IACtB,OAAO;QACL,GAAG,UAAU;QACb,MAAM,EAAE,KAAc;KACvB,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"restContractBuilder.js","sourceRoot":"","sources":["../../src/rest/restContractBuilder.ts"],"names":[],"mappings":"AA+RA,iBAAiB;AACjB,MAAM,UAAU,iBAAiB,CAC/B,MAKsE;IAGtE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC5B,MAAM,OAAO,GAAG,mBAAmB,IAAI,MAAM,IAAI,MAAM,CAAC,iBAAiB,KAAK,SAAS,CAAA;IAEvF,oEAAoE;IACpE,MAAM,aAAa,GAAG,MAAM,KAAK,QAAQ,CAAA;IACzC,MAAM,8BAA8B,GAAG,aAAa,CAAA;IAEpD,MAAM,UAAU,GAAG;QACjB,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,IAAI,8BAA8B;QACzF,yBAAyB,EAAE,MAAM,CAAC,yBAAyB,IAAI,KAAK;QACpE,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;QACjD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB;QACvD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,yBAAyB,EAAE,MAAM,CAAC,yBAAyB;QAC3D,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,2BAA2B,EAAE,MAAM,CAAC,2BAA2B;QAC/D,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;KAClB,CAAA;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,iCAAiC;QACjC,OAAO;YACL,GAAG,UAAU;YACb,MAAM,EAAE,MAAkC;YAC1C,qFAAqF;YACrF,iBAAiB,EAAG,MAAqC,CAAC,iBAAiB;SAC5E,CAAA;IACH,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,eAAe;QACf,OAAO;YACL,GAAG,UAAU;YACb,MAAM,EAAE,QAAiB;SAC1B,CAAA;IACH,CAAC;IAED,sBAAsB;IACtB,OAAO;QACL,GAAG,UAAU;QACb,MAAM,EAAE,KAAc;KACvB,CAAA;AACH,CAAC"}
@@ -5,13 +5,13 @@ import type { SSEMethod } from './sseContracts.ts';
5
5
  import type { SSEEventSchemas } from './sseTypes.ts';
6
6
  /**
7
7
  * Definition for a dual-mode route.
8
- * Use `syncResponseBody` for the non-streaming response schema.
8
+ * Use `successResponseBodySchema` for the non-streaming response schema.
9
9
  *
10
10
  * @template Method - HTTP method (GET, POST, PUT, PATCH)
11
11
  * @template Params - Path parameters schema
12
12
  * @template Query - Query string parameters schema
13
13
  * @template RequestHeaders - Request headers schema
14
- * @template Body - Request requestBody schema (for POST/PUT/PATCH)
14
+ * @template Body - Request body schema (for POST/PUT/PATCH)
15
15
  * @template SyncResponse - Sync response schema (for Accept: application/json)
16
16
  * @template Events - SSE event schemas (for Accept: text/event-stream)
17
17
  * @template ResponseHeaders - Response headers schema (for sync mode)
@@ -20,27 +20,27 @@ import type { SSEEventSchemas } from './sseTypes.ts';
20
20
  export type DualModeContractDefinition<Method extends SSEMethod = SSEMethod, Params extends z.ZodTypeAny = z.ZodTypeAny, Query extends z.ZodTypeAny = z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny = z.ZodTypeAny, 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
22
  pathResolver: RoutePathResolver<z.infer<Params>>;
23
- params: Params;
24
- query: Query;
25
- requestHeaders: RequestHeaders;
26
- requestBody: Body;
23
+ requestPathParamsSchema: Params;
24
+ requestQuerySchema: Query;
25
+ requestHeaderSchema: RequestHeaders;
26
+ requestBodySchema: Body;
27
27
  /** Sync response schema - use with `sync` handler */
28
- syncResponseBody: SyncResponse;
29
- responseHeaders?: ResponseHeaders;
28
+ successResponseBodySchema: SyncResponse;
29
+ responseHeaderSchema?: ResponseHeaders;
30
30
  /**
31
31
  * Alternative response schemas by HTTP status code.
32
32
  * Used to define different response shapes for error cases (e.g., 400, 404, 500).
33
33
  *
34
34
  * @example
35
35
  * ```ts
36
- * responseSchemasByStatusCode: {
36
+ * responseBodySchemasByStatusCode: {
37
37
  * 400: z.object({ error: z.string(), details: z.array(z.string()) }),
38
38
  * 404: z.object({ error: z.string() }),
39
39
  * }
40
40
  * ```
41
41
  */
42
- responseSchemasByStatusCode?: ResponseSchemasByStatusCode;
43
- sseEvents: Events;
42
+ responseBodySchemasByStatusCode?: ResponseSchemasByStatusCode;
43
+ serverSentEventSchemas: Events;
44
44
  isDualMode: true;
45
45
  };
46
46
  /**
@@ -50,14 +50,14 @@ export type DualModeContractDefinition<Method extends SSEMethod = SSEMethod, Par
50
50
  export type AnyDualModeContractDefinition = {
51
51
  method: SSEMethod;
52
52
  pathResolver: RoutePathResolver<any>;
53
- params: z.ZodTypeAny;
54
- query: z.ZodTypeAny;
55
- requestHeaders: z.ZodTypeAny;
56
- requestBody: z.ZodTypeAny | undefined;
57
- /** Sync response schema */
58
- syncResponseBody: z.ZodTypeAny;
59
- responseHeaders?: z.ZodTypeAny;
60
- responseSchemasByStatusCode?: Partial<Record<HttpStatusCode, z.ZodTypeAny>>;
61
- sseEvents: SSEEventSchemas;
53
+ requestPathParamsSchema: z.ZodTypeAny;
54
+ requestQuerySchema: z.ZodTypeAny;
55
+ requestHeaderSchema: z.ZodTypeAny;
56
+ requestBodySchema: z.ZodTypeAny | undefined;
57
+ /** Sync response schema - use with `sync` handler */
58
+ successResponseBodySchema: z.ZodTypeAny;
59
+ responseHeaderSchema?: z.ZodTypeAny;
60
+ responseBodySchemasByStatusCode?: Partial<Record<HttpStatusCode, z.ZodTypeAny>>;
61
+ serverSentEventSchemas: SSEEventSchemas;
62
62
  isDualMode: true;
63
63
  };
@@ -6,14 +6,14 @@ import type { SSEContractDefinition } from './sseContracts.ts';
6
6
  import type { SSEEventSchemas } from './sseTypes.ts';
7
7
  /**
8
8
  * Configuration for building a GET SSE route.
9
- * Forbids requestBody for GET variants.
9
+ * Forbids requestBodySchema for GET variants.
10
10
  */
11
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> = {
12
12
  pathResolver: RoutePathResolver<z.infer<Params>>;
13
- params: Params;
14
- query: Query;
15
- requestHeaders: RequestHeaders;
16
- sseEvents: Events;
13
+ requestPathParamsSchema: Params;
14
+ requestQuerySchema: Query;
15
+ requestHeaderSchema: RequestHeaders;
16
+ serverSentEventSchemas: Events;
17
17
  /**
18
18
  * Error response schemas by HTTP status code.
19
19
  * Used to define response shapes for errors that occur before streaming starts
@@ -21,28 +21,28 @@ export type SSEGetContractConfig<Params extends z.ZodTypeAny, Query extends z.Zo
21
21
  *
22
22
  * @example
23
23
  * ```ts
24
- * responseSchemasByStatusCode: {
24
+ * responseBodySchemasByStatusCode: {
25
25
  * 401: z.object({ error: z.literal('Unauthorized') }),
26
26
  * 404: z.object({ error: z.string() }),
27
27
  * }
28
28
  * ```
29
29
  */
30
- responseSchemasByStatusCode?: ResponseSchemasByStatusCode;
31
- requestBody?: never;
32
- syncResponseBody?: never;
30
+ responseBodySchemasByStatusCode?: ResponseSchemasByStatusCode;
31
+ requestBodySchema?: never;
32
+ successResponseBodySchema?: never;
33
33
  };
34
34
  /**
35
- * Configuration for building a POST/PUT/PATCH SSE route with request requestBody.
36
- * Requires requestBody for payload variants.
35
+ * Configuration for building a POST/PUT/PATCH SSE route with request body.
36
+ * Requires requestBodySchema for payload variants.
37
37
  */
38
38
  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> = {
39
39
  method?: 'post' | 'put' | 'patch';
40
40
  pathResolver: RoutePathResolver<z.infer<Params>>;
41
- params: Params;
42
- query: Query;
43
- requestHeaders: RequestHeaders;
44
- requestBody: Body;
45
- sseEvents: Events;
41
+ requestPathParamsSchema: Params;
42
+ requestQuerySchema: Query;
43
+ requestHeaderSchema: RequestHeaders;
44
+ requestBodySchema: Body;
45
+ serverSentEventSchemas: Events;
46
46
  /**
47
47
  * Error response schemas by HTTP status code.
48
48
  * Used to define response shapes for errors that occur before streaming starts
@@ -50,95 +50,95 @@ export type SSEPayloadContractConfig<Params extends z.ZodTypeAny, Query extends
50
50
  *
51
51
  * @example
52
52
  * ```ts
53
- * responseSchemasByStatusCode: {
53
+ * responseBodySchemasByStatusCode: {
54
54
  * 401: z.object({ error: z.literal('Unauthorized') }),
55
55
  * 404: z.object({ error: z.string() }),
56
56
  * }
57
57
  * ```
58
58
  */
59
- responseSchemasByStatusCode?: ResponseSchemasByStatusCode;
60
- syncResponseBody?: never;
59
+ responseBodySchemasByStatusCode?: ResponseSchemasByStatusCode;
60
+ successResponseBodySchema?: never;
61
61
  };
62
62
  /**
63
63
  * Configuration for building a GET dual-mode route.
64
- * Requires syncResponseBody, forbids requestBody.
64
+ * Requires successResponseBodySchema, forbids requestBodySchema.
65
65
  */
66
66
  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> = {
67
67
  pathResolver: RoutePathResolver<z.infer<Params>>;
68
- params: Params;
69
- query: Query;
70
- requestHeaders: RequestHeaders;
68
+ requestPathParamsSchema: Params;
69
+ requestQuerySchema: Query;
70
+ requestHeaderSchema: RequestHeaders;
71
71
  /** Single sync response schema */
72
- syncResponseBody: JsonResponse;
72
+ successResponseBodySchema: JsonResponse;
73
73
  /**
74
74
  * Schema for validating response headers (sync mode only).
75
75
  * Used to define and validate headers that the server will send in the response.
76
76
  *
77
77
  * @example
78
78
  * ```ts
79
- * responseHeaders: z.object({
79
+ * responseHeaderSchema: z.object({
80
80
  * 'x-ratelimit-limit': z.string(),
81
81
  * 'x-ratelimit-remaining': z.string(),
82
82
  * })
83
83
  * ```
84
84
  */
85
- responseHeaders?: ResponseHeaders;
85
+ responseHeaderSchema?: ResponseHeaders;
86
86
  /**
87
87
  * Alternative response schemas by HTTP status code.
88
88
  * Used to define different response shapes for error cases.
89
89
  *
90
90
  * @example
91
91
  * ```ts
92
- * responseSchemasByStatusCode: {
92
+ * responseBodySchemasByStatusCode: {
93
93
  * 400: z.object({ error: z.string(), details: z.array(z.string()) }),
94
94
  * 404: z.object({ error: z.string() }),
95
95
  * }
96
96
  * ```
97
97
  */
98
- responseSchemasByStatusCode?: ResponseSchemasByStatusCode;
99
- sseEvents: Events;
100
- requestBody?: never;
98
+ responseBodySchemasByStatusCode?: ResponseSchemasByStatusCode;
99
+ serverSentEventSchemas: Events;
100
+ requestBodySchema?: never;
101
101
  };
102
102
  /**
103
- * Configuration for building a POST/PUT/PATCH dual-mode route with request requestBody.
104
- * Requires both requestBody and syncResponseBody.
103
+ * Configuration for building a POST/PUT/PATCH dual-mode route with request body.
104
+ * Requires both requestBodySchema and successResponseBodySchema.
105
105
  */
106
106
  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> = {
107
107
  method?: 'post' | 'put' | 'patch';
108
108
  pathResolver: RoutePathResolver<z.infer<Params>>;
109
- params: Params;
110
- query: Query;
111
- requestHeaders: RequestHeaders;
112
- requestBody: Body;
109
+ requestPathParamsSchema: Params;
110
+ requestQuerySchema: Query;
111
+ requestHeaderSchema: RequestHeaders;
112
+ requestBodySchema: Body;
113
113
  /** Single sync response schema */
114
- syncResponseBody: JsonResponse;
114
+ successResponseBodySchema: JsonResponse;
115
115
  /**
116
116
  * Schema for validating response headers (sync mode only).
117
117
  * Used to define and validate headers that the server will send in the response.
118
118
  *
119
119
  * @example
120
120
  * ```ts
121
- * responseHeaders: z.object({
121
+ * responseHeaderSchema: z.object({
122
122
  * 'x-ratelimit-limit': z.string(),
123
123
  * 'x-ratelimit-remaining': z.string(),
124
124
  * })
125
125
  * ```
126
126
  */
127
- responseHeaders?: ResponseHeaders;
127
+ responseHeaderSchema?: ResponseHeaders;
128
128
  /**
129
129
  * Alternative response schemas by HTTP status code.
130
130
  * Used to define different response shapes for error cases.
131
131
  *
132
132
  * @example
133
133
  * ```ts
134
- * responseSchemasByStatusCode: {
134
+ * responseBodySchemasByStatusCode: {
135
135
  * 400: z.object({ error: z.string(), details: z.array(z.string()) }),
136
136
  * 404: z.object({ error: z.string() }),
137
137
  * }
138
138
  * ```
139
139
  */
140
- responseSchemasByStatusCode?: ResponseSchemasByStatusCode;
141
- sseEvents: Events;
140
+ responseBodySchemasByStatusCode?: ResponseSchemasByStatusCode;
141
+ serverSentEventSchemas: Events;
142
142
  };
143
143
  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>;
144
144
  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>;
@@ -12,10 +12,10 @@
12
12
  * This is ideal for AI/LLM APIs (like OpenAI) where clients can choose between
13
13
  * getting the full response at once or streaming it token-by-token.
14
14
  *
15
- * The contract type is automatically determined based on the presence of `syncResponseBody`:
15
+ * The contract type is automatically determined based on the presence of `successResponseBodySchema`:
16
16
  *
17
- * | `syncResponseBody` | `requestBody` | Result |
18
- * |--------------------|---------------|--------|
17
+ * | `successResponseBodySchema` | `requestBodySchema` | Result |
18
+ * |----------------------------|---------------------|--------|
19
19
  * | ❌ | ❌ | SSE-only GET |
20
20
  * | ❌ | ✅ | SSE-only POST/PUT/PATCH |
21
21
  * | ✅ | ❌ | Dual-mode GET |
@@ -26,10 +26,10 @@
26
26
  * // SSE-only: Pure streaming endpoint (e.g., live notifications)
27
27
  * const notificationsStream = buildSseContract({
28
28
  * pathResolver: () => '/api/notifications/stream',
29
- * params: z.object({}),
30
- * query: z.object({ userId: z.string().optional() }),
31
- * requestHeaders: z.object({}),
32
- * sseEvents: {
29
+ * requestPathParamsSchema: z.object({}),
30
+ * requestQuerySchema: z.object({ userId: z.string().optional() }),
31
+ * requestHeaderSchema: z.object({}),
32
+ * serverSentEventSchemas: {
33
33
  * notification: z.object({ id: z.string(), message: z.string() }),
34
34
  * },
35
35
  * })
@@ -40,12 +40,12 @@
40
40
  * const chatCompletion = buildSseContract({
41
41
  * method: 'POST',
42
42
  * pathResolver: () => '/api/chat/completions',
43
- * params: z.object({}),
44
- * query: z.object({}),
45
- * requestHeaders: z.object({}),
46
- * requestBody: z.object({ message: z.string() }),
47
- * syncResponseBody: z.object({ reply: z.string(), usage: z.object({ tokens: z.number() }) }),
48
- * sseEvents: {
43
+ * requestPathParamsSchema: z.object({}),
44
+ * requestQuerySchema: z.object({}),
45
+ * requestHeaderSchema: z.object({}),
46
+ * requestBodySchema: z.object({ message: z.string() }),
47
+ * successResponseBodySchema: z.object({ reply: z.string(), usage: z.object({ tokens: z.number() }) }),
48
+ * serverSentEventSchemas: {
49
49
  * chunk: z.object({ delta: z.string() }),
50
50
  * done: z.object({ usage: z.object({ total: z.number() }) }),
51
51
  * },
@@ -57,11 +57,11 @@
57
57
  function buildBaseFields(config, hasBody) {
58
58
  return {
59
59
  pathResolver: config.pathResolver,
60
- params: config.params,
61
- query: config.query,
62
- requestHeaders: config.requestHeaders,
63
- requestBody: hasBody ? config.requestBody : undefined,
64
- sseEvents: config.sseEvents,
60
+ requestPathParamsSchema: config.requestPathParamsSchema,
61
+ requestQuerySchema: config.requestQuerySchema,
62
+ requestHeaderSchema: config.requestHeaderSchema,
63
+ requestBodySchema: hasBody ? config.requestBodySchema : undefined,
64
+ serverSentEventSchemas: config.serverSentEventSchemas,
65
65
  };
66
66
  }
67
67
  // Helper to determine method
@@ -70,18 +70,19 @@ function determineMethod(config, hasBody, defaultMethod) {
70
70
  }
71
71
  // Implementation
72
72
  export function buildSseContract(config) {
73
- const hasSyncResponseBody = 'syncResponseBody' in config && config.syncResponseBody !== undefined;
74
- const hasBody = 'requestBody' in config && config.requestBody !== undefined;
73
+ const hasSyncResponseBody = 'successResponseBodySchema' in config && config.successResponseBodySchema !== undefined;
74
+ const hasBody = 'requestBodySchema' in config && config.requestBodySchema !== undefined;
75
75
  const base = buildBaseFields(config, hasBody);
76
76
  if (hasSyncResponseBody) {
77
77
  // Dual-mode contract
78
78
  return {
79
79
  ...base,
80
80
  method: determineMethod(config, hasBody, 'post'),
81
- syncResponseBody: config.syncResponseBody,
82
- responseHeaders: config.responseHeaders,
83
- responseSchemasByStatusCode: config
84
- .responseSchemasByStatusCode,
81
+ successResponseBodySchema: config
82
+ .successResponseBodySchema,
83
+ responseHeaderSchema: config.responseHeaderSchema,
84
+ responseBodySchemasByStatusCode: config
85
+ .responseBodySchemasByStatusCode,
85
86
  isDualMode: true,
86
87
  };
87
88
  }
@@ -89,8 +90,8 @@ export function buildSseContract(config) {
89
90
  return {
90
91
  ...base,
91
92
  method: determineMethod(config, hasBody, 'post'),
92
- responseSchemasByStatusCode: config
93
- .responseSchemasByStatusCode,
93
+ responseBodySchemasByStatusCode: config
94
+ .responseBodySchemasByStatusCode,
94
95
  isSSE: true,
95
96
  };
96
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sseContractBuilders.js","sourceRoot":"","sources":["../../src/sse/sseContractBuilders.ts"],"names":[],"mappings":"AAyLA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,uCAAuC;AACvC,gEAAgE;AAChE,SAAS,eAAe,CAAC,MAAW,EAAE,OAAgB;IACpD,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;QACrD,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAA;AACH,CAAC;AAED,6BAA6B;AAC7B,SAAS,eAAe,CAAC,MAA2B,EAAE,OAAgB,EAAE,aAAqB;IAC3F,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAC3D,CAAC;AAwHD,iBAAiB;AACjB,MAAM,UAAU,gBAAgB,CAC9B,MAOiD;IAGjD,MAAM,mBAAmB,GAAG,kBAAkB,IAAI,MAAM,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS,CAAA;IACjG,MAAM,OAAO,GAAG,aAAa,IAAI,MAAM,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,CAAA;IAC3E,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE7C,IAAI,mBAAmB,EAAE,CAAC;QACxB,qBAAqB;QACrB,OAAO;YACL,GAAG,IAAI;YACP,MAAM,EAAE,eAAe,CAAC,MAA6B,EAAE,OAAO,EAAE,MAAM,CAAC;YACvE,gBAAgB,EAAG,MAAwC,CAAC,gBAAgB;YAC5E,eAAe,EAAG,MAAwC,CAAC,eAAe;YAC1E,2BAA2B,EAAG,MAAoD;iBAC/E,2BAA2B;YAC9B,UAAU,EAAE,IAAI;SACjB,CAAA;IACH,CAAC;IAED,oBAAoB;IACpB,OAAO;QACL,GAAG,IAAI;QACP,MAAM,EAAE,eAAe,CAAC,MAA6B,EAAE,OAAO,EAAE,MAAM,CAAC;QACvE,2BAA2B,EAAG,MAAoD;aAC/E,2BAA2B;QAC9B,KAAK,EAAE,IAAI;KACZ,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"sseContractBuilders.js","sourceRoot":"","sources":["../../src/sse/sseContractBuilders.ts"],"names":[],"mappings":"AAyLA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,uCAAuC;AACvC,gEAAgE;AAChE,SAAS,eAAe,CAAC,MAAW,EAAE,OAAgB;IACpD,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,uBAAuB,EAAE,MAAM,CAAC,uBAAuB;QACvD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,iBAAiB,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS;QACjE,sBAAsB,EAAE,MAAM,CAAC,sBAAsB;KACtD,CAAA;AACH,CAAC;AAED,6BAA6B;AAC7B,SAAS,eAAe,CAAC,MAA2B,EAAE,OAAgB,EAAE,aAAqB;IAC3F,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAC3D,CAAC;AAwHD,iBAAiB;AACjB,MAAM,UAAU,gBAAgB,CAC9B,MAOiD;IAGjD,MAAM,mBAAmB,GACvB,2BAA2B,IAAI,MAAM,IAAI,MAAM,CAAC,yBAAyB,KAAK,SAAS,CAAA;IACzF,MAAM,OAAO,GAAG,mBAAmB,IAAI,MAAM,IAAI,MAAM,CAAC,iBAAiB,KAAK,SAAS,CAAA;IACvF,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE7C,IAAI,mBAAmB,EAAE,CAAC;QACxB,qBAAqB;QACrB,OAAO;YACL,GAAG,IAAI;YACP,MAAM,EAAE,eAAe,CAAC,MAA6B,EAAE,OAAO,EAAE,MAAM,CAAC;YACvE,yBAAyB,EAAG,MAAiD;iBAC1E,yBAAyB;YAC5B,oBAAoB,EAAG,MAA6C,CAAC,oBAAoB;YACzF,+BAA+B,EAAG,MAAwD;iBACvF,+BAA+B;YAClC,UAAU,EAAE,IAAI;SACjB,CAAA;IACH,CAAC;IAED,oBAAoB;IACpB,OAAO;QACL,GAAG,IAAI;QACP,MAAM,EAAE,eAAe,CAAC,MAA6B,EAAE,OAAO,EAAE,MAAM,CAAC;QACvE,+BAA+B,EAAG,MAAwD;aACvF,+BAA+B;QAClC,KAAK,EAAE,IAAI;KACZ,CAAA;AACH,CAAC"}
@@ -15,7 +15,7 @@ export type SSEMethod = 'get' | 'post' | 'put' | 'patch';
15
15
  * @template Params - Path parameters schema
16
16
  * @template Query - Query string parameters schema
17
17
  * @template RequestHeaders - Request headers schema
18
- * @template Body - Request requestBody schema (for POST/PUT/PATCH)
18
+ * @template Body - Request body schema (for 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
  */
@@ -26,11 +26,11 @@ export type SSEContractDefinition<Method extends SSEMethod = SSEMethod, Params e
26
26
  * Receives typed params and returns the URL path string.
27
27
  */
28
28
  pathResolver: RoutePathResolver<z.infer<Params>>;
29
- params: Params;
30
- query: Query;
31
- requestHeaders: RequestHeaders;
32
- requestBody: Body;
33
- sseEvents: Events;
29
+ requestPathParamsSchema: Params;
30
+ requestQuerySchema: Query;
31
+ requestHeaderSchema: RequestHeaders;
32
+ requestBodySchema: Body;
33
+ serverSentEventSchemas: Events;
34
34
  /**
35
35
  * Error response schemas by HTTP status code.
36
36
  * Used to define response shapes for errors that occur before streaming starts
@@ -38,13 +38,13 @@ export type SSEContractDefinition<Method extends SSEMethod = SSEMethod, Params e
38
38
  *
39
39
  * @example
40
40
  * ```ts
41
- * responseSchemasByStatusCode: {
41
+ * responseBodySchemasByStatusCode: {
42
42
  * 401: z.object({ error: z.literal('Unauthorized') }),
43
43
  * 404: z.object({ error: z.string() }),
44
44
  * }
45
45
  * ```
46
46
  */
47
- responseSchemasByStatusCode?: ResponseSchemasByStatusCode;
47
+ responseBodySchemasByStatusCode?: ResponseSchemasByStatusCode;
48
48
  isSSE: true;
49
49
  };
50
50
  /**
@@ -54,11 +54,11 @@ export type SSEContractDefinition<Method extends SSEMethod = SSEMethod, Params e
54
54
  export type AnySSEContractDefinition = {
55
55
  method: SSEMethod;
56
56
  pathResolver: RoutePathResolver<any>;
57
- params: z.ZodTypeAny;
58
- query: z.ZodTypeAny;
59
- requestHeaders: z.ZodTypeAny;
60
- requestBody: z.ZodTypeAny | undefined;
61
- sseEvents: SSEEventSchemas;
62
- responseSchemasByStatusCode?: Partial<Record<HttpStatusCode, z.ZodTypeAny>>;
57
+ requestPathParamsSchema: z.ZodTypeAny;
58
+ requestQuerySchema: z.ZodTypeAny;
59
+ requestHeaderSchema: z.ZodTypeAny;
60
+ requestBodySchema: z.ZodTypeAny | undefined;
61
+ serverSentEventSchemas: SSEEventSchemas;
62
+ responseBodySchemasByStatusCode?: Partial<Record<HttpStatusCode, z.ZodTypeAny>>;
63
63
  isSSE: true;
64
64
  };
@@ -11,19 +11,19 @@ export type SSEEventSchemas = Record<string, z.ZodTypeAny>;
11
11
  * @example
12
12
  * ```typescript
13
13
  * type Contracts = {
14
- * notifications: { sseEvents: { alert: z.ZodObject<...> } }
15
- * chat: { sseEvents: { message: z.ZodObject<...>, done: z.ZodObject<...> } }
14
+ * notifications: { serverSentEventSchemas: { alert: z.ZodObject<...> } }
15
+ * chat: { serverSentEventSchemas: { message: z.ZodObject<...>, done: z.ZodObject<...> } }
16
16
  * }
17
17
  * // AllContractEventNames<Contracts> = 'alert' | 'message' | 'done'
18
18
  * ```
19
19
  */
20
- export type AllContractEventNames<Contracts extends Record<string, AnySSEContractDefinition>> = Contracts[keyof Contracts]['sseEvents'] extends infer E ? E extends SSEEventSchemas ? keyof E & string : never : never;
20
+ export type AllContractEventNames<Contracts extends Record<string, AnySSEContractDefinition>> = Contracts[keyof Contracts]['serverSentEventSchemas'] extends infer E ? E extends SSEEventSchemas ? keyof E & string : never : never;
21
21
  /**
22
22
  * Extract the schema for a specific event name across all contracts.
23
23
  * Returns the Zod schema for the event, or never if not found.
24
24
  */
25
25
  export type ExtractEventSchema<Contracts extends Record<string, AnySSEContractDefinition>, EventName extends string> = {
26
- [K in keyof Contracts]: EventName extends keyof Contracts[K]['sseEvents'] ? Contracts[K]['sseEvents'][EventName] : never;
26
+ [K in keyof Contracts]: EventName extends keyof Contracts[K]['serverSentEventSchemas'] ? Contracts[K]['serverSentEventSchemas'][EventName] : never;
27
27
  }[keyof Contracts];
28
28
  /**
29
29
  * Flatten all events from all contracts into a single record.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lokalise/api-contracts",
3
- "version": "6.3.0",
3
+ "version": "6.5.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],