openapi-typesafe-helpers 1.0.0-rc.0 → 1.0.0-rc.2
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 +9 -0
- package/dist/index.d.cts +170 -56
- package/dist/index.d.mts +170 -56
- package/dist/index.d.ts +170 -56
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -6,6 +6,15 @@ Type helpers shared by `openapi-typesafe-fetch` and `openapi-typesafe-react-quer
|
|
|
6
6
|
A maintained successor to `openapi-typescript-helpers` (see the [repository README](../../README.md)).
|
|
7
7
|
Most projects do not need to install it directly.
|
|
8
8
|
|
|
9
|
+
> **Release candidate.** The current version is a 1.0.0 release candidate (`1.0.0-rc.N`);
|
|
10
|
+
> names and output can still change before 1.0.0.
|
|
11
|
+
|
|
12
|
+
## Versioning
|
|
13
|
+
|
|
14
|
+
Semantic versioning from 1.0.0, with one version for all openapi-typesafe packages. What the
|
|
15
|
+
version promises, and what may grow in a minor release, is listed under
|
|
16
|
+
[Versioning](https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs/compatibility.md#versioning).
|
|
17
|
+
|
|
9
18
|
## License
|
|
10
19
|
|
|
11
20
|
[MIT](./LICENSE)
|
package/dist/index.d.cts
CHANGED
|
@@ -1,172 +1,286 @@
|
|
|
1
|
-
type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"
|
|
1
|
+
type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"
|
|
2
|
+
/** OpenAPI 3.2: a safe, idempotent request with a body. */
|
|
3
|
+
| "query";
|
|
4
|
+
/** 2XX statuses */
|
|
2
5
|
type OkStatus = 200 | 201 | 202 | 203 | 204 | 206 | 207 | "2XX";
|
|
6
|
+
/** 4XX and 5XX statuses */
|
|
3
7
|
type ErrorStatus = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | "5XX" | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 444 | 450 | 451 | 497 | 498 | 499 | "4XX" | "default";
|
|
8
|
+
/** Get a union of OK Statuses */
|
|
4
9
|
type OKStatusUnion<T> = FilterKeys<T, OkStatus>;
|
|
10
|
+
/** Get first error status, in order */
|
|
5
11
|
type FirstErrorStatus<T> = T extends {
|
|
6
|
-
500:
|
|
12
|
+
500: unknown;
|
|
7
13
|
} ? T[500] : T extends {
|
|
8
|
-
501:
|
|
14
|
+
501: unknown;
|
|
9
15
|
} ? T[501] : T extends {
|
|
10
|
-
502:
|
|
16
|
+
502: unknown;
|
|
11
17
|
} ? T[502] : T extends {
|
|
12
|
-
503:
|
|
18
|
+
503: unknown;
|
|
13
19
|
} ? T[503] : T extends {
|
|
14
|
-
504:
|
|
20
|
+
504: unknown;
|
|
15
21
|
} ? T[504] : T extends {
|
|
16
|
-
505:
|
|
22
|
+
505: unknown;
|
|
17
23
|
} ? T[505] : T extends {
|
|
18
|
-
506:
|
|
24
|
+
506: unknown;
|
|
19
25
|
} ? T[506] : T extends {
|
|
20
|
-
507:
|
|
26
|
+
507: unknown;
|
|
21
27
|
} ? T[507] : T extends {
|
|
22
|
-
508:
|
|
28
|
+
508: unknown;
|
|
23
29
|
} ? T[508] : T extends {
|
|
24
|
-
510:
|
|
30
|
+
510: unknown;
|
|
25
31
|
} ? T[510] : T extends {
|
|
26
|
-
511:
|
|
32
|
+
511: unknown;
|
|
27
33
|
} ? T[511] : T extends {
|
|
28
|
-
"5XX":
|
|
34
|
+
"5XX": unknown;
|
|
29
35
|
} ? T["5XX"] : T extends {
|
|
30
|
-
400:
|
|
36
|
+
400: unknown;
|
|
31
37
|
} ? T[400] : T extends {
|
|
32
|
-
401:
|
|
38
|
+
401: unknown;
|
|
33
39
|
} ? T[401] : T extends {
|
|
34
|
-
402:
|
|
40
|
+
402: unknown;
|
|
35
41
|
} ? T[402] : T extends {
|
|
36
|
-
403:
|
|
42
|
+
403: unknown;
|
|
37
43
|
} ? T[403] : T extends {
|
|
38
|
-
404:
|
|
44
|
+
404: unknown;
|
|
39
45
|
} ? T[404] : T extends {
|
|
40
|
-
405:
|
|
46
|
+
405: unknown;
|
|
41
47
|
} ? T[405] : T extends {
|
|
42
|
-
406:
|
|
48
|
+
406: unknown;
|
|
43
49
|
} ? T[406] : T extends {
|
|
44
|
-
407:
|
|
50
|
+
407: unknown;
|
|
45
51
|
} ? T[407] : T extends {
|
|
46
|
-
408:
|
|
52
|
+
408: unknown;
|
|
47
53
|
} ? T[408] : T extends {
|
|
48
|
-
409:
|
|
54
|
+
409: unknown;
|
|
49
55
|
} ? T[409] : T extends {
|
|
50
|
-
410:
|
|
56
|
+
410: unknown;
|
|
51
57
|
} ? T[410] : T extends {
|
|
52
|
-
411:
|
|
58
|
+
411: unknown;
|
|
53
59
|
} ? T[411] : T extends {
|
|
54
|
-
412:
|
|
60
|
+
412: unknown;
|
|
55
61
|
} ? T[412] : T extends {
|
|
56
|
-
413:
|
|
62
|
+
413: unknown;
|
|
57
63
|
} ? T[413] : T extends {
|
|
58
|
-
414:
|
|
64
|
+
414: unknown;
|
|
59
65
|
} ? T[414] : T extends {
|
|
60
|
-
415:
|
|
66
|
+
415: unknown;
|
|
61
67
|
} ? T[415] : T extends {
|
|
62
|
-
416:
|
|
68
|
+
416: unknown;
|
|
63
69
|
} ? T[416] : T extends {
|
|
64
|
-
417:
|
|
70
|
+
417: unknown;
|
|
65
71
|
} ? T[417] : T extends {
|
|
66
|
-
418:
|
|
72
|
+
418: unknown;
|
|
67
73
|
} ? T[418] : T extends {
|
|
68
|
-
420:
|
|
74
|
+
420: unknown;
|
|
69
75
|
} ? T[420] : T extends {
|
|
70
|
-
421:
|
|
76
|
+
421: unknown;
|
|
71
77
|
} ? T[421] : T extends {
|
|
72
|
-
422:
|
|
78
|
+
422: unknown;
|
|
73
79
|
} ? T[422] : T extends {
|
|
74
|
-
423:
|
|
80
|
+
423: unknown;
|
|
75
81
|
} ? T[423] : T extends {
|
|
76
|
-
424:
|
|
82
|
+
424: unknown;
|
|
77
83
|
} ? T[424] : T extends {
|
|
78
|
-
425:
|
|
84
|
+
425: unknown;
|
|
79
85
|
} ? T[425] : T extends {
|
|
80
|
-
426:
|
|
86
|
+
426: unknown;
|
|
81
87
|
} ? T[426] : T extends {
|
|
82
|
-
427:
|
|
88
|
+
427: unknown;
|
|
83
89
|
} ? T[427] : T extends {
|
|
84
|
-
428:
|
|
90
|
+
428: unknown;
|
|
85
91
|
} ? T[428] : T extends {
|
|
86
|
-
429:
|
|
92
|
+
429: unknown;
|
|
87
93
|
} ? T[429] : T extends {
|
|
88
|
-
430:
|
|
94
|
+
430: unknown;
|
|
89
95
|
} ? T[430] : T extends {
|
|
90
|
-
431:
|
|
96
|
+
431: unknown;
|
|
91
97
|
} ? T[431] : T extends {
|
|
92
|
-
444:
|
|
98
|
+
444: unknown;
|
|
93
99
|
} ? T[444] : T extends {
|
|
94
|
-
450:
|
|
100
|
+
450: unknown;
|
|
95
101
|
} ? T[450] : T extends {
|
|
96
|
-
451:
|
|
102
|
+
451: unknown;
|
|
97
103
|
} ? T[451] : T extends {
|
|
98
|
-
497:
|
|
104
|
+
497: unknown;
|
|
99
105
|
} ? T[497] : T extends {
|
|
100
|
-
498:
|
|
106
|
+
498: unknown;
|
|
101
107
|
} ? T[498] : T extends {
|
|
102
|
-
499:
|
|
108
|
+
499: unknown;
|
|
103
109
|
} ? T[499] : T extends {
|
|
104
|
-
"4XX":
|
|
110
|
+
"4XX": unknown;
|
|
105
111
|
} ? T["4XX"] : T extends {
|
|
106
|
-
default:
|
|
112
|
+
default: unknown;
|
|
107
113
|
} ? T["default"] : never;
|
|
108
|
-
|
|
114
|
+
/** The paths that have each of the methods: upstream's `PathsWithMethod`. */
|
|
115
|
+
type PathsWithEveryMethod<Paths extends {}, PathnameMethod extends HttpMethod> = {
|
|
109
116
|
[Pathname in keyof Paths]: Paths[Pathname] extends {
|
|
110
|
-
[K in PathnameMethod]:
|
|
117
|
+
[K in PathnameMethod]: unknown;
|
|
111
118
|
} ? Pathname : never;
|
|
112
119
|
}[keyof Paths];
|
|
120
|
+
/** The paths that have at least one method. */
|
|
121
|
+
type PathsWithAnyMethod<Paths extends {}> = {
|
|
122
|
+
[Pathname in keyof Paths]: {
|
|
123
|
+
[Method in HttpMethod]: Paths[Pathname] extends {
|
|
124
|
+
[K in Method]: unknown;
|
|
125
|
+
} ? Pathname : never;
|
|
126
|
+
}[HttpMethod];
|
|
127
|
+
}[keyof Paths];
|
|
128
|
+
/**
|
|
129
|
+
* Given an OpenAPI **Paths Object**, find all paths that have the given method. For a union of
|
|
130
|
+
* methods, the paths that have each of them, so a call with either method finds its operation.
|
|
131
|
+
* For `HttpMethod` itself, a method not known yet, the paths that have any method too: TypeScript
|
|
132
|
+
* uses it where a hook's `Method` is not inferred, as in `Parameters<typeof $api.queryOptions>`,
|
|
133
|
+
* and the paths with every method were none (upstream #2178).
|
|
134
|
+
*
|
|
135
|
+
* A union with upstream's type, not a conditional type over the method: code that is generic in
|
|
136
|
+
* the method (`Path extends PathsWithMethod<Paths, Method>`, as swr-openapi has) must still
|
|
137
|
+
* relate one `PathsWithMethod` to another, and TypeScript cannot relate a type to a conditional
|
|
138
|
+
* type that waits for its method (TS2344). For a known method the second member is `never`.
|
|
139
|
+
*/
|
|
140
|
+
type PathsWithMethod<Paths extends {}, PathnameMethod extends HttpMethod> = PathsWithEveryMethod<Paths, PathnameMethod> | (HttpMethod extends PathnameMethod ? PathsWithAnyMethod<Paths> : never);
|
|
141
|
+
/**
|
|
142
|
+
* DO NOT USE!
|
|
143
|
+
* Only used only for OperationObject type inference
|
|
144
|
+
*/
|
|
113
145
|
interface OperationObject {
|
|
114
146
|
parameters: any;
|
|
115
147
|
requestBody: any;
|
|
116
148
|
responses: any;
|
|
117
149
|
}
|
|
150
|
+
/** Internal helper used in PathsWithMethod */
|
|
118
151
|
type PathItemObject = {
|
|
119
152
|
[M in HttpMethod]: OperationObject;
|
|
120
153
|
} & {
|
|
121
154
|
parameters?: any;
|
|
122
155
|
};
|
|
156
|
+
/** Return `responses` for an Operation Object */
|
|
123
157
|
type ResponseObjectMap<T> = T extends {
|
|
124
158
|
responses: any;
|
|
125
159
|
} ? T["responses"] : unknown;
|
|
160
|
+
/** Return `content` for a Response Object */
|
|
126
161
|
type ResponseContent<T> = T extends {
|
|
127
162
|
content: any;
|
|
128
163
|
} ? T["content"] : unknown;
|
|
164
|
+
/** Return type of `requestBody` for an Operation Object */
|
|
129
165
|
type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
|
|
166
|
+
/** Internal helper to get object type with only the `requestBody` property */
|
|
130
167
|
type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
|
|
168
|
+
/** Resolve to `true` if request body is optional, else `false` */
|
|
131
169
|
type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
|
|
170
|
+
/** Internal helper used in OperationRequestBodyContent */
|
|
132
171
|
type OperationRequestBodyMediaContent<T> = IsOperationRequestBodyOptional<T> extends true ? ResponseContent<NonNullable<OperationRequestBody<T>>> | undefined : ResponseContent<OperationRequestBody<T>>;
|
|
172
|
+
/** Return first `content` from a Request Object Mapping, allowing any media type */
|
|
133
173
|
type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never ? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined : FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
|
|
134
|
-
|
|
174
|
+
/**
|
|
175
|
+
* The statuses of success responses in a Response Object Map: the 2XX statuses, or `default` when
|
|
176
|
+
* no 2XX status is declared. `default` covers every status the operation does not declare (OpenAPI
|
|
177
|
+
* Responses Object), so then it covers every success (upstream #1862). With a 2XX status declared,
|
|
178
|
+
* `default` is left to the errors, as before.
|
|
179
|
+
*/
|
|
180
|
+
type SuccessStatus<T> = [Extract<keyof T, OkStatus>] extends [never] ? "default" : OkStatus;
|
|
181
|
+
/** Return all 2XX responses from a Response Object Map, or `default` if it declares no 2XX one */
|
|
182
|
+
type SuccessResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, SuccessStatus<T>>;
|
|
135
183
|
type GetResponseContent<T extends Record<string | number, any>, Media extends MediaType = MediaType, ResponseCode extends keyof T = keyof T> = ResponseCode extends keyof T ? {
|
|
136
184
|
[K in ResponseCode]: T[K]["content"] extends Record<string, any> ? FilterKeys<T[K]["content"], Media> extends never ? T[K]["content"] : FilterKeys<T[K]["content"], Media> : K extends keyof T ? T[K]["content"] : never;
|
|
137
185
|
}[ResponseCode] : never;
|
|
186
|
+
/**
|
|
187
|
+
* Return all 5XX and 4XX responses (in that order) from a Response Object Map
|
|
188
|
+
*/
|
|
138
189
|
type ErrorResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, ErrorStatus>;
|
|
190
|
+
/** Return first JSON-like 2XX response from a path + HTTP method */
|
|
139
191
|
type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = SuccessResponse<ResponseObjectMap<PathMethod>, `${string}/json`>;
|
|
192
|
+
/** Return first JSON-like 5XX or 4XX response from a path + HTTP method */
|
|
140
193
|
type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = ErrorResponse<ResponseObjectMap<PathMethod>, `${string}/json`>;
|
|
194
|
+
/** Return JSON-like request body from a path + HTTP method */
|
|
141
195
|
type RequestBodyJSON<PathMethod> = JSONLike<FilterKeys<OperationRequestBody<PathMethod>, "content">>;
|
|
196
|
+
/** Find first match of multiple keys */
|
|
142
197
|
type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];
|
|
143
|
-
|
|
198
|
+
/**
|
|
199
|
+
* @deprecated Use `FilterKeys` instead
|
|
200
|
+
* Get the type of a value of an input object with a given key. If the key is
|
|
201
|
+
* not found, return a default type. Works with unions of objects too.
|
|
202
|
+
*/
|
|
203
|
+
type GetValueWithDefault<Obj, KeyPattern, Default> = Obj extends unknown ? FilterKeys<Obj, KeyPattern> extends never ? Default : FilterKeys<Obj, KeyPattern> : never;
|
|
204
|
+
/**
|
|
205
|
+
* Return any `[string]/[string]` media type (important because openapi-typesafe-fetch allows any
|
|
206
|
+
* content response, not just JSON-like)
|
|
207
|
+
*/
|
|
144
208
|
type MediaType = `${string}/${string}`;
|
|
209
|
+
/**
|
|
210
|
+
* Return any media type containing "json" (works for "application/json",
|
|
211
|
+
* "application/vnd.api+json", "application/vnd.oai.openapi+json")
|
|
212
|
+
*/
|
|
145
213
|
type JSONLike<T> = FilterKeys<T, `${string}/json`>;
|
|
214
|
+
/**
|
|
215
|
+
* Filter objects that have required keys
|
|
216
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
217
|
+
*/
|
|
146
218
|
type FindRequiredKeys<T, K extends keyof T> = K extends unknown ? undefined extends T[K] ? never : K : K;
|
|
219
|
+
/**
|
|
220
|
+
* Does this object contain required keys?
|
|
221
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
222
|
+
*/
|
|
147
223
|
type HasRequiredKeys<T> = FindRequiredKeys<T, keyof T>;
|
|
224
|
+
/**
|
|
225
|
+
* Helper to get the required keys of an object. If no keys are required, will be `undefined` with
|
|
226
|
+
* strictNullChecks enabled, else `never`
|
|
227
|
+
*/
|
|
148
228
|
type RequiredKeysOfHelper<T> = {
|
|
149
229
|
[K in keyof T]: {} extends Pick<T, K> ? never : K;
|
|
150
230
|
}[keyof T];
|
|
231
|
+
/** Get the required keys of an object, or `never` if no keys are required */
|
|
151
232
|
type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;
|
|
233
|
+
/** Marker type for readOnly properties (excluded from request bodies) */
|
|
152
234
|
type $Read<T> = {
|
|
153
235
|
readonly $read: T;
|
|
154
236
|
};
|
|
237
|
+
/** Marker type for writeOnly properties (excluded from response bodies) */
|
|
155
238
|
type $Write<T> = {
|
|
156
239
|
readonly $write: T;
|
|
157
240
|
};
|
|
241
|
+
/** Primitives, also branded ones (`string & { __brand: "Id" }`), which stay unmapped (#2765). */
|
|
158
242
|
type ReadWritePrimitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
243
|
+
/**
|
|
244
|
+
* Types that stay unmapped. Mapping a function type drops its call signatures, so a `Blob` from
|
|
245
|
+
* `--binary-as-blob` lost its methods (`arrayBuffer()`, `text()`, ...) in response data.
|
|
246
|
+
*/
|
|
159
247
|
type ReadWriteLeaf = ReadWritePrimitive | ((...args: never) => unknown);
|
|
248
|
+
/**
|
|
249
|
+
* Keys of `T` whose value is a `Marker`. A key whose value is only `null` or `undefined` is not
|
|
250
|
+
* marked: `NonNullable` of it is `never`, and `never` extends every marker (upstream #2717). The
|
|
251
|
+
* checks are not distributive (`NonNullable<T[K]>` is not a type parameter), so `never` is seen.
|
|
252
|
+
*/
|
|
160
253
|
type ReadWriteMarkedKeys<T, Marker> = {
|
|
161
254
|
[K in keyof T]-?: NonNullable<T[K]> extends never ? never : NonNullable<T[K]> extends Marker ? K : never;
|
|
162
255
|
}[keyof T];
|
|
256
|
+
/**
|
|
257
|
+
* Resolve an array or a tuple element by element. An array uses `T[number]`, not `infer E`: for an
|
|
258
|
+
* intersection of arrays (`allOf`) inference keeps one member and narrowing breaks (upstream
|
|
259
|
+
* #2620). `T` is a plain array when an array of its elements is assignable to it; otherwise it is a
|
|
260
|
+
* tuple (also `[A, ...B[]]`), mapped homomorphically to stay a tuple (upstream #2632). Both keep
|
|
261
|
+
* `readonly` (upstream #2615).
|
|
262
|
+
*/
|
|
163
263
|
type ReadWriteResolveArray<T extends readonly unknown[], Resolved extends "read" | "write"> = T[number][] extends T ? T extends unknown[] ? ReadWriteResolve<T[number], Resolved>[] : readonly ReadWriteResolve<T[number], Resolved>[] : {
|
|
164
264
|
[K in keyof T]: ReadWriteResolve<T[K], Resolved>;
|
|
165
265
|
};
|
|
166
266
|
type ReadWriteResolve<T, Resolved extends "read" | "write"> = Resolved extends "read" ? Readable<T> : Writable<T>;
|
|
267
|
+
/**
|
|
268
|
+
* Resolve type for reading (responses): strips $Write properties, unwraps $Read
|
|
269
|
+
* - $Read<T> → T (readable), continues recursion
|
|
270
|
+
* - $Write<T> → never (excluded from response)
|
|
271
|
+
* - primitives (also branded), functions, arrays and tuples keep their shape; objects resolve
|
|
272
|
+
* recursively
|
|
273
|
+
*/
|
|
167
274
|
type Readable<T> = T extends $Write<any> ? never : T extends $Read<infer U> ? Readable<U> : T extends ReadWriteLeaf ? T : T extends readonly unknown[] ? ReadWriteResolveArray<T, "read"> : T extends object ? {
|
|
168
275
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Write<any>> ? never : K]: Readable<T[K]>;
|
|
169
276
|
} : T;
|
|
277
|
+
/**
|
|
278
|
+
* Resolve type for writing (requests): strips $Read properties, unwraps $Write
|
|
279
|
+
* - $Write<T> → T (writable), continues recursion
|
|
280
|
+
* - $Read<T> → never (excluded from request)
|
|
281
|
+
* - primitives (also branded), functions, arrays and tuples keep their shape; objects resolve
|
|
282
|
+
* recursively
|
|
283
|
+
*/
|
|
170
284
|
type Writable<T> = T extends $Read<any> ? never : T extends $Write<infer U> ? Writable<U> : T extends ReadWriteLeaf ? T : T extends readonly unknown[] ? ReadWriteResolveArray<T, "write"> : T extends object ? {
|
|
171
285
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Read<any>> ? never : K]: Writable<T[K]>;
|
|
172
286
|
} & {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,172 +1,286 @@
|
|
|
1
|
-
type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"
|
|
1
|
+
type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"
|
|
2
|
+
/** OpenAPI 3.2: a safe, idempotent request with a body. */
|
|
3
|
+
| "query";
|
|
4
|
+
/** 2XX statuses */
|
|
2
5
|
type OkStatus = 200 | 201 | 202 | 203 | 204 | 206 | 207 | "2XX";
|
|
6
|
+
/** 4XX and 5XX statuses */
|
|
3
7
|
type ErrorStatus = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | "5XX" | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 444 | 450 | 451 | 497 | 498 | 499 | "4XX" | "default";
|
|
8
|
+
/** Get a union of OK Statuses */
|
|
4
9
|
type OKStatusUnion<T> = FilterKeys<T, OkStatus>;
|
|
10
|
+
/** Get first error status, in order */
|
|
5
11
|
type FirstErrorStatus<T> = T extends {
|
|
6
|
-
500:
|
|
12
|
+
500: unknown;
|
|
7
13
|
} ? T[500] : T extends {
|
|
8
|
-
501:
|
|
14
|
+
501: unknown;
|
|
9
15
|
} ? T[501] : T extends {
|
|
10
|
-
502:
|
|
16
|
+
502: unknown;
|
|
11
17
|
} ? T[502] : T extends {
|
|
12
|
-
503:
|
|
18
|
+
503: unknown;
|
|
13
19
|
} ? T[503] : T extends {
|
|
14
|
-
504:
|
|
20
|
+
504: unknown;
|
|
15
21
|
} ? T[504] : T extends {
|
|
16
|
-
505:
|
|
22
|
+
505: unknown;
|
|
17
23
|
} ? T[505] : T extends {
|
|
18
|
-
506:
|
|
24
|
+
506: unknown;
|
|
19
25
|
} ? T[506] : T extends {
|
|
20
|
-
507:
|
|
26
|
+
507: unknown;
|
|
21
27
|
} ? T[507] : T extends {
|
|
22
|
-
508:
|
|
28
|
+
508: unknown;
|
|
23
29
|
} ? T[508] : T extends {
|
|
24
|
-
510:
|
|
30
|
+
510: unknown;
|
|
25
31
|
} ? T[510] : T extends {
|
|
26
|
-
511:
|
|
32
|
+
511: unknown;
|
|
27
33
|
} ? T[511] : T extends {
|
|
28
|
-
"5XX":
|
|
34
|
+
"5XX": unknown;
|
|
29
35
|
} ? T["5XX"] : T extends {
|
|
30
|
-
400:
|
|
36
|
+
400: unknown;
|
|
31
37
|
} ? T[400] : T extends {
|
|
32
|
-
401:
|
|
38
|
+
401: unknown;
|
|
33
39
|
} ? T[401] : T extends {
|
|
34
|
-
402:
|
|
40
|
+
402: unknown;
|
|
35
41
|
} ? T[402] : T extends {
|
|
36
|
-
403:
|
|
42
|
+
403: unknown;
|
|
37
43
|
} ? T[403] : T extends {
|
|
38
|
-
404:
|
|
44
|
+
404: unknown;
|
|
39
45
|
} ? T[404] : T extends {
|
|
40
|
-
405:
|
|
46
|
+
405: unknown;
|
|
41
47
|
} ? T[405] : T extends {
|
|
42
|
-
406:
|
|
48
|
+
406: unknown;
|
|
43
49
|
} ? T[406] : T extends {
|
|
44
|
-
407:
|
|
50
|
+
407: unknown;
|
|
45
51
|
} ? T[407] : T extends {
|
|
46
|
-
408:
|
|
52
|
+
408: unknown;
|
|
47
53
|
} ? T[408] : T extends {
|
|
48
|
-
409:
|
|
54
|
+
409: unknown;
|
|
49
55
|
} ? T[409] : T extends {
|
|
50
|
-
410:
|
|
56
|
+
410: unknown;
|
|
51
57
|
} ? T[410] : T extends {
|
|
52
|
-
411:
|
|
58
|
+
411: unknown;
|
|
53
59
|
} ? T[411] : T extends {
|
|
54
|
-
412:
|
|
60
|
+
412: unknown;
|
|
55
61
|
} ? T[412] : T extends {
|
|
56
|
-
413:
|
|
62
|
+
413: unknown;
|
|
57
63
|
} ? T[413] : T extends {
|
|
58
|
-
414:
|
|
64
|
+
414: unknown;
|
|
59
65
|
} ? T[414] : T extends {
|
|
60
|
-
415:
|
|
66
|
+
415: unknown;
|
|
61
67
|
} ? T[415] : T extends {
|
|
62
|
-
416:
|
|
68
|
+
416: unknown;
|
|
63
69
|
} ? T[416] : T extends {
|
|
64
|
-
417:
|
|
70
|
+
417: unknown;
|
|
65
71
|
} ? T[417] : T extends {
|
|
66
|
-
418:
|
|
72
|
+
418: unknown;
|
|
67
73
|
} ? T[418] : T extends {
|
|
68
|
-
420:
|
|
74
|
+
420: unknown;
|
|
69
75
|
} ? T[420] : T extends {
|
|
70
|
-
421:
|
|
76
|
+
421: unknown;
|
|
71
77
|
} ? T[421] : T extends {
|
|
72
|
-
422:
|
|
78
|
+
422: unknown;
|
|
73
79
|
} ? T[422] : T extends {
|
|
74
|
-
423:
|
|
80
|
+
423: unknown;
|
|
75
81
|
} ? T[423] : T extends {
|
|
76
|
-
424:
|
|
82
|
+
424: unknown;
|
|
77
83
|
} ? T[424] : T extends {
|
|
78
|
-
425:
|
|
84
|
+
425: unknown;
|
|
79
85
|
} ? T[425] : T extends {
|
|
80
|
-
426:
|
|
86
|
+
426: unknown;
|
|
81
87
|
} ? T[426] : T extends {
|
|
82
|
-
427:
|
|
88
|
+
427: unknown;
|
|
83
89
|
} ? T[427] : T extends {
|
|
84
|
-
428:
|
|
90
|
+
428: unknown;
|
|
85
91
|
} ? T[428] : T extends {
|
|
86
|
-
429:
|
|
92
|
+
429: unknown;
|
|
87
93
|
} ? T[429] : T extends {
|
|
88
|
-
430:
|
|
94
|
+
430: unknown;
|
|
89
95
|
} ? T[430] : T extends {
|
|
90
|
-
431:
|
|
96
|
+
431: unknown;
|
|
91
97
|
} ? T[431] : T extends {
|
|
92
|
-
444:
|
|
98
|
+
444: unknown;
|
|
93
99
|
} ? T[444] : T extends {
|
|
94
|
-
450:
|
|
100
|
+
450: unknown;
|
|
95
101
|
} ? T[450] : T extends {
|
|
96
|
-
451:
|
|
102
|
+
451: unknown;
|
|
97
103
|
} ? T[451] : T extends {
|
|
98
|
-
497:
|
|
104
|
+
497: unknown;
|
|
99
105
|
} ? T[497] : T extends {
|
|
100
|
-
498:
|
|
106
|
+
498: unknown;
|
|
101
107
|
} ? T[498] : T extends {
|
|
102
|
-
499:
|
|
108
|
+
499: unknown;
|
|
103
109
|
} ? T[499] : T extends {
|
|
104
|
-
"4XX":
|
|
110
|
+
"4XX": unknown;
|
|
105
111
|
} ? T["4XX"] : T extends {
|
|
106
|
-
default:
|
|
112
|
+
default: unknown;
|
|
107
113
|
} ? T["default"] : never;
|
|
108
|
-
|
|
114
|
+
/** The paths that have each of the methods: upstream's `PathsWithMethod`. */
|
|
115
|
+
type PathsWithEveryMethod<Paths extends {}, PathnameMethod extends HttpMethod> = {
|
|
109
116
|
[Pathname in keyof Paths]: Paths[Pathname] extends {
|
|
110
|
-
[K in PathnameMethod]:
|
|
117
|
+
[K in PathnameMethod]: unknown;
|
|
111
118
|
} ? Pathname : never;
|
|
112
119
|
}[keyof Paths];
|
|
120
|
+
/** The paths that have at least one method. */
|
|
121
|
+
type PathsWithAnyMethod<Paths extends {}> = {
|
|
122
|
+
[Pathname in keyof Paths]: {
|
|
123
|
+
[Method in HttpMethod]: Paths[Pathname] extends {
|
|
124
|
+
[K in Method]: unknown;
|
|
125
|
+
} ? Pathname : never;
|
|
126
|
+
}[HttpMethod];
|
|
127
|
+
}[keyof Paths];
|
|
128
|
+
/**
|
|
129
|
+
* Given an OpenAPI **Paths Object**, find all paths that have the given method. For a union of
|
|
130
|
+
* methods, the paths that have each of them, so a call with either method finds its operation.
|
|
131
|
+
* For `HttpMethod` itself, a method not known yet, the paths that have any method too: TypeScript
|
|
132
|
+
* uses it where a hook's `Method` is not inferred, as in `Parameters<typeof $api.queryOptions>`,
|
|
133
|
+
* and the paths with every method were none (upstream #2178).
|
|
134
|
+
*
|
|
135
|
+
* A union with upstream's type, not a conditional type over the method: code that is generic in
|
|
136
|
+
* the method (`Path extends PathsWithMethod<Paths, Method>`, as swr-openapi has) must still
|
|
137
|
+
* relate one `PathsWithMethod` to another, and TypeScript cannot relate a type to a conditional
|
|
138
|
+
* type that waits for its method (TS2344). For a known method the second member is `never`.
|
|
139
|
+
*/
|
|
140
|
+
type PathsWithMethod<Paths extends {}, PathnameMethod extends HttpMethod> = PathsWithEveryMethod<Paths, PathnameMethod> | (HttpMethod extends PathnameMethod ? PathsWithAnyMethod<Paths> : never);
|
|
141
|
+
/**
|
|
142
|
+
* DO NOT USE!
|
|
143
|
+
* Only used only for OperationObject type inference
|
|
144
|
+
*/
|
|
113
145
|
interface OperationObject {
|
|
114
146
|
parameters: any;
|
|
115
147
|
requestBody: any;
|
|
116
148
|
responses: any;
|
|
117
149
|
}
|
|
150
|
+
/** Internal helper used in PathsWithMethod */
|
|
118
151
|
type PathItemObject = {
|
|
119
152
|
[M in HttpMethod]: OperationObject;
|
|
120
153
|
} & {
|
|
121
154
|
parameters?: any;
|
|
122
155
|
};
|
|
156
|
+
/** Return `responses` for an Operation Object */
|
|
123
157
|
type ResponseObjectMap<T> = T extends {
|
|
124
158
|
responses: any;
|
|
125
159
|
} ? T["responses"] : unknown;
|
|
160
|
+
/** Return `content` for a Response Object */
|
|
126
161
|
type ResponseContent<T> = T extends {
|
|
127
162
|
content: any;
|
|
128
163
|
} ? T["content"] : unknown;
|
|
164
|
+
/** Return type of `requestBody` for an Operation Object */
|
|
129
165
|
type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
|
|
166
|
+
/** Internal helper to get object type with only the `requestBody` property */
|
|
130
167
|
type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
|
|
168
|
+
/** Resolve to `true` if request body is optional, else `false` */
|
|
131
169
|
type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
|
|
170
|
+
/** Internal helper used in OperationRequestBodyContent */
|
|
132
171
|
type OperationRequestBodyMediaContent<T> = IsOperationRequestBodyOptional<T> extends true ? ResponseContent<NonNullable<OperationRequestBody<T>>> | undefined : ResponseContent<OperationRequestBody<T>>;
|
|
172
|
+
/** Return first `content` from a Request Object Mapping, allowing any media type */
|
|
133
173
|
type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never ? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined : FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
|
|
134
|
-
|
|
174
|
+
/**
|
|
175
|
+
* The statuses of success responses in a Response Object Map: the 2XX statuses, or `default` when
|
|
176
|
+
* no 2XX status is declared. `default` covers every status the operation does not declare (OpenAPI
|
|
177
|
+
* Responses Object), so then it covers every success (upstream #1862). With a 2XX status declared,
|
|
178
|
+
* `default` is left to the errors, as before.
|
|
179
|
+
*/
|
|
180
|
+
type SuccessStatus<T> = [Extract<keyof T, OkStatus>] extends [never] ? "default" : OkStatus;
|
|
181
|
+
/** Return all 2XX responses from a Response Object Map, or `default` if it declares no 2XX one */
|
|
182
|
+
type SuccessResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, SuccessStatus<T>>;
|
|
135
183
|
type GetResponseContent<T extends Record<string | number, any>, Media extends MediaType = MediaType, ResponseCode extends keyof T = keyof T> = ResponseCode extends keyof T ? {
|
|
136
184
|
[K in ResponseCode]: T[K]["content"] extends Record<string, any> ? FilterKeys<T[K]["content"], Media> extends never ? T[K]["content"] : FilterKeys<T[K]["content"], Media> : K extends keyof T ? T[K]["content"] : never;
|
|
137
185
|
}[ResponseCode] : never;
|
|
186
|
+
/**
|
|
187
|
+
* Return all 5XX and 4XX responses (in that order) from a Response Object Map
|
|
188
|
+
*/
|
|
138
189
|
type ErrorResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, ErrorStatus>;
|
|
190
|
+
/** Return first JSON-like 2XX response from a path + HTTP method */
|
|
139
191
|
type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = SuccessResponse<ResponseObjectMap<PathMethod>, `${string}/json`>;
|
|
192
|
+
/** Return first JSON-like 5XX or 4XX response from a path + HTTP method */
|
|
140
193
|
type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = ErrorResponse<ResponseObjectMap<PathMethod>, `${string}/json`>;
|
|
194
|
+
/** Return JSON-like request body from a path + HTTP method */
|
|
141
195
|
type RequestBodyJSON<PathMethod> = JSONLike<FilterKeys<OperationRequestBody<PathMethod>, "content">>;
|
|
196
|
+
/** Find first match of multiple keys */
|
|
142
197
|
type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];
|
|
143
|
-
|
|
198
|
+
/**
|
|
199
|
+
* @deprecated Use `FilterKeys` instead
|
|
200
|
+
* Get the type of a value of an input object with a given key. If the key is
|
|
201
|
+
* not found, return a default type. Works with unions of objects too.
|
|
202
|
+
*/
|
|
203
|
+
type GetValueWithDefault<Obj, KeyPattern, Default> = Obj extends unknown ? FilterKeys<Obj, KeyPattern> extends never ? Default : FilterKeys<Obj, KeyPattern> : never;
|
|
204
|
+
/**
|
|
205
|
+
* Return any `[string]/[string]` media type (important because openapi-typesafe-fetch allows any
|
|
206
|
+
* content response, not just JSON-like)
|
|
207
|
+
*/
|
|
144
208
|
type MediaType = `${string}/${string}`;
|
|
209
|
+
/**
|
|
210
|
+
* Return any media type containing "json" (works for "application/json",
|
|
211
|
+
* "application/vnd.api+json", "application/vnd.oai.openapi+json")
|
|
212
|
+
*/
|
|
145
213
|
type JSONLike<T> = FilterKeys<T, `${string}/json`>;
|
|
214
|
+
/**
|
|
215
|
+
* Filter objects that have required keys
|
|
216
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
217
|
+
*/
|
|
146
218
|
type FindRequiredKeys<T, K extends keyof T> = K extends unknown ? undefined extends T[K] ? never : K : K;
|
|
219
|
+
/**
|
|
220
|
+
* Does this object contain required keys?
|
|
221
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
222
|
+
*/
|
|
147
223
|
type HasRequiredKeys<T> = FindRequiredKeys<T, keyof T>;
|
|
224
|
+
/**
|
|
225
|
+
* Helper to get the required keys of an object. If no keys are required, will be `undefined` with
|
|
226
|
+
* strictNullChecks enabled, else `never`
|
|
227
|
+
*/
|
|
148
228
|
type RequiredKeysOfHelper<T> = {
|
|
149
229
|
[K in keyof T]: {} extends Pick<T, K> ? never : K;
|
|
150
230
|
}[keyof T];
|
|
231
|
+
/** Get the required keys of an object, or `never` if no keys are required */
|
|
151
232
|
type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;
|
|
233
|
+
/** Marker type for readOnly properties (excluded from request bodies) */
|
|
152
234
|
type $Read<T> = {
|
|
153
235
|
readonly $read: T;
|
|
154
236
|
};
|
|
237
|
+
/** Marker type for writeOnly properties (excluded from response bodies) */
|
|
155
238
|
type $Write<T> = {
|
|
156
239
|
readonly $write: T;
|
|
157
240
|
};
|
|
241
|
+
/** Primitives, also branded ones (`string & { __brand: "Id" }`), which stay unmapped (#2765). */
|
|
158
242
|
type ReadWritePrimitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
243
|
+
/**
|
|
244
|
+
* Types that stay unmapped. Mapping a function type drops its call signatures, so a `Blob` from
|
|
245
|
+
* `--binary-as-blob` lost its methods (`arrayBuffer()`, `text()`, ...) in response data.
|
|
246
|
+
*/
|
|
159
247
|
type ReadWriteLeaf = ReadWritePrimitive | ((...args: never) => unknown);
|
|
248
|
+
/**
|
|
249
|
+
* Keys of `T` whose value is a `Marker`. A key whose value is only `null` or `undefined` is not
|
|
250
|
+
* marked: `NonNullable` of it is `never`, and `never` extends every marker (upstream #2717). The
|
|
251
|
+
* checks are not distributive (`NonNullable<T[K]>` is not a type parameter), so `never` is seen.
|
|
252
|
+
*/
|
|
160
253
|
type ReadWriteMarkedKeys<T, Marker> = {
|
|
161
254
|
[K in keyof T]-?: NonNullable<T[K]> extends never ? never : NonNullable<T[K]> extends Marker ? K : never;
|
|
162
255
|
}[keyof T];
|
|
256
|
+
/**
|
|
257
|
+
* Resolve an array or a tuple element by element. An array uses `T[number]`, not `infer E`: for an
|
|
258
|
+
* intersection of arrays (`allOf`) inference keeps one member and narrowing breaks (upstream
|
|
259
|
+
* #2620). `T` is a plain array when an array of its elements is assignable to it; otherwise it is a
|
|
260
|
+
* tuple (also `[A, ...B[]]`), mapped homomorphically to stay a tuple (upstream #2632). Both keep
|
|
261
|
+
* `readonly` (upstream #2615).
|
|
262
|
+
*/
|
|
163
263
|
type ReadWriteResolveArray<T extends readonly unknown[], Resolved extends "read" | "write"> = T[number][] extends T ? T extends unknown[] ? ReadWriteResolve<T[number], Resolved>[] : readonly ReadWriteResolve<T[number], Resolved>[] : {
|
|
164
264
|
[K in keyof T]: ReadWriteResolve<T[K], Resolved>;
|
|
165
265
|
};
|
|
166
266
|
type ReadWriteResolve<T, Resolved extends "read" | "write"> = Resolved extends "read" ? Readable<T> : Writable<T>;
|
|
267
|
+
/**
|
|
268
|
+
* Resolve type for reading (responses): strips $Write properties, unwraps $Read
|
|
269
|
+
* - $Read<T> → T (readable), continues recursion
|
|
270
|
+
* - $Write<T> → never (excluded from response)
|
|
271
|
+
* - primitives (also branded), functions, arrays and tuples keep their shape; objects resolve
|
|
272
|
+
* recursively
|
|
273
|
+
*/
|
|
167
274
|
type Readable<T> = T extends $Write<any> ? never : T extends $Read<infer U> ? Readable<U> : T extends ReadWriteLeaf ? T : T extends readonly unknown[] ? ReadWriteResolveArray<T, "read"> : T extends object ? {
|
|
168
275
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Write<any>> ? never : K]: Readable<T[K]>;
|
|
169
276
|
} : T;
|
|
277
|
+
/**
|
|
278
|
+
* Resolve type for writing (requests): strips $Read properties, unwraps $Write
|
|
279
|
+
* - $Write<T> → T (writable), continues recursion
|
|
280
|
+
* - $Read<T> → never (excluded from request)
|
|
281
|
+
* - primitives (also branded), functions, arrays and tuples keep their shape; objects resolve
|
|
282
|
+
* recursively
|
|
283
|
+
*/
|
|
170
284
|
type Writable<T> = T extends $Read<any> ? never : T extends $Write<infer U> ? Writable<U> : T extends ReadWriteLeaf ? T : T extends readonly unknown[] ? ReadWriteResolveArray<T, "write"> : T extends object ? {
|
|
171
285
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Read<any>> ? never : K]: Writable<T[K]>;
|
|
172
286
|
} & {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,172 +1,286 @@
|
|
|
1
|
-
type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"
|
|
1
|
+
type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"
|
|
2
|
+
/** OpenAPI 3.2: a safe, idempotent request with a body. */
|
|
3
|
+
| "query";
|
|
4
|
+
/** 2XX statuses */
|
|
2
5
|
type OkStatus = 200 | 201 | 202 | 203 | 204 | 206 | 207 | "2XX";
|
|
6
|
+
/** 4XX and 5XX statuses */
|
|
3
7
|
type ErrorStatus = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | "5XX" | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 444 | 450 | 451 | 497 | 498 | 499 | "4XX" | "default";
|
|
8
|
+
/** Get a union of OK Statuses */
|
|
4
9
|
type OKStatusUnion<T> = FilterKeys<T, OkStatus>;
|
|
10
|
+
/** Get first error status, in order */
|
|
5
11
|
type FirstErrorStatus<T> = T extends {
|
|
6
|
-
500:
|
|
12
|
+
500: unknown;
|
|
7
13
|
} ? T[500] : T extends {
|
|
8
|
-
501:
|
|
14
|
+
501: unknown;
|
|
9
15
|
} ? T[501] : T extends {
|
|
10
|
-
502:
|
|
16
|
+
502: unknown;
|
|
11
17
|
} ? T[502] : T extends {
|
|
12
|
-
503:
|
|
18
|
+
503: unknown;
|
|
13
19
|
} ? T[503] : T extends {
|
|
14
|
-
504:
|
|
20
|
+
504: unknown;
|
|
15
21
|
} ? T[504] : T extends {
|
|
16
|
-
505:
|
|
22
|
+
505: unknown;
|
|
17
23
|
} ? T[505] : T extends {
|
|
18
|
-
506:
|
|
24
|
+
506: unknown;
|
|
19
25
|
} ? T[506] : T extends {
|
|
20
|
-
507:
|
|
26
|
+
507: unknown;
|
|
21
27
|
} ? T[507] : T extends {
|
|
22
|
-
508:
|
|
28
|
+
508: unknown;
|
|
23
29
|
} ? T[508] : T extends {
|
|
24
|
-
510:
|
|
30
|
+
510: unknown;
|
|
25
31
|
} ? T[510] : T extends {
|
|
26
|
-
511:
|
|
32
|
+
511: unknown;
|
|
27
33
|
} ? T[511] : T extends {
|
|
28
|
-
"5XX":
|
|
34
|
+
"5XX": unknown;
|
|
29
35
|
} ? T["5XX"] : T extends {
|
|
30
|
-
400:
|
|
36
|
+
400: unknown;
|
|
31
37
|
} ? T[400] : T extends {
|
|
32
|
-
401:
|
|
38
|
+
401: unknown;
|
|
33
39
|
} ? T[401] : T extends {
|
|
34
|
-
402:
|
|
40
|
+
402: unknown;
|
|
35
41
|
} ? T[402] : T extends {
|
|
36
|
-
403:
|
|
42
|
+
403: unknown;
|
|
37
43
|
} ? T[403] : T extends {
|
|
38
|
-
404:
|
|
44
|
+
404: unknown;
|
|
39
45
|
} ? T[404] : T extends {
|
|
40
|
-
405:
|
|
46
|
+
405: unknown;
|
|
41
47
|
} ? T[405] : T extends {
|
|
42
|
-
406:
|
|
48
|
+
406: unknown;
|
|
43
49
|
} ? T[406] : T extends {
|
|
44
|
-
407:
|
|
50
|
+
407: unknown;
|
|
45
51
|
} ? T[407] : T extends {
|
|
46
|
-
408:
|
|
52
|
+
408: unknown;
|
|
47
53
|
} ? T[408] : T extends {
|
|
48
|
-
409:
|
|
54
|
+
409: unknown;
|
|
49
55
|
} ? T[409] : T extends {
|
|
50
|
-
410:
|
|
56
|
+
410: unknown;
|
|
51
57
|
} ? T[410] : T extends {
|
|
52
|
-
411:
|
|
58
|
+
411: unknown;
|
|
53
59
|
} ? T[411] : T extends {
|
|
54
|
-
412:
|
|
60
|
+
412: unknown;
|
|
55
61
|
} ? T[412] : T extends {
|
|
56
|
-
413:
|
|
62
|
+
413: unknown;
|
|
57
63
|
} ? T[413] : T extends {
|
|
58
|
-
414:
|
|
64
|
+
414: unknown;
|
|
59
65
|
} ? T[414] : T extends {
|
|
60
|
-
415:
|
|
66
|
+
415: unknown;
|
|
61
67
|
} ? T[415] : T extends {
|
|
62
|
-
416:
|
|
68
|
+
416: unknown;
|
|
63
69
|
} ? T[416] : T extends {
|
|
64
|
-
417:
|
|
70
|
+
417: unknown;
|
|
65
71
|
} ? T[417] : T extends {
|
|
66
|
-
418:
|
|
72
|
+
418: unknown;
|
|
67
73
|
} ? T[418] : T extends {
|
|
68
|
-
420:
|
|
74
|
+
420: unknown;
|
|
69
75
|
} ? T[420] : T extends {
|
|
70
|
-
421:
|
|
76
|
+
421: unknown;
|
|
71
77
|
} ? T[421] : T extends {
|
|
72
|
-
422:
|
|
78
|
+
422: unknown;
|
|
73
79
|
} ? T[422] : T extends {
|
|
74
|
-
423:
|
|
80
|
+
423: unknown;
|
|
75
81
|
} ? T[423] : T extends {
|
|
76
|
-
424:
|
|
82
|
+
424: unknown;
|
|
77
83
|
} ? T[424] : T extends {
|
|
78
|
-
425:
|
|
84
|
+
425: unknown;
|
|
79
85
|
} ? T[425] : T extends {
|
|
80
|
-
426:
|
|
86
|
+
426: unknown;
|
|
81
87
|
} ? T[426] : T extends {
|
|
82
|
-
427:
|
|
88
|
+
427: unknown;
|
|
83
89
|
} ? T[427] : T extends {
|
|
84
|
-
428:
|
|
90
|
+
428: unknown;
|
|
85
91
|
} ? T[428] : T extends {
|
|
86
|
-
429:
|
|
92
|
+
429: unknown;
|
|
87
93
|
} ? T[429] : T extends {
|
|
88
|
-
430:
|
|
94
|
+
430: unknown;
|
|
89
95
|
} ? T[430] : T extends {
|
|
90
|
-
431:
|
|
96
|
+
431: unknown;
|
|
91
97
|
} ? T[431] : T extends {
|
|
92
|
-
444:
|
|
98
|
+
444: unknown;
|
|
93
99
|
} ? T[444] : T extends {
|
|
94
|
-
450:
|
|
100
|
+
450: unknown;
|
|
95
101
|
} ? T[450] : T extends {
|
|
96
|
-
451:
|
|
102
|
+
451: unknown;
|
|
97
103
|
} ? T[451] : T extends {
|
|
98
|
-
497:
|
|
104
|
+
497: unknown;
|
|
99
105
|
} ? T[497] : T extends {
|
|
100
|
-
498:
|
|
106
|
+
498: unknown;
|
|
101
107
|
} ? T[498] : T extends {
|
|
102
|
-
499:
|
|
108
|
+
499: unknown;
|
|
103
109
|
} ? T[499] : T extends {
|
|
104
|
-
"4XX":
|
|
110
|
+
"4XX": unknown;
|
|
105
111
|
} ? T["4XX"] : T extends {
|
|
106
|
-
default:
|
|
112
|
+
default: unknown;
|
|
107
113
|
} ? T["default"] : never;
|
|
108
|
-
|
|
114
|
+
/** The paths that have each of the methods: upstream's `PathsWithMethod`. */
|
|
115
|
+
type PathsWithEveryMethod<Paths extends {}, PathnameMethod extends HttpMethod> = {
|
|
109
116
|
[Pathname in keyof Paths]: Paths[Pathname] extends {
|
|
110
|
-
[K in PathnameMethod]:
|
|
117
|
+
[K in PathnameMethod]: unknown;
|
|
111
118
|
} ? Pathname : never;
|
|
112
119
|
}[keyof Paths];
|
|
120
|
+
/** The paths that have at least one method. */
|
|
121
|
+
type PathsWithAnyMethod<Paths extends {}> = {
|
|
122
|
+
[Pathname in keyof Paths]: {
|
|
123
|
+
[Method in HttpMethod]: Paths[Pathname] extends {
|
|
124
|
+
[K in Method]: unknown;
|
|
125
|
+
} ? Pathname : never;
|
|
126
|
+
}[HttpMethod];
|
|
127
|
+
}[keyof Paths];
|
|
128
|
+
/**
|
|
129
|
+
* Given an OpenAPI **Paths Object**, find all paths that have the given method. For a union of
|
|
130
|
+
* methods, the paths that have each of them, so a call with either method finds its operation.
|
|
131
|
+
* For `HttpMethod` itself, a method not known yet, the paths that have any method too: TypeScript
|
|
132
|
+
* uses it where a hook's `Method` is not inferred, as in `Parameters<typeof $api.queryOptions>`,
|
|
133
|
+
* and the paths with every method were none (upstream #2178).
|
|
134
|
+
*
|
|
135
|
+
* A union with upstream's type, not a conditional type over the method: code that is generic in
|
|
136
|
+
* the method (`Path extends PathsWithMethod<Paths, Method>`, as swr-openapi has) must still
|
|
137
|
+
* relate one `PathsWithMethod` to another, and TypeScript cannot relate a type to a conditional
|
|
138
|
+
* type that waits for its method (TS2344). For a known method the second member is `never`.
|
|
139
|
+
*/
|
|
140
|
+
type PathsWithMethod<Paths extends {}, PathnameMethod extends HttpMethod> = PathsWithEveryMethod<Paths, PathnameMethod> | (HttpMethod extends PathnameMethod ? PathsWithAnyMethod<Paths> : never);
|
|
141
|
+
/**
|
|
142
|
+
* DO NOT USE!
|
|
143
|
+
* Only used only for OperationObject type inference
|
|
144
|
+
*/
|
|
113
145
|
interface OperationObject {
|
|
114
146
|
parameters: any;
|
|
115
147
|
requestBody: any;
|
|
116
148
|
responses: any;
|
|
117
149
|
}
|
|
150
|
+
/** Internal helper used in PathsWithMethod */
|
|
118
151
|
type PathItemObject = {
|
|
119
152
|
[M in HttpMethod]: OperationObject;
|
|
120
153
|
} & {
|
|
121
154
|
parameters?: any;
|
|
122
155
|
};
|
|
156
|
+
/** Return `responses` for an Operation Object */
|
|
123
157
|
type ResponseObjectMap<T> = T extends {
|
|
124
158
|
responses: any;
|
|
125
159
|
} ? T["responses"] : unknown;
|
|
160
|
+
/** Return `content` for a Response Object */
|
|
126
161
|
type ResponseContent<T> = T extends {
|
|
127
162
|
content: any;
|
|
128
163
|
} ? T["content"] : unknown;
|
|
164
|
+
/** Return type of `requestBody` for an Operation Object */
|
|
129
165
|
type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
|
|
166
|
+
/** Internal helper to get object type with only the `requestBody` property */
|
|
130
167
|
type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
|
|
168
|
+
/** Resolve to `true` if request body is optional, else `false` */
|
|
131
169
|
type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
|
|
170
|
+
/** Internal helper used in OperationRequestBodyContent */
|
|
132
171
|
type OperationRequestBodyMediaContent<T> = IsOperationRequestBodyOptional<T> extends true ? ResponseContent<NonNullable<OperationRequestBody<T>>> | undefined : ResponseContent<OperationRequestBody<T>>;
|
|
172
|
+
/** Return first `content` from a Request Object Mapping, allowing any media type */
|
|
133
173
|
type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never ? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined : FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
|
|
134
|
-
|
|
174
|
+
/**
|
|
175
|
+
* The statuses of success responses in a Response Object Map: the 2XX statuses, or `default` when
|
|
176
|
+
* no 2XX status is declared. `default` covers every status the operation does not declare (OpenAPI
|
|
177
|
+
* Responses Object), so then it covers every success (upstream #1862). With a 2XX status declared,
|
|
178
|
+
* `default` is left to the errors, as before.
|
|
179
|
+
*/
|
|
180
|
+
type SuccessStatus<T> = [Extract<keyof T, OkStatus>] extends [never] ? "default" : OkStatus;
|
|
181
|
+
/** Return all 2XX responses from a Response Object Map, or `default` if it declares no 2XX one */
|
|
182
|
+
type SuccessResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, SuccessStatus<T>>;
|
|
135
183
|
type GetResponseContent<T extends Record<string | number, any>, Media extends MediaType = MediaType, ResponseCode extends keyof T = keyof T> = ResponseCode extends keyof T ? {
|
|
136
184
|
[K in ResponseCode]: T[K]["content"] extends Record<string, any> ? FilterKeys<T[K]["content"], Media> extends never ? T[K]["content"] : FilterKeys<T[K]["content"], Media> : K extends keyof T ? T[K]["content"] : never;
|
|
137
185
|
}[ResponseCode] : never;
|
|
186
|
+
/**
|
|
187
|
+
* Return all 5XX and 4XX responses (in that order) from a Response Object Map
|
|
188
|
+
*/
|
|
138
189
|
type ErrorResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, ErrorStatus>;
|
|
190
|
+
/** Return first JSON-like 2XX response from a path + HTTP method */
|
|
139
191
|
type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = SuccessResponse<ResponseObjectMap<PathMethod>, `${string}/json`>;
|
|
192
|
+
/** Return first JSON-like 5XX or 4XX response from a path + HTTP method */
|
|
140
193
|
type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = ErrorResponse<ResponseObjectMap<PathMethod>, `${string}/json`>;
|
|
194
|
+
/** Return JSON-like request body from a path + HTTP method */
|
|
141
195
|
type RequestBodyJSON<PathMethod> = JSONLike<FilterKeys<OperationRequestBody<PathMethod>, "content">>;
|
|
196
|
+
/** Find first match of multiple keys */
|
|
142
197
|
type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];
|
|
143
|
-
|
|
198
|
+
/**
|
|
199
|
+
* @deprecated Use `FilterKeys` instead
|
|
200
|
+
* Get the type of a value of an input object with a given key. If the key is
|
|
201
|
+
* not found, return a default type. Works with unions of objects too.
|
|
202
|
+
*/
|
|
203
|
+
type GetValueWithDefault<Obj, KeyPattern, Default> = Obj extends unknown ? FilterKeys<Obj, KeyPattern> extends never ? Default : FilterKeys<Obj, KeyPattern> : never;
|
|
204
|
+
/**
|
|
205
|
+
* Return any `[string]/[string]` media type (important because openapi-typesafe-fetch allows any
|
|
206
|
+
* content response, not just JSON-like)
|
|
207
|
+
*/
|
|
144
208
|
type MediaType = `${string}/${string}`;
|
|
209
|
+
/**
|
|
210
|
+
* Return any media type containing "json" (works for "application/json",
|
|
211
|
+
* "application/vnd.api+json", "application/vnd.oai.openapi+json")
|
|
212
|
+
*/
|
|
145
213
|
type JSONLike<T> = FilterKeys<T, `${string}/json`>;
|
|
214
|
+
/**
|
|
215
|
+
* Filter objects that have required keys
|
|
216
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
217
|
+
*/
|
|
146
218
|
type FindRequiredKeys<T, K extends keyof T> = K extends unknown ? undefined extends T[K] ? never : K : K;
|
|
219
|
+
/**
|
|
220
|
+
* Does this object contain required keys?
|
|
221
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
222
|
+
*/
|
|
147
223
|
type HasRequiredKeys<T> = FindRequiredKeys<T, keyof T>;
|
|
224
|
+
/**
|
|
225
|
+
* Helper to get the required keys of an object. If no keys are required, will be `undefined` with
|
|
226
|
+
* strictNullChecks enabled, else `never`
|
|
227
|
+
*/
|
|
148
228
|
type RequiredKeysOfHelper<T> = {
|
|
149
229
|
[K in keyof T]: {} extends Pick<T, K> ? never : K;
|
|
150
230
|
}[keyof T];
|
|
231
|
+
/** Get the required keys of an object, or `never` if no keys are required */
|
|
151
232
|
type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;
|
|
233
|
+
/** Marker type for readOnly properties (excluded from request bodies) */
|
|
152
234
|
type $Read<T> = {
|
|
153
235
|
readonly $read: T;
|
|
154
236
|
};
|
|
237
|
+
/** Marker type for writeOnly properties (excluded from response bodies) */
|
|
155
238
|
type $Write<T> = {
|
|
156
239
|
readonly $write: T;
|
|
157
240
|
};
|
|
241
|
+
/** Primitives, also branded ones (`string & { __brand: "Id" }`), which stay unmapped (#2765). */
|
|
158
242
|
type ReadWritePrimitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
243
|
+
/**
|
|
244
|
+
* Types that stay unmapped. Mapping a function type drops its call signatures, so a `Blob` from
|
|
245
|
+
* `--binary-as-blob` lost its methods (`arrayBuffer()`, `text()`, ...) in response data.
|
|
246
|
+
*/
|
|
159
247
|
type ReadWriteLeaf = ReadWritePrimitive | ((...args: never) => unknown);
|
|
248
|
+
/**
|
|
249
|
+
* Keys of `T` whose value is a `Marker`. A key whose value is only `null` or `undefined` is not
|
|
250
|
+
* marked: `NonNullable` of it is `never`, and `never` extends every marker (upstream #2717). The
|
|
251
|
+
* checks are not distributive (`NonNullable<T[K]>` is not a type parameter), so `never` is seen.
|
|
252
|
+
*/
|
|
160
253
|
type ReadWriteMarkedKeys<T, Marker> = {
|
|
161
254
|
[K in keyof T]-?: NonNullable<T[K]> extends never ? never : NonNullable<T[K]> extends Marker ? K : never;
|
|
162
255
|
}[keyof T];
|
|
256
|
+
/**
|
|
257
|
+
* Resolve an array or a tuple element by element. An array uses `T[number]`, not `infer E`: for an
|
|
258
|
+
* intersection of arrays (`allOf`) inference keeps one member and narrowing breaks (upstream
|
|
259
|
+
* #2620). `T` is a plain array when an array of its elements is assignable to it; otherwise it is a
|
|
260
|
+
* tuple (also `[A, ...B[]]`), mapped homomorphically to stay a tuple (upstream #2632). Both keep
|
|
261
|
+
* `readonly` (upstream #2615).
|
|
262
|
+
*/
|
|
163
263
|
type ReadWriteResolveArray<T extends readonly unknown[], Resolved extends "read" | "write"> = T[number][] extends T ? T extends unknown[] ? ReadWriteResolve<T[number], Resolved>[] : readonly ReadWriteResolve<T[number], Resolved>[] : {
|
|
164
264
|
[K in keyof T]: ReadWriteResolve<T[K], Resolved>;
|
|
165
265
|
};
|
|
166
266
|
type ReadWriteResolve<T, Resolved extends "read" | "write"> = Resolved extends "read" ? Readable<T> : Writable<T>;
|
|
267
|
+
/**
|
|
268
|
+
* Resolve type for reading (responses): strips $Write properties, unwraps $Read
|
|
269
|
+
* - $Read<T> → T (readable), continues recursion
|
|
270
|
+
* - $Write<T> → never (excluded from response)
|
|
271
|
+
* - primitives (also branded), functions, arrays and tuples keep their shape; objects resolve
|
|
272
|
+
* recursively
|
|
273
|
+
*/
|
|
167
274
|
type Readable<T> = T extends $Write<any> ? never : T extends $Read<infer U> ? Readable<U> : T extends ReadWriteLeaf ? T : T extends readonly unknown[] ? ReadWriteResolveArray<T, "read"> : T extends object ? {
|
|
168
275
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Write<any>> ? never : K]: Readable<T[K]>;
|
|
169
276
|
} : T;
|
|
277
|
+
/**
|
|
278
|
+
* Resolve type for writing (requests): strips $Read properties, unwraps $Write
|
|
279
|
+
* - $Write<T> → T (writable), continues recursion
|
|
280
|
+
* - $Read<T> → never (excluded from request)
|
|
281
|
+
* - primitives (also branded), functions, arrays and tuples keep their shape; objects resolve
|
|
282
|
+
* recursively
|
|
283
|
+
*/
|
|
170
284
|
type Writable<T> = T extends $Read<any> ? never : T extends $Write<infer U> ? Writable<U> : T extends ReadWriteLeaf ? T : T extends readonly unknown[] ? ReadWriteResolveArray<T, "write"> : T extends object ? {
|
|
171
285
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Read<any>> ? never : K]: Writable<T[K]>;
|
|
172
286
|
} & {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-typesafe-helpers",
|
|
3
3
|
"description": "TypeScript helpers for consuming openapi-typesafe types",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Fedor Chishchin",
|
|
7
7
|
"url": "https://github.com/fedorello"
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"url": "https://github.com/openapi-typesafe/openapi-typesafe/issues"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"typescript": "^6.0.3"
|
|
39
|
+
"typescript": "^6.0.3",
|
|
40
|
+
"vite-node": "6.0.0"
|
|
40
41
|
},
|
|
41
42
|
"engines": {
|
|
42
43
|
"node": ">=22"
|
|
@@ -44,9 +45,10 @@
|
|
|
44
45
|
"scripts": {
|
|
45
46
|
"build": "unbuild",
|
|
46
47
|
"format": "biome format src --write",
|
|
47
|
-
"lint": "pnpm run lint:js && pnpm run lint:ts",
|
|
48
|
+
"lint": "pnpm run lint:js && pnpm run lint:ts && pnpm run lint:sizes",
|
|
48
49
|
"lint:js": "biome check src",
|
|
49
50
|
"lint:ts": "tsc --noEmit",
|
|
51
|
+
"lint:sizes": "vite-node ../openapi-typesafe/scripts/size-rules/check-sizes.ts src",
|
|
50
52
|
"test": "pnpm run test:exports",
|
|
51
53
|
"test:exports": "pnpm run build && ../../scripts/check-exports.sh"
|
|
52
54
|
}
|