@lokalise/api-contracts 6.11.0 → 6.13.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 +112 -26
- package/dist/HttpStatusCodes.d.ts +38 -1
- package/dist/HttpStatusCodes.js +14 -0
- package/dist/HttpStatusCodes.js.map +1 -1
- package/dist/new/clientTypes.d.ts +51 -7
- package/dist/new/contractResponse.d.ts +22 -8
- package/dist/new/contractResponse.js +44 -10
- package/dist/new/contractResponse.js.map +1 -1
- package/dist/new/defineApiContract.d.ts +2 -0
- package/dist/new/defineApiContract.js +6 -3
- package/dist/new/defineApiContract.js.map +1 -1
- package/dist/new/inferTypes.d.ts +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ This eliminates assumptions across the boundary and keeps documentation, validat
|
|
|
12
12
|
### REST routes
|
|
13
13
|
|
|
14
14
|
```ts
|
|
15
|
-
import { defineApiContract,
|
|
15
|
+
import { defineApiContract, noBodyResponse } from '@lokalise/api-contracts'
|
|
16
16
|
import { z } from 'zod/v4'
|
|
17
17
|
|
|
18
18
|
// GET with path params
|
|
@@ -41,7 +41,7 @@ const deleteUser = defineApiContract({
|
|
|
41
41
|
requestPathParamsSchema: z.object({ userId: z.uuid() }),
|
|
42
42
|
pathResolver: ({ userId }) => `/users/${userId}`,
|
|
43
43
|
responsesByStatusCode: {
|
|
44
|
-
204:
|
|
44
|
+
204: noBodyResponse(),
|
|
45
45
|
},
|
|
46
46
|
})
|
|
47
47
|
```
|
|
@@ -121,6 +121,87 @@ const chatCompletion = defineApiContract({
|
|
|
121
121
|
})
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
+
### Wildcard and default response keys
|
|
125
|
+
|
|
126
|
+
In addition to exact status codes, `responsesByStatusCode` accepts OpenAPI-style range keys (`'1xx'`–`'5xx'`) and `'default'` as fallbacks.
|
|
127
|
+
|
|
128
|
+
Lookup precedence at runtime: **exact code → range key → `'default'`**.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { defineApiContract } from '@lokalise/api-contracts'
|
|
132
|
+
import { z } from 'zod/v4'
|
|
133
|
+
|
|
134
|
+
// '2xx' covers all 200–299 responses
|
|
135
|
+
const listItems = defineApiContract({
|
|
136
|
+
method: 'get',
|
|
137
|
+
pathResolver: () => '/items',
|
|
138
|
+
responsesByStatusCode: {
|
|
139
|
+
'2xx': z.object({ items: z.array(z.string()) }),
|
|
140
|
+
'4xx': z.object({ message: z.string() }),
|
|
141
|
+
},
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// exact code takes precedence over the range key
|
|
145
|
+
const createItem = defineApiContract({
|
|
146
|
+
method: 'post',
|
|
147
|
+
pathResolver: () => '/items',
|
|
148
|
+
requestBodySchema: z.object({ name: z.string() }),
|
|
149
|
+
responsesByStatusCode: {
|
|
150
|
+
201: z.object({ id: z.string() }),
|
|
151
|
+
'4xx': z.object({ message: z.string() }),
|
|
152
|
+
},
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
// 'default' matches any status code not covered by a more specific entry
|
|
156
|
+
const flexible = defineApiContract({
|
|
157
|
+
method: 'get',
|
|
158
|
+
pathResolver: () => '/data',
|
|
159
|
+
responsesByStatusCode: {
|
|
160
|
+
200: z.object({ data: z.unknown() }),
|
|
161
|
+
default: z.object({ error: z.string() }),
|
|
162
|
+
},
|
|
163
|
+
})
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The `'2xx'` range key participates in SSE detection and success/error type narrowing exactly like explicit 2xx codes: `InferNonSseClientResponse` maps it to `SuccessfulHttpStatusCode`, and `hasAnySuccessSseResponse` returns `true` when it holds an SSE schema.
|
|
167
|
+
|
|
168
|
+
`'default'` is split into a success half (`SuccessfulHttpStatusCode`) and a non-success half in `InferSseClientResponse` / `InferNonSseClientResponse` so that `captureAsError` type narrowing stays correct regardless of the actual status code.
|
|
169
|
+
|
|
170
|
+
### OpenAPI response descriptions
|
|
171
|
+
|
|
172
|
+
All response factories accept an optional `ResponseOptions` object as their last argument.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import {
|
|
176
|
+
defineApiContract,
|
|
177
|
+
noBodyResponse,
|
|
178
|
+
textResponse,
|
|
179
|
+
blobResponse,
|
|
180
|
+
sseResponse,
|
|
181
|
+
anyOfResponses,
|
|
182
|
+
} from '@lokalise/api-contracts'
|
|
183
|
+
import { z } from 'zod/v4'
|
|
184
|
+
|
|
185
|
+
const contract = defineApiContract({
|
|
186
|
+
method: 'post',
|
|
187
|
+
pathResolver: () => '/files',
|
|
188
|
+
requestBodySchema: z.object({ name: z.string() }),
|
|
189
|
+
responsesByStatusCode: {
|
|
190
|
+
201: z.object({ id: z.string() }).describe('Created resource'),
|
|
191
|
+
204: noBodyResponse({ description: 'Deleted — no content returned' }),
|
|
192
|
+
200: anyOfResponses(
|
|
193
|
+
[
|
|
194
|
+
z.object({ id: z.string() }).describe('JSON representation'),
|
|
195
|
+
textResponse('text/csv', { description: 'CSV export' }),
|
|
196
|
+
blobResponse('application/pdf', { description: 'PDF report' }),
|
|
197
|
+
sseResponse({ update: z.object({ id: z.string() }) }, { description: 'Live update stream' }),
|
|
198
|
+
],
|
|
199
|
+
{ description: 'Multiple response formats available' },
|
|
200
|
+
),
|
|
201
|
+
},
|
|
202
|
+
})
|
|
203
|
+
```
|
|
204
|
+
|
|
124
205
|
`getSseSchemaByEventName(contract)` extracts SSE event schemas from a contract:
|
|
125
206
|
|
|
126
207
|
```ts
|
|
@@ -136,31 +217,36 @@ getSseSchemaByEventName(chatCompletion)
|
|
|
136
217
|
### All fields
|
|
137
218
|
|
|
138
219
|
```ts
|
|
139
|
-
|
|
220
|
+
type ApiContractOptions = {
|
|
140
221
|
// Required
|
|
141
|
-
method: 'get' | 'post' | 'put' | 'patch' | 'delete'
|
|
142
|
-
pathResolver: (pathParams) => string
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
222
|
+
method: 'get' | 'post' | 'put' | 'patch' | 'delete'
|
|
223
|
+
pathResolver: (pathParams: Record<string, string>) => string
|
|
224
|
+
// Accepts exact codes, OpenAPI-style range keys ('1xx'–'5xx'), and a catch-all 'default'.
|
|
225
|
+
// Lookup precedence at runtime: exact code → range key → 'default'.
|
|
226
|
+
responsesByStatusCode: Partial<
|
|
227
|
+
Record<
|
|
228
|
+
HttpStatusCode | '1xx' | '2xx' | '3xx' | '4xx' | '5xx' | 'default',
|
|
229
|
+
z.ZodType | NoBodyResponse | TypedTextResponse | TypedBlobResponse | TypedSseResponse | AnyOfResponses
|
|
230
|
+
>
|
|
231
|
+
>
|
|
146
232
|
|
|
147
233
|
// Path params — links pathResolver parameter type to the schema
|
|
148
|
-
requestPathParamsSchema
|
|
234
|
+
requestPathParamsSchema?: z.ZodObject<z.ZodRawShape>
|
|
149
235
|
|
|
150
236
|
// Request
|
|
151
|
-
requestBodySchema
|
|
152
|
-
requestQuerySchema
|
|
153
|
-
requestHeaderSchema
|
|
237
|
+
requestBodySchema?: z.ZodType | ContractNoBody // required for POST / PUT / PATCH, forbidden otherwise
|
|
238
|
+
requestQuerySchema?: z.ZodObject<z.ZodRawShape>
|
|
239
|
+
requestHeaderSchema?: z.ZodObject<z.ZodRawShape>
|
|
154
240
|
|
|
155
241
|
// Response
|
|
156
|
-
responseHeaderSchema
|
|
242
|
+
responseHeaderSchema?: z.ZodObject<z.ZodRawShape>
|
|
157
243
|
|
|
158
244
|
// Documentation
|
|
159
|
-
summary
|
|
160
|
-
description
|
|
161
|
-
tags
|
|
162
|
-
metadata
|
|
163
|
-
}
|
|
245
|
+
summary?: string
|
|
246
|
+
description?: string
|
|
247
|
+
tags?: readonly string[]
|
|
248
|
+
metadata?: Record<string, unknown>
|
|
249
|
+
}
|
|
164
250
|
```
|
|
165
251
|
|
|
166
252
|
### Header schemas
|
|
@@ -185,7 +271,7 @@ const contract = defineApiContract({
|
|
|
185
271
|
|
|
186
272
|
### Type utilities
|
|
187
273
|
|
|
188
|
-
**`InferNonSseSuccessResponses<T>`** — TypeScript output type of all non-SSE 2xx responses. JSON schemas → `z.output<T>`, `textResponse` → `string`, `blobResponse` → `Blob`, `ContractNoBody` → `undefined`, `sseResponse` → `never` (excluded). `anyOfResponses` entries are unpacked before mapping.
|
|
274
|
+
**`InferNonSseSuccessResponses<T>`** — TypeScript output type of all non-SSE 2xx responses. JSON schemas → `z.output<T>`, `textResponse` → `string`, `blobResponse` → `Blob`, `ContractNoBody`/`NoBodyResponse` → `undefined`, `sseResponse` → `never` (excluded). `anyOfResponses` entries are unpacked before mapping.
|
|
189
275
|
|
|
190
276
|
```ts
|
|
191
277
|
import type { InferNonSseSuccessResponses } from '@lokalise/api-contracts'
|
|
@@ -201,13 +287,13 @@ type CsvResponse = InferNonSseSuccessResponses<typeof exportCsv['responsesByStat
|
|
|
201
287
|
|
|
202
288
|
**`InferSseSuccessResponses<T>`** — extracts the SSE event schema map type from a `responsesByStatusCode` map. Returns `never` when no SSE schemas are present.
|
|
203
289
|
|
|
204
|
-
**`HasAnySseSuccessResponse<T>`** — `true` if any 2xx entry is a `TypedSseResponse` or an `AnyOfResponses` containing one.
|
|
290
|
+
**`HasAnySseSuccessResponse<T>`** — `true` if any 2xx entry (exact code or `'2xx'` range key) is a `TypedSseResponse` or an `AnyOfResponses` containing one.
|
|
205
291
|
|
|
206
292
|
**`HasAnyJsonSuccessResponse<T>`** — `true` if any 2xx entry is a JSON Zod schema or an `AnyOfResponses` containing one.
|
|
207
293
|
|
|
208
294
|
**`HasAnyNonSseSuccessResponse<T>`** — `true` if any 2xx entry is a non-SSE response (JSON, text, blob, or no-body).
|
|
209
295
|
|
|
210
|
-
**`IsNoBodySuccessResponse<T>`** — `true` when all 2xx entries are `ContractNoBody` or no 2xx status codes are defined.
|
|
296
|
+
**`IsNoBodySuccessResponse<T>`** — `true` when all 2xx entries are `ContractNoBody`/`NoBodyResponse` or no 2xx status codes are defined.
|
|
211
297
|
|
|
212
298
|
**`ContractResponseMode<T>`** — classifies a contract into `'dual'` (SSE + non-SSE), `'sse'` (SSE-only), or `'non-sse'` (JSON/text/blob/no-body).
|
|
213
299
|
|
|
@@ -229,9 +315,9 @@ These types are primarily consumed by HTTP client implementations.
|
|
|
229
315
|
|
|
230
316
|
**`ClientRequestParams<TApiContract, TIsStreaming>`** — infers the request parameter object for a contract. Includes `pathParams`, `body`, `queryParams`, `headers` (required when the corresponding schema is defined), `pathPrefix` (always optional), and `streaming` (required for dual-mode contracts, forbidden otherwise).
|
|
231
317
|
|
|
232
|
-
**`InferSseClientResponse<TApiContract>`** — discriminated union of `{ statusCode, headers, body }` for SSE mode.
|
|
318
|
+
**`InferSseClientResponse<TApiContract>`** — discriminated union of `{ statusCode, headers, body }` for SSE mode. Exact 2xx codes and the `'2xx'` range key yield `AsyncIterable<SseEventOf<...>>`; error codes, other range keys, and `'default'` yield the declared body type. `'default'` is split into a `SuccessfulHttpStatusCode` half and a non-success half.
|
|
233
319
|
|
|
234
|
-
**`InferNonSseClientResponse<TApiContract>`** — same shape as above for non-SSE mode.
|
|
320
|
+
**`InferNonSseClientResponse<TApiContract>`** — same shape as above for non-SSE mode. Exact 2xx codes and the `'2xx'` range key yield JSON / `string` / `Blob` / `null` (SSE excluded); error codes, other range keys, and `'default'` yield the declared body type as-is. `'default'` is split the same way.
|
|
235
321
|
|
|
236
322
|
**`DefaultStreaming<T>`** — `true` for SSE-only contracts, `false` for everything else.
|
|
237
323
|
|
|
@@ -271,7 +357,7 @@ import { describeApiContract } from '@lokalise/api-contracts'
|
|
|
271
357
|
describeApiContract(getUser) // "GET /users/:userId"
|
|
272
358
|
```
|
|
273
359
|
|
|
274
|
-
**`getSuccessResponseSchema`** — merged Zod schema from all 2xx JSON entries. `ContractNoBody` and non-JSON entries are excluded. Returns `null` when no schema is present.
|
|
360
|
+
**`getSuccessResponseSchema`** *(deprecated — no known consumers, will be removed in a future release)* — merged Zod schema from all 2xx JSON entries. `ContractNoBody`/`NoBodyResponse` and non-JSON entries are excluded. Returns `null` when no schema is present.
|
|
275
361
|
|
|
276
362
|
```ts
|
|
277
363
|
import { getSuccessResponseSchema } from '@lokalise/api-contracts'
|
|
@@ -280,7 +366,7 @@ getSuccessResponseSchema(getUser) // ZodObject
|
|
|
280
366
|
getSuccessResponseSchema(deleteUser) // null
|
|
281
367
|
```
|
|
282
368
|
|
|
283
|
-
**`getIsEmptyResponseExpected`** — `true` when no Zod schema exists among 2xx entries.
|
|
369
|
+
**`getIsEmptyResponseExpected`** *(deprecated — no known consumers, will be removed in a future release)* — `true` when no Zod schema exists among 2xx entries.
|
|
284
370
|
|
|
285
371
|
```ts
|
|
286
372
|
import { getIsEmptyResponseExpected } from '@lokalise/api-contracts'
|
|
@@ -289,7 +375,7 @@ getIsEmptyResponseExpected(deleteUser) // true
|
|
|
289
375
|
getIsEmptyResponseExpected(getUser) // false
|
|
290
376
|
```
|
|
291
377
|
|
|
292
|
-
**`hasAnySuccessSseResponse`** — `true` when any 2xx entry is an SSE response (including inside `anyOfResponses`).
|
|
378
|
+
**`hasAnySuccessSseResponse`** — `true` when any 2xx entry (exact code or `'2xx'` range key) is an SSE response (including inside `anyOfResponses`).
|
|
293
379
|
|
|
294
380
|
```ts
|
|
295
381
|
import { hasAnySuccessSseResponse } from '@lokalise/api-contracts'
|
|
@@ -1,3 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
/** Tuple of all 1xx informational HTTP status codes. */
|
|
2
|
+
export declare const INFORMATIONAL_HTTP_STATUS_CODES: readonly [100, 101, 102, 103];
|
|
3
|
+
/** Union of all 1xx informational HTTP status codes. */
|
|
4
|
+
export type InformationalHttpStatusCode = (typeof INFORMATIONAL_HTTP_STATUS_CODES)[number];
|
|
5
|
+
/** Tuple of all 2xx successful HTTP status codes. */
|
|
2
6
|
export declare const SUCCESSFUL_HTTP_STATUS_CODES: readonly [200, 201, 202, 203, 204, 205, 206, 207, 208, 226];
|
|
7
|
+
/** Union of all 2xx successful HTTP status codes. */
|
|
3
8
|
export type SuccessfulHttpStatusCode = (typeof SUCCESSFUL_HTTP_STATUS_CODES)[number];
|
|
9
|
+
/** Tuple of all 3xx redirection HTTP status codes. */
|
|
10
|
+
export declare const REDIRECTION_HTTP_STATUS_CODES: readonly [300, 301, 302, 303, 304, 305, 306, 307, 308];
|
|
11
|
+
/** Union of all 3xx redirection HTTP status codes. */
|
|
12
|
+
export type RedirectionHttpStatusCode = (typeof REDIRECTION_HTTP_STATUS_CODES)[number];
|
|
13
|
+
/** Tuple of all 4xx client-error HTTP status codes. */
|
|
14
|
+
export declare const CLIENT_ERROR_HTTP_STATUS_CODES: readonly [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];
|
|
15
|
+
/** Union of all 4xx client-error HTTP status codes. */
|
|
16
|
+
export type ClientErrorHttpStatusCode = (typeof CLIENT_ERROR_HTTP_STATUS_CODES)[number];
|
|
17
|
+
/** Tuple of all 5xx server-error HTTP status codes. */
|
|
18
|
+
export declare const SERVER_ERROR_HTTP_STATUS_CODES: readonly [500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511];
|
|
19
|
+
/** Union of all 5xx server-error HTTP status codes. */
|
|
20
|
+
export type ServerErrorHttpStatusCode = (typeof SERVER_ERROR_HTTP_STATUS_CODES)[number];
|
|
21
|
+
/** Union of every standard HTTP status code across all classes (1xx–5xx). */
|
|
22
|
+
export type HttpStatusCode = InformationalHttpStatusCode | SuccessfulHttpStatusCode | RedirectionHttpStatusCode | ClientErrorHttpStatusCode | ServerErrorHttpStatusCode;
|
|
23
|
+
/** String representation of an HTTP status class. */
|
|
24
|
+
export type HttpStatusCodeRange = '1xx' | '2xx' | '3xx' | '4xx' | '5xx';
|
|
25
|
+
/** Range key or catch-all fallback. */
|
|
26
|
+
export type WildcardStatusCodeKey = HttpStatusCodeRange | 'default';
|
|
27
|
+
type RangeExpansion = {
|
|
28
|
+
'1xx': InformationalHttpStatusCode;
|
|
29
|
+
'2xx': SuccessfulHttpStatusCode;
|
|
30
|
+
'3xx': RedirectionHttpStatusCode;
|
|
31
|
+
'4xx': ClientErrorHttpStatusCode;
|
|
32
|
+
'5xx': ServerErrorHttpStatusCode;
|
|
33
|
+
default: HttpStatusCode;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Maps a `WildcardStatusCodeKey` to its concrete `HttpStatusCode` union.
|
|
37
|
+
* `'default'` expands to the full `HttpStatusCode` union.
|
|
38
|
+
*/
|
|
39
|
+
export type ExpandStatusRangeKey<K extends WildcardStatusCodeKey> = RangeExpansion[K];
|
|
40
|
+
export {};
|
package/dist/HttpStatusCodes.js
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
|
+
/** Tuple of all 1xx informational HTTP status codes. */
|
|
2
|
+
export const INFORMATIONAL_HTTP_STATUS_CODES = [100, 101, 102, 103];
|
|
3
|
+
/** Tuple of all 2xx successful HTTP status codes. */
|
|
1
4
|
export const SUCCESSFUL_HTTP_STATUS_CODES = [
|
|
2
5
|
200, 201, 202, 203, 204, 205, 206, 207, 208, 226,
|
|
3
6
|
];
|
|
7
|
+
/** Tuple of all 3xx redirection HTTP status codes. */
|
|
8
|
+
export const REDIRECTION_HTTP_STATUS_CODES = [300, 301, 302, 303, 304, 305, 306, 307, 308];
|
|
9
|
+
/** Tuple of all 4xx client-error HTTP status codes. */
|
|
10
|
+
export const CLIENT_ERROR_HTTP_STATUS_CODES = [
|
|
11
|
+
400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418,
|
|
12
|
+
421, 422, 423, 424, 425, 426, 428, 429, 431, 451,
|
|
13
|
+
];
|
|
14
|
+
/** Tuple of all 5xx server-error HTTP status codes. */
|
|
15
|
+
export const SERVER_ERROR_HTTP_STATUS_CODES = [
|
|
16
|
+
500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511,
|
|
17
|
+
];
|
|
4
18
|
//# sourceMappingURL=HttpStatusCodes.js.map
|
|
@@ -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":"AAAA,wDAAwD;AACxD,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAA;AAI5E,qDAAqD;AACrD,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;AAIV,sDAAsD;AACtD,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAA;AAInG,uDAAuD;AACvD,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAC7F,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACxC,CAAA;AAIV,uDAAuD;AACvD,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CAC7C,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { z } from 'zod/v4';
|
|
2
2
|
import type { InferSchemaInput, InferSchemaOutput } from '../apiContracts.ts';
|
|
3
|
-
import type { HttpStatusCode, SuccessfulHttpStatusCode } from '../HttpStatusCodes.ts';
|
|
3
|
+
import type { ExpandStatusRangeKey, HttpStatusCode, HttpStatusCodeRange, SuccessfulHttpStatusCode, WildcardStatusCodeKey } from '../HttpStatusCodes.ts';
|
|
4
4
|
import type { Prettify } from '../typeUtils.ts';
|
|
5
5
|
import type { ContractNoBody } from './constants.ts';
|
|
6
6
|
import type { ResponsesByStatusCode, SseSchemaByEventName } from './contractResponse.ts';
|
|
@@ -47,10 +47,47 @@ type SseInferClientResponseBody<T> = Extract<InferClientResponseBody<T>, AsyncIt
|
|
|
47
47
|
* Like InferClientResponseBody but returns only non-SSE bodies — SSE entries resolve to never.
|
|
48
48
|
*/
|
|
49
49
|
type NonSseInferClientResponseBody<T> = Exclude<InferClientResponseBody<T>, AsyncIterable<unknown>>;
|
|
50
|
+
type WildcardSseBody<V, K extends WildcardStatusCodeKey> = K extends '2xx' ? SseInferClientResponseBody<V> : InferClientResponseBody<V>;
|
|
51
|
+
type WildcardNonSseBody<V, K extends WildcardStatusCodeKey> = K extends '2xx' ? NonSseInferClientResponseBody<V> : InferClientResponseBody<V>;
|
|
52
|
+
type ExactStatusCodes<TApiContract extends ApiContract> = keyof TApiContract['responsesByStatusCode'] & HttpStatusCode;
|
|
53
|
+
type RangeStatusCodes<TApiContract extends ApiContract> = {
|
|
54
|
+
[K in keyof TApiContract['responsesByStatusCode'] & HttpStatusCodeRange]: ExpandStatusRangeKey<K>;
|
|
55
|
+
}[keyof TApiContract['responsesByStatusCode'] & HttpStatusCodeRange];
|
|
56
|
+
type DefaultSuccessStatusCodes<TApiContract extends ApiContract> = Exclude<SuccessfulHttpStatusCode, ExactStatusCodes<TApiContract> | RangeStatusCodes<TApiContract>>;
|
|
57
|
+
type DefaultNonSuccessStatusCodes<TApiContract extends ApiContract> = Exclude<Exclude<HttpStatusCode, SuccessfulHttpStatusCode>, ExactStatusCodes<TApiContract> | RangeStatusCodes<TApiContract>>;
|
|
58
|
+
type WildcardSseEntry<TApiContract extends ApiContract, K extends WildcardStatusCodeKey> = K extends 'default' ? {
|
|
59
|
+
statusCode: DefaultSuccessStatusCodes<TApiContract>;
|
|
60
|
+
headers: InferClientResponseHeaders<TApiContract>;
|
|
61
|
+
body: SseInferClientResponseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>>;
|
|
62
|
+
} | {
|
|
63
|
+
statusCode: DefaultNonSuccessStatusCodes<TApiContract>;
|
|
64
|
+
headers: InferClientResponseHeaders<TApiContract>;
|
|
65
|
+
body: InferClientResponseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>>;
|
|
66
|
+
} : {
|
|
67
|
+
statusCode: Exclude<ExpandStatusRangeKey<K>, ExactStatusCodes<TApiContract>>;
|
|
68
|
+
headers: InferClientResponseHeaders<TApiContract>;
|
|
69
|
+
body: WildcardSseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>, K>;
|
|
70
|
+
};
|
|
71
|
+
type WildcardNonSseEntry<TApiContract extends ApiContract, K extends WildcardStatusCodeKey> = K extends 'default' ? {
|
|
72
|
+
statusCode: DefaultSuccessStatusCodes<TApiContract>;
|
|
73
|
+
headers: InferClientResponseHeaders<TApiContract>;
|
|
74
|
+
body: NonSseInferClientResponseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>>;
|
|
75
|
+
} | {
|
|
76
|
+
statusCode: DefaultNonSuccessStatusCodes<TApiContract>;
|
|
77
|
+
headers: InferClientResponseHeaders<TApiContract>;
|
|
78
|
+
body: InferClientResponseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>>;
|
|
79
|
+
} : {
|
|
80
|
+
statusCode: Exclude<ExpandStatusRangeKey<K>, ExactStatusCodes<TApiContract>>;
|
|
81
|
+
headers: InferClientResponseHeaders<TApiContract>;
|
|
82
|
+
body: WildcardNonSseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>, K>;
|
|
83
|
+
};
|
|
50
84
|
/**
|
|
51
85
|
* Infers a discriminated union of `{ statusCode, headers, body }` for SSE mode:
|
|
52
|
-
* - success status codes → SSE body only (AsyncIterable)
|
|
53
|
-
* - error status codes
|
|
86
|
+
* - exact success status codes and `'2xx'` range → SSE body only (AsyncIterable)
|
|
87
|
+
* - error status codes, other ranges, and `'default'` → body as-is (all kinds)
|
|
88
|
+
*
|
|
89
|
+
* `'default'` is split into a success half (`SuccessfulHttpStatusCode`) and a non-success half
|
|
90
|
+
* so that `captureAsError` type narrowing stays correct regardless of the actual status code.
|
|
54
91
|
*
|
|
55
92
|
* Headers are typed via `InferClientResponseHeaders`: known headers from `responseHeaderSchema`
|
|
56
93
|
* are strongly typed; all other headers remain accessible as `string | undefined`.
|
|
@@ -61,11 +98,16 @@ export type InferSseClientResponse<TApiContract extends ApiContract> = {
|
|
|
61
98
|
headers: InferClientResponseHeaders<TApiContract>;
|
|
62
99
|
body: K extends SuccessfulHttpStatusCode ? SseInferClientResponseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>> : InferClientResponseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>>;
|
|
63
100
|
};
|
|
64
|
-
}[keyof TApiContract['responsesByStatusCode'] & HttpStatusCode]
|
|
101
|
+
}[keyof TApiContract['responsesByStatusCode'] & HttpStatusCode] | {
|
|
102
|
+
[K in keyof TApiContract['responsesByStatusCode'] & WildcardStatusCodeKey]: WildcardSseEntry<TApiContract, K>;
|
|
103
|
+
}[keyof TApiContract['responsesByStatusCode'] & WildcardStatusCodeKey];
|
|
65
104
|
/**
|
|
66
105
|
* Infers a discriminated union of `{ statusCode, headers, body }` for non-SSE mode:
|
|
67
|
-
* - success status codes → non-SSE body only (JSON / text / blob / null)
|
|
68
|
-
* - error status codes
|
|
106
|
+
* - exact success status codes and `'2xx'` range → non-SSE body only (JSON / text / blob / null)
|
|
107
|
+
* - error status codes, other ranges, and `'default'` → body as-is (all kinds)
|
|
108
|
+
*
|
|
109
|
+
* `'default'` is split into a success half (`SuccessfulHttpStatusCode`) and a non-success half
|
|
110
|
+
* so that `captureAsError` type narrowing stays correct regardless of the actual status code.
|
|
69
111
|
*
|
|
70
112
|
* Headers are typed via `InferClientResponseHeaders`: known headers from `responseHeaderSchema`
|
|
71
113
|
* are strongly typed; all other headers remain accessible as `string | undefined`.
|
|
@@ -76,5 +118,7 @@ export type InferNonSseClientResponse<TApiContract extends ApiContract> = {
|
|
|
76
118
|
headers: InferClientResponseHeaders<TApiContract>;
|
|
77
119
|
body: K extends SuccessfulHttpStatusCode ? NonSseInferClientResponseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>> : InferClientResponseBody<NonNullable<TApiContract['responsesByStatusCode'][K]>>;
|
|
78
120
|
};
|
|
79
|
-
}[keyof TApiContract['responsesByStatusCode'] & HttpStatusCode]
|
|
121
|
+
}[keyof TApiContract['responsesByStatusCode'] & HttpStatusCode] | {
|
|
122
|
+
[K in keyof TApiContract['responsesByStatusCode'] & WildcardStatusCodeKey]: WildcardNonSseEntry<TApiContract, K>;
|
|
123
|
+
}[keyof TApiContract['responsesByStatusCode'] & WildcardStatusCodeKey];
|
|
80
124
|
export {};
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import type { z } from 'zod/v4';
|
|
2
|
-
import type { HttpStatusCode } from '../HttpStatusCodes.ts';
|
|
2
|
+
import type { HttpStatusCode, WildcardStatusCodeKey } from '../HttpStatusCodes.ts';
|
|
3
3
|
import { ContractNoBody } from './constants.ts';
|
|
4
|
+
export type ResponseOptions = {
|
|
5
|
+
readonly description?: string;
|
|
6
|
+
};
|
|
4
7
|
export type TypedTextResponse = {
|
|
5
8
|
readonly _tag: 'TextResponse';
|
|
6
9
|
readonly contentType: string;
|
|
10
|
+
readonly description?: string;
|
|
7
11
|
};
|
|
8
|
-
export declare const textResponse: (contentType: string) => TypedTextResponse;
|
|
12
|
+
export declare const textResponse: (contentType: string, options?: ResponseOptions) => TypedTextResponse;
|
|
9
13
|
export declare const isTextResponse: (value: ApiContractResponse) => value is TypedTextResponse;
|
|
10
14
|
export type TypedBlobResponse = {
|
|
11
15
|
readonly _tag: 'BlobResponse';
|
|
12
16
|
readonly contentType: string;
|
|
17
|
+
readonly description?: string;
|
|
13
18
|
};
|
|
14
|
-
export declare const blobResponse: (contentType: string) => TypedBlobResponse;
|
|
19
|
+
export declare const blobResponse: (contentType: string, options?: ResponseOptions) => TypedBlobResponse;
|
|
15
20
|
export declare const isBlobResponse: (value: ApiContractResponse) => value is TypedBlobResponse;
|
|
16
21
|
export type SseSchemaByEventName = Record<string, z.ZodType>;
|
|
17
22
|
export type TypedSseResponse<T extends SseSchemaByEventName = SseSchemaByEventName> = {
|
|
18
23
|
readonly _tag: 'SseResponse';
|
|
19
24
|
readonly schemaByEventName: T;
|
|
25
|
+
readonly description?: string;
|
|
20
26
|
};
|
|
21
|
-
export declare const sseResponse: <T extends SseSchemaByEventName>(schemaByEventName: T) => TypedSseResponse<T>;
|
|
27
|
+
export declare const sseResponse: <T extends SseSchemaByEventName>(schemaByEventName: T, options?: ResponseOptions) => TypedSseResponse<T>;
|
|
22
28
|
export declare const isSseResponse: (value: ApiContractResponse) => value is TypedSseResponse;
|
|
23
29
|
export type TypedJsonResponse = z.ZodType;
|
|
24
30
|
export declare const isJsonResponse: (value: ApiContractResponse) => value is TypedJsonResponse;
|
|
@@ -26,11 +32,18 @@ export type TypedApiContractResponse = TypedJsonResponse | TypedTextResponse | T
|
|
|
26
32
|
export type AnyOfResponses<T extends TypedApiContractResponse = TypedApiContractResponse> = {
|
|
27
33
|
readonly _tag: 'AnyOfResponses';
|
|
28
34
|
readonly responses: T[];
|
|
35
|
+
readonly description?: string;
|
|
29
36
|
};
|
|
30
|
-
export declare const anyOfResponses: <T extends TypedApiContractResponse>(responses: T[]) => AnyOfResponses<T>;
|
|
37
|
+
export declare const anyOfResponses: <T extends TypedApiContractResponse>(responses: T[], options?: ResponseOptions) => AnyOfResponses<T>;
|
|
31
38
|
export declare const isAnyOfResponses: (value: ApiContractResponse) => value is AnyOfResponses;
|
|
32
|
-
export type
|
|
33
|
-
|
|
39
|
+
export type NoBodyResponse = {
|
|
40
|
+
readonly _tag: 'NoBodyResponse';
|
|
41
|
+
readonly description?: string;
|
|
42
|
+
};
|
|
43
|
+
export declare const noBodyResponse: (options?: ResponseOptions) => NoBodyResponse;
|
|
44
|
+
export declare const isNoBodyResponse: (value: ApiContractResponse) => value is NoBodyResponse;
|
|
45
|
+
export type ApiContractResponse = typeof ContractNoBody | NoBodyResponse | TypedApiContractResponse | AnyOfResponses;
|
|
46
|
+
export type ResponsesByStatusCode = Partial<Record<HttpStatusCode | WildcardStatusCodeKey, ApiContractResponse>>;
|
|
34
47
|
export type ResponseKind = {
|
|
35
48
|
kind: 'noContent';
|
|
36
49
|
} | {
|
|
@@ -63,6 +76,7 @@ export type ResponseKind = {
|
|
|
63
76
|
export declare const resolveContractResponse: (schemaEntry: ApiContractResponse, contentType: string | undefined, strict?: boolean) => ResponseKind | null;
|
|
64
77
|
/**
|
|
65
78
|
* Combines status-code lookup and content-type resolution into a single call.
|
|
66
|
-
*
|
|
79
|
+
* Lookup precedence: exact code → range key (e.g. `'4xx'`) → `'default'`.
|
|
80
|
+
* Returns `null` when no entry matches or the content-type cannot be matched.
|
|
67
81
|
*/
|
|
68
82
|
export declare function resolveResponseEntry(responsesByStatusCode: ResponsesByStatusCode, statusCode: number, contentType: string | undefined, strictContentType: boolean): ResponseKind | null;
|
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
import { ContractNoBody } from "./constants.js";
|
|
2
|
-
export const textResponse = (contentType) => ({
|
|
2
|
+
export const textResponse = (contentType, options) => ({
|
|
3
3
|
_tag: 'TextResponse',
|
|
4
4
|
contentType,
|
|
5
|
+
...(options?.description !== undefined && { description: options.description }),
|
|
5
6
|
});
|
|
6
7
|
export const isTextResponse = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'TextResponse';
|
|
7
|
-
export const blobResponse = (contentType) => ({
|
|
8
|
+
export const blobResponse = (contentType, options) => ({
|
|
8
9
|
_tag: 'BlobResponse',
|
|
9
10
|
contentType,
|
|
11
|
+
...(options?.description !== undefined && { description: options.description }),
|
|
10
12
|
});
|
|
11
13
|
export const isBlobResponse = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'BlobResponse';
|
|
12
|
-
export const sseResponse = (schemaByEventName) => ({
|
|
14
|
+
export const sseResponse = (schemaByEventName, options) => ({
|
|
13
15
|
_tag: 'SseResponse',
|
|
14
16
|
schemaByEventName,
|
|
17
|
+
...(options?.description !== undefined && { description: options.description }),
|
|
15
18
|
});
|
|
16
19
|
export const isSseResponse = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'SseResponse';
|
|
17
20
|
export const isJsonResponse = (value) => typeof value === 'object' && value !== null && !('_tag' in value);
|
|
18
|
-
export const anyOfResponses = (responses) => ({
|
|
21
|
+
export const anyOfResponses = (responses, options) => ({
|
|
19
22
|
_tag: 'AnyOfResponses',
|
|
20
23
|
responses,
|
|
24
|
+
...(options?.description !== undefined && { description: options.description }),
|
|
21
25
|
});
|
|
22
26
|
export const isAnyOfResponses = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'AnyOfResponses';
|
|
27
|
+
export const noBodyResponse = (options) => ({
|
|
28
|
+
_tag: 'NoBodyResponse',
|
|
29
|
+
...(options?.description !== undefined && { description: options.description }),
|
|
30
|
+
});
|
|
31
|
+
export const isNoBodyResponse = (value) => typeof value === 'object' && value !== null && '_tag' in value && value._tag === 'NoBodyResponse';
|
|
23
32
|
const matchTypedResponse = (entry, contentType) => {
|
|
24
33
|
if (isTextResponse(entry)) {
|
|
25
34
|
return contentType.includes(entry.contentType) ? { kind: 'text' } : null;
|
|
@@ -66,7 +75,7 @@ const resolveByKind = (entry) => {
|
|
|
66
75
|
* content-type to disambiguate regardless of this flag.
|
|
67
76
|
*/
|
|
68
77
|
export const resolveContractResponse = (schemaEntry, contentType, strict = true) => {
|
|
69
|
-
if (schemaEntry === ContractNoBody) {
|
|
78
|
+
if (schemaEntry === ContractNoBody || isNoBodyResponse(schemaEntry)) {
|
|
70
79
|
return { kind: 'noContent' };
|
|
71
80
|
}
|
|
72
81
|
if (isAnyOfResponses(schemaEntry)) {
|
|
@@ -88,15 +97,40 @@ export const resolveContractResponse = (schemaEntry, contentType, strict = true)
|
|
|
88
97
|
const matched = matchTypedResponse(schemaEntry, contentType);
|
|
89
98
|
return matched ?? (strict ? null : resolveByKind(schemaEntry));
|
|
90
99
|
};
|
|
100
|
+
function getRangeKey(statusCode) {
|
|
101
|
+
if (statusCode >= 100 && statusCode < 200)
|
|
102
|
+
return '1xx';
|
|
103
|
+
if (statusCode >= 200 && statusCode < 300)
|
|
104
|
+
return '2xx';
|
|
105
|
+
if (statusCode >= 300 && statusCode < 400)
|
|
106
|
+
return '3xx';
|
|
107
|
+
if (statusCode >= 400 && statusCode < 500)
|
|
108
|
+
return '4xx';
|
|
109
|
+
if (statusCode >= 500 && statusCode < 600)
|
|
110
|
+
return '5xx';
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
91
113
|
/**
|
|
92
114
|
* Combines status-code lookup and content-type resolution into a single call.
|
|
93
|
-
*
|
|
115
|
+
* Lookup precedence: exact code → range key (e.g. `'4xx'`) → `'default'`.
|
|
116
|
+
* Returns `null` when no entry matches or the content-type cannot be matched.
|
|
94
117
|
*/
|
|
95
118
|
export function resolveResponseEntry(responsesByStatusCode, statusCode, contentType, strictContentType) {
|
|
96
|
-
const
|
|
97
|
-
if (
|
|
98
|
-
return
|
|
119
|
+
const exactEntry = responsesByStatusCode[statusCode];
|
|
120
|
+
if (exactEntry) {
|
|
121
|
+
return resolveContractResponse(exactEntry, contentType, strictContentType);
|
|
99
122
|
}
|
|
100
|
-
|
|
123
|
+
const rangeKey = getRangeKey(statusCode);
|
|
124
|
+
if (rangeKey) {
|
|
125
|
+
const rangeEntry = responsesByStatusCode[rangeKey];
|
|
126
|
+
if (rangeEntry) {
|
|
127
|
+
return resolveContractResponse(rangeEntry, contentType, strictContentType);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const defaultEntry = responsesByStatusCode['default'];
|
|
131
|
+
if (defaultEntry) {
|
|
132
|
+
return resolveContractResponse(defaultEntry, contentType, strictContentType);
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
101
135
|
}
|
|
102
136
|
//# sourceMappingURL=contractResponse.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contractResponse.js","sourceRoot":"","sources":["../../src/new/contractResponse.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"contractResponse.js","sourceRoot":"","sources":["../../src/new/contractResponse.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,6 +43,8 @@ export declare const mapApiContractToPath: (routeConfig: ApiContract) => string;
|
|
|
43
43
|
export declare const describeApiContract: (routeConfig: ApiContract) => string;
|
|
44
44
|
export declare const getSseSchemaByEventName: (routeConfig: ApiContract) => SseSchemaByEventName | null;
|
|
45
45
|
export declare const hasAnySuccessSseResponse: (apiContract: ApiContract) => boolean;
|
|
46
|
+
/** @deprecated No known consumers — will be removed in a future release. */
|
|
46
47
|
export declare const getSuccessResponseSchema: (routeConfig: ApiContract) => z.ZodType | null;
|
|
48
|
+
/** @deprecated No known consumers — will be removed in a future release. */
|
|
47
49
|
export declare const getIsEmptyResponseExpected: (routeConfig: ApiContract) => boolean;
|
|
48
50
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod/v4';
|
|
2
2
|
import { SUCCESSFUL_HTTP_STATUS_CODES } from "../HttpStatusCodes.js";
|
|
3
3
|
import { ContractNoBody } from "./constants.js";
|
|
4
|
-
import { isAnyOfResponses, isBlobResponse, isSseResponse, isTextResponse, } from "./contractResponse.js";
|
|
4
|
+
import { isAnyOfResponses, isBlobResponse, isNoBodyResponse, isSseResponse, isTextResponse, } from "./contractResponse.js";
|
|
5
5
|
export const defineApiContract = (contract) => contract;
|
|
6
6
|
export const mapApiContractToPath = (routeConfig) => {
|
|
7
7
|
if (!routeConfig.requestPathParamsSchema) {
|
|
@@ -33,7 +33,7 @@ export const getSseSchemaByEventName = (routeConfig) => {
|
|
|
33
33
|
return Object.keys(result).length > 0 ? result : null;
|
|
34
34
|
};
|
|
35
35
|
export const hasAnySuccessSseResponse = (apiContract) => {
|
|
36
|
-
for (const code of SUCCESSFUL_HTTP_STATUS_CODES) {
|
|
36
|
+
for (const code of [...SUCCESSFUL_HTTP_STATUS_CODES, '2xx', 'default']) {
|
|
37
37
|
const value = apiContract.responsesByStatusCode[code];
|
|
38
38
|
if (!value) {
|
|
39
39
|
continue;
|
|
@@ -51,6 +51,7 @@ export const hasAnySuccessSseResponse = (apiContract) => {
|
|
|
51
51
|
}
|
|
52
52
|
return false;
|
|
53
53
|
};
|
|
54
|
+
/** @deprecated No known consumers — will be removed in a future release. */
|
|
54
55
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: it is acceptable
|
|
55
56
|
export const getSuccessResponseSchema = (routeConfig) => {
|
|
56
57
|
const schemas = [];
|
|
@@ -68,6 +69,7 @@ export const getSuccessResponseSchema = (routeConfig) => {
|
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
else if (value === ContractNoBody ||
|
|
72
|
+
isNoBodyResponse(value) ||
|
|
71
73
|
isSseResponse(value) ||
|
|
72
74
|
isTextResponse(value) ||
|
|
73
75
|
isBlobResponse(value)) {
|
|
@@ -86,11 +88,12 @@ export const getSuccessResponseSchema = (routeConfig) => {
|
|
|
86
88
|
}
|
|
87
89
|
return hasDirectNonJsonEntry ? z.never() : null;
|
|
88
90
|
};
|
|
91
|
+
/** @deprecated No known consumers — will be removed in a future release. */
|
|
89
92
|
export const getIsEmptyResponseExpected = (routeConfig) => {
|
|
90
93
|
let isEmptyResponseExpected = true;
|
|
91
94
|
for (const code of SUCCESSFUL_HTTP_STATUS_CODES) {
|
|
92
95
|
const value = routeConfig.responsesByStatusCode[code];
|
|
93
|
-
if (value && value !== ContractNoBody) {
|
|
96
|
+
if (value && value !== ContractNoBody && !isNoBodyResponse(value)) {
|
|
94
97
|
isEmptyResponseExpected = false;
|
|
95
98
|
break;
|
|
96
99
|
}
|
|
@@ -1 +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;AA+C9B,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,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,WAAwB,EAAW,EAAE;IAC5E,KAAK,MAAM,IAAI,IAAI,4BAA4B,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"defineApiContract.js","sourceRoot":"","sources":["../../src/new/defineApiContract.ts"],"names":[],"mappings":"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"}
|
package/dist/new/inferTypes.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { SuccessfulHttpStatusCode } from '../HttpStatusCodes.ts';
|
|
|
3
3
|
import type { ValueOf } from '../typeUtils.ts';
|
|
4
4
|
import type { ContractNoBody } from './constants.ts';
|
|
5
5
|
import type { ResponsesByStatusCode } from './contractResponse.ts';
|
|
6
|
-
type ExtractSuccessResponses<T extends ResponsesByStatusCode> = ValueOf<T, Extract<keyof T, SuccessfulHttpStatusCode>>;
|
|
6
|
+
type ExtractSuccessResponses<T extends ResponsesByStatusCode> = ValueOf<T, Extract<keyof T, SuccessfulHttpStatusCode | '2xx' | 'default'>>;
|
|
7
7
|
/**
|
|
8
8
|
* Returns true if all success responses have no body (ContractNoBody or no success status codes defined).
|
|
9
9
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lokalise/api-contracts",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.13.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist"
|
|
6
6
|
],
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"homepage": "https://github.com/lokalise/shared-ts-libs",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "git://github.com/lokalise/shared-ts-libs.git"
|
|
14
|
+
"url": "git://github.com/lokalise/shared-ts-libs.git",
|
|
15
|
+
"directory": "packages/app/api-contracts"
|
|
15
16
|
},
|
|
16
17
|
"exports": {
|
|
17
18
|
".": "./dist/index.js",
|
|
@@ -38,11 +39,11 @@
|
|
|
38
39
|
"@biomejs/biome": "^2.4.7",
|
|
39
40
|
"@lokalise/biome-config": "^3.1.0",
|
|
40
41
|
"@lokalise/tsconfig": "^4.0.0",
|
|
41
|
-
"@types/node": "^25.
|
|
42
|
-
"@vitest/coverage-v8": "^4.
|
|
42
|
+
"@types/node": "^25.9.1",
|
|
43
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
43
44
|
"rimraf": "^6.1.2",
|
|
44
45
|
"typescript": "6.0.3",
|
|
45
|
-
"vitest": "^4.
|
|
46
|
+
"vitest": "^4.1.7",
|
|
46
47
|
"zod": "^4.3.6"
|
|
47
48
|
},
|
|
48
49
|
"scripts": {
|