openapi-typesafe-helpers 1.0.0-rc.1 → 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 +160 -55
- package/dist/index.d.mts +160 -55
- package/dist/index.d.ts +160 -55
- 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,181 +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;
|
|
114
|
+
/** The paths that have each of the methods: upstream's `PathsWithMethod`. */
|
|
108
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. */
|
|
113
121
|
type PathsWithAnyMethod<Paths extends {}> = {
|
|
114
122
|
[Pathname in keyof Paths]: {
|
|
115
123
|
[Method in HttpMethod]: Paths[Pathname] extends {
|
|
116
|
-
[K in Method]:
|
|
124
|
+
[K in Method]: unknown;
|
|
117
125
|
} ? Pathname : never;
|
|
118
126
|
}[HttpMethod];
|
|
119
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
|
+
*/
|
|
120
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
|
+
*/
|
|
121
145
|
interface OperationObject {
|
|
122
146
|
parameters: any;
|
|
123
147
|
requestBody: any;
|
|
124
148
|
responses: any;
|
|
125
149
|
}
|
|
150
|
+
/** Internal helper used in PathsWithMethod */
|
|
126
151
|
type PathItemObject = {
|
|
127
152
|
[M in HttpMethod]: OperationObject;
|
|
128
153
|
} & {
|
|
129
154
|
parameters?: any;
|
|
130
155
|
};
|
|
156
|
+
/** Return `responses` for an Operation Object */
|
|
131
157
|
type ResponseObjectMap<T> = T extends {
|
|
132
158
|
responses: any;
|
|
133
159
|
} ? T["responses"] : unknown;
|
|
160
|
+
/** Return `content` for a Response Object */
|
|
134
161
|
type ResponseContent<T> = T extends {
|
|
135
162
|
content: any;
|
|
136
163
|
} ? T["content"] : unknown;
|
|
164
|
+
/** Return type of `requestBody` for an Operation Object */
|
|
137
165
|
type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
|
|
166
|
+
/** Internal helper to get object type with only the `requestBody` property */
|
|
138
167
|
type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
|
|
168
|
+
/** Resolve to `true` if request body is optional, else `false` */
|
|
139
169
|
type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
|
|
170
|
+
/** Internal helper used in OperationRequestBodyContent */
|
|
140
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 */
|
|
141
173
|
type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never ? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined : FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
|
|
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
|
+
*/
|
|
142
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 */
|
|
143
182
|
type SuccessResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, SuccessStatus<T>>;
|
|
144
183
|
type GetResponseContent<T extends Record<string | number, any>, Media extends MediaType = MediaType, ResponseCode extends keyof T = keyof T> = ResponseCode extends keyof T ? {
|
|
145
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;
|
|
146
185
|
}[ResponseCode] : never;
|
|
186
|
+
/**
|
|
187
|
+
* Return all 5XX and 4XX responses (in that order) from a Response Object Map
|
|
188
|
+
*/
|
|
147
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 */
|
|
148
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 */
|
|
149
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 */
|
|
150
195
|
type RequestBodyJSON<PathMethod> = JSONLike<FilterKeys<OperationRequestBody<PathMethod>, "content">>;
|
|
196
|
+
/** Find first match of multiple keys */
|
|
151
197
|
type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];
|
|
152
|
-
|
|
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
|
+
*/
|
|
153
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
|
+
*/
|
|
154
213
|
type JSONLike<T> = FilterKeys<T, `${string}/json`>;
|
|
214
|
+
/**
|
|
215
|
+
* Filter objects that have required keys
|
|
216
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
217
|
+
*/
|
|
155
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
|
+
*/
|
|
156
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
|
+
*/
|
|
157
228
|
type RequiredKeysOfHelper<T> = {
|
|
158
229
|
[K in keyof T]: {} extends Pick<T, K> ? never : K;
|
|
159
230
|
}[keyof T];
|
|
231
|
+
/** Get the required keys of an object, or `never` if no keys are required */
|
|
160
232
|
type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;
|
|
233
|
+
/** Marker type for readOnly properties (excluded from request bodies) */
|
|
161
234
|
type $Read<T> = {
|
|
162
235
|
readonly $read: T;
|
|
163
236
|
};
|
|
237
|
+
/** Marker type for writeOnly properties (excluded from response bodies) */
|
|
164
238
|
type $Write<T> = {
|
|
165
239
|
readonly $write: T;
|
|
166
240
|
};
|
|
241
|
+
/** Primitives, also branded ones (`string & { __brand: "Id" }`), which stay unmapped (#2765). */
|
|
167
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
|
+
*/
|
|
168
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
|
+
*/
|
|
169
253
|
type ReadWriteMarkedKeys<T, Marker> = {
|
|
170
254
|
[K in keyof T]-?: NonNullable<T[K]> extends never ? never : NonNullable<T[K]> extends Marker ? K : never;
|
|
171
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
|
+
*/
|
|
172
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>[] : {
|
|
173
264
|
[K in keyof T]: ReadWriteResolve<T[K], Resolved>;
|
|
174
265
|
};
|
|
175
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
|
+
*/
|
|
176
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 ? {
|
|
177
275
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Write<any>> ? never : K]: Readable<T[K]>;
|
|
178
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
|
+
*/
|
|
179
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 ? {
|
|
180
285
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Read<any>> ? never : K]: Writable<T[K]>;
|
|
181
286
|
} & {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,181 +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;
|
|
114
|
+
/** The paths that have each of the methods: upstream's `PathsWithMethod`. */
|
|
108
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. */
|
|
113
121
|
type PathsWithAnyMethod<Paths extends {}> = {
|
|
114
122
|
[Pathname in keyof Paths]: {
|
|
115
123
|
[Method in HttpMethod]: Paths[Pathname] extends {
|
|
116
|
-
[K in Method]:
|
|
124
|
+
[K in Method]: unknown;
|
|
117
125
|
} ? Pathname : never;
|
|
118
126
|
}[HttpMethod];
|
|
119
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
|
+
*/
|
|
120
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
|
+
*/
|
|
121
145
|
interface OperationObject {
|
|
122
146
|
parameters: any;
|
|
123
147
|
requestBody: any;
|
|
124
148
|
responses: any;
|
|
125
149
|
}
|
|
150
|
+
/** Internal helper used in PathsWithMethod */
|
|
126
151
|
type PathItemObject = {
|
|
127
152
|
[M in HttpMethod]: OperationObject;
|
|
128
153
|
} & {
|
|
129
154
|
parameters?: any;
|
|
130
155
|
};
|
|
156
|
+
/** Return `responses` for an Operation Object */
|
|
131
157
|
type ResponseObjectMap<T> = T extends {
|
|
132
158
|
responses: any;
|
|
133
159
|
} ? T["responses"] : unknown;
|
|
160
|
+
/** Return `content` for a Response Object */
|
|
134
161
|
type ResponseContent<T> = T extends {
|
|
135
162
|
content: any;
|
|
136
163
|
} ? T["content"] : unknown;
|
|
164
|
+
/** Return type of `requestBody` for an Operation Object */
|
|
137
165
|
type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
|
|
166
|
+
/** Internal helper to get object type with only the `requestBody` property */
|
|
138
167
|
type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
|
|
168
|
+
/** Resolve to `true` if request body is optional, else `false` */
|
|
139
169
|
type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
|
|
170
|
+
/** Internal helper used in OperationRequestBodyContent */
|
|
140
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 */
|
|
141
173
|
type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never ? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined : FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
|
|
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
|
+
*/
|
|
142
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 */
|
|
143
182
|
type SuccessResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, SuccessStatus<T>>;
|
|
144
183
|
type GetResponseContent<T extends Record<string | number, any>, Media extends MediaType = MediaType, ResponseCode extends keyof T = keyof T> = ResponseCode extends keyof T ? {
|
|
145
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;
|
|
146
185
|
}[ResponseCode] : never;
|
|
186
|
+
/**
|
|
187
|
+
* Return all 5XX and 4XX responses (in that order) from a Response Object Map
|
|
188
|
+
*/
|
|
147
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 */
|
|
148
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 */
|
|
149
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 */
|
|
150
195
|
type RequestBodyJSON<PathMethod> = JSONLike<FilterKeys<OperationRequestBody<PathMethod>, "content">>;
|
|
196
|
+
/** Find first match of multiple keys */
|
|
151
197
|
type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];
|
|
152
|
-
|
|
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
|
+
*/
|
|
153
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
|
+
*/
|
|
154
213
|
type JSONLike<T> = FilterKeys<T, `${string}/json`>;
|
|
214
|
+
/**
|
|
215
|
+
* Filter objects that have required keys
|
|
216
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
217
|
+
*/
|
|
155
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
|
+
*/
|
|
156
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
|
+
*/
|
|
157
228
|
type RequiredKeysOfHelper<T> = {
|
|
158
229
|
[K in keyof T]: {} extends Pick<T, K> ? never : K;
|
|
159
230
|
}[keyof T];
|
|
231
|
+
/** Get the required keys of an object, or `never` if no keys are required */
|
|
160
232
|
type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;
|
|
233
|
+
/** Marker type for readOnly properties (excluded from request bodies) */
|
|
161
234
|
type $Read<T> = {
|
|
162
235
|
readonly $read: T;
|
|
163
236
|
};
|
|
237
|
+
/** Marker type for writeOnly properties (excluded from response bodies) */
|
|
164
238
|
type $Write<T> = {
|
|
165
239
|
readonly $write: T;
|
|
166
240
|
};
|
|
241
|
+
/** Primitives, also branded ones (`string & { __brand: "Id" }`), which stay unmapped (#2765). */
|
|
167
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
|
+
*/
|
|
168
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
|
+
*/
|
|
169
253
|
type ReadWriteMarkedKeys<T, Marker> = {
|
|
170
254
|
[K in keyof T]-?: NonNullable<T[K]> extends never ? never : NonNullable<T[K]> extends Marker ? K : never;
|
|
171
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
|
+
*/
|
|
172
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>[] : {
|
|
173
264
|
[K in keyof T]: ReadWriteResolve<T[K], Resolved>;
|
|
174
265
|
};
|
|
175
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
|
+
*/
|
|
176
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 ? {
|
|
177
275
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Write<any>> ? never : K]: Readable<T[K]>;
|
|
178
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
|
+
*/
|
|
179
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 ? {
|
|
180
285
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Read<any>> ? never : K]: Writable<T[K]>;
|
|
181
286
|
} & {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,181 +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;
|
|
114
|
+
/** The paths that have each of the methods: upstream's `PathsWithMethod`. */
|
|
108
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. */
|
|
113
121
|
type PathsWithAnyMethod<Paths extends {}> = {
|
|
114
122
|
[Pathname in keyof Paths]: {
|
|
115
123
|
[Method in HttpMethod]: Paths[Pathname] extends {
|
|
116
|
-
[K in Method]:
|
|
124
|
+
[K in Method]: unknown;
|
|
117
125
|
} ? Pathname : never;
|
|
118
126
|
}[HttpMethod];
|
|
119
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
|
+
*/
|
|
120
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
|
+
*/
|
|
121
145
|
interface OperationObject {
|
|
122
146
|
parameters: any;
|
|
123
147
|
requestBody: any;
|
|
124
148
|
responses: any;
|
|
125
149
|
}
|
|
150
|
+
/** Internal helper used in PathsWithMethod */
|
|
126
151
|
type PathItemObject = {
|
|
127
152
|
[M in HttpMethod]: OperationObject;
|
|
128
153
|
} & {
|
|
129
154
|
parameters?: any;
|
|
130
155
|
};
|
|
156
|
+
/** Return `responses` for an Operation Object */
|
|
131
157
|
type ResponseObjectMap<T> = T extends {
|
|
132
158
|
responses: any;
|
|
133
159
|
} ? T["responses"] : unknown;
|
|
160
|
+
/** Return `content` for a Response Object */
|
|
134
161
|
type ResponseContent<T> = T extends {
|
|
135
162
|
content: any;
|
|
136
163
|
} ? T["content"] : unknown;
|
|
164
|
+
/** Return type of `requestBody` for an Operation Object */
|
|
137
165
|
type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
|
|
166
|
+
/** Internal helper to get object type with only the `requestBody` property */
|
|
138
167
|
type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
|
|
168
|
+
/** Resolve to `true` if request body is optional, else `false` */
|
|
139
169
|
type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
|
|
170
|
+
/** Internal helper used in OperationRequestBodyContent */
|
|
140
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 */
|
|
141
173
|
type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never ? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined : FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
|
|
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
|
+
*/
|
|
142
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 */
|
|
143
182
|
type SuccessResponse<T extends Record<string | number, any>, Media extends MediaType = MediaType> = GetResponseContent<T, Media, SuccessStatus<T>>;
|
|
144
183
|
type GetResponseContent<T extends Record<string | number, any>, Media extends MediaType = MediaType, ResponseCode extends keyof T = keyof T> = ResponseCode extends keyof T ? {
|
|
145
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;
|
|
146
185
|
}[ResponseCode] : never;
|
|
186
|
+
/**
|
|
187
|
+
* Return all 5XX and 4XX responses (in that order) from a Response Object Map
|
|
188
|
+
*/
|
|
147
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 */
|
|
148
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 */
|
|
149
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 */
|
|
150
195
|
type RequestBodyJSON<PathMethod> = JSONLike<FilterKeys<OperationRequestBody<PathMethod>, "content">>;
|
|
196
|
+
/** Find first match of multiple keys */
|
|
151
197
|
type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];
|
|
152
|
-
|
|
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
|
+
*/
|
|
153
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
|
+
*/
|
|
154
213
|
type JSONLike<T> = FilterKeys<T, `${string}/json`>;
|
|
214
|
+
/**
|
|
215
|
+
* Filter objects that have required keys
|
|
216
|
+
* @deprecated Use `RequiredKeysOf` instead
|
|
217
|
+
*/
|
|
155
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
|
+
*/
|
|
156
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
|
+
*/
|
|
157
228
|
type RequiredKeysOfHelper<T> = {
|
|
158
229
|
[K in keyof T]: {} extends Pick<T, K> ? never : K;
|
|
159
230
|
}[keyof T];
|
|
231
|
+
/** Get the required keys of an object, or `never` if no keys are required */
|
|
160
232
|
type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;
|
|
233
|
+
/** Marker type for readOnly properties (excluded from request bodies) */
|
|
161
234
|
type $Read<T> = {
|
|
162
235
|
readonly $read: T;
|
|
163
236
|
};
|
|
237
|
+
/** Marker type for writeOnly properties (excluded from response bodies) */
|
|
164
238
|
type $Write<T> = {
|
|
165
239
|
readonly $write: T;
|
|
166
240
|
};
|
|
241
|
+
/** Primitives, also branded ones (`string & { __brand: "Id" }`), which stay unmapped (#2765). */
|
|
167
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
|
+
*/
|
|
168
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
|
+
*/
|
|
169
253
|
type ReadWriteMarkedKeys<T, Marker> = {
|
|
170
254
|
[K in keyof T]-?: NonNullable<T[K]> extends never ? never : NonNullable<T[K]> extends Marker ? K : never;
|
|
171
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
|
+
*/
|
|
172
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>[] : {
|
|
173
264
|
[K in keyof T]: ReadWriteResolve<T[K], Resolved>;
|
|
174
265
|
};
|
|
175
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
|
+
*/
|
|
176
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 ? {
|
|
177
275
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Write<any>> ? never : K]: Readable<T[K]>;
|
|
178
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
|
+
*/
|
|
179
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 ? {
|
|
180
285
|
[K in keyof T as K extends ReadWriteMarkedKeys<T, $Read<any>> ? never : K]: Writable<T[K]>;
|
|
181
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
|
}
|