ts / src / types.ts
406 words
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
 * Type-level helpers over the generated OpenAPI types. The spec has no
 * operationIds and no shared component schemas, so every request and
 * response type is addressed by its path and method:
 *
 *   Res<'/domains/check', 'get'>            the 2xx JSON body
 *   Body<'/domains/registrations', 'post'>  the JSON request body
 *   Query<'/domains/search', 'get'>         the query parameters
 *   Params<'/tunnels/{id}', 'get'>          the path parameters
 */
import type { paths } from './generated/api.js';

export type ApiPaths = paths;

/** Lower-case method keys, as they appear in the spec. */
export type MethodKey = 'get' | 'post' | 'put' | 'patch' | 'delete';

/** Upper-case HTTP methods, as they go on the wire. */
export type Method = Uppercase<MethodKey>;

/** Every path that defines METHOD. */
export type PathsWith<M extends MethodKey> = {
  [P in keyof paths]: paths[P] extends { [K in M]: object } ? P : never;
}[keyof paths];

type Operation<P extends keyof paths, M extends MethodKey> =
  paths[P] extends { [K in M]: infer O } ? O : never;

type JsonOf<R> = R extends { content: { 'application/json': infer B } } ? B : Record<string, never>;

type Success<R> = {
  [S in keyof R]: S extends 200 | 201 | 202 | 204 ? JsonOf<R[S]> : never;
}[keyof R];

/** The successful (2xx) JSON response body of an operation. */
export type Res<P extends keyof paths, M extends MethodKey> =
  Operation<P, M> extends { responses: infer R } ? Success<R> : never;

/** The JSON request body of an operation, or `never` when it has none. */
export type Body<P extends keyof paths, M extends MethodKey> =
  Operation<P, M> extends { requestBody?: infer RB }
    ? RB extends { content: { 'application/json': infer B } }
      ? B
      : never
    : never;

/** The query parameters of an operation, or `never` when it has none. */
export type Query<P extends keyof paths, M extends MethodKey> =
  Operation<P, M> extends { parameters: { query?: infer Q } }
    ? Q extends object
      ? Q
      : never
    : never;

/** The path parameters of an operation, or `never` when it has none. */
export type Params<P extends keyof paths, M extends MethodKey> =
  Operation<P, M> extends { parameters: { path: infer PP } }
    ? PP extends object
      ? PP
      : never
    : never;

/** Element type of an array-valued field of a response. */
export type ElementOf<T> = T extends readonly (infer E)[] ? E : never;

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/ts.git