@defjs/core 0.3.3 → 0.4.0-beta.1
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/LICENSE +1 -1
- package/README.md +85 -2
- package/index.d.ts +1645 -189
- package/index.js +5638 -852
- package/index.min.js +44 -1
- package/package.json +14 -12
package/index.d.ts
CHANGED
|
@@ -1,194 +1,1650 @@
|
|
|
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
|
-
|
|
65
|
-
|
|
1
|
+
//#region src/internal/http_request.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* How the HTTP response body should be parsed before struct validation.
|
|
4
|
+
* Chosen from the declared struct kind: string is text, blob and file are blobs,
|
|
5
|
+
* arrayBuffer is bytes, and every other kind is JSON.
|
|
6
|
+
*/
|
|
7
|
+
type HttpResponseType = 'arraybuffer' | 'blob' | 'json' | 'text';
|
|
8
|
+
/**
|
|
9
|
+
* Progress snapshot for upload or download callbacks.
|
|
10
|
+
* Mirrors the familiar `ProgressEvent` shape (`loaded` / `total` / `lengthComputable`).
|
|
11
|
+
*/
|
|
12
|
+
interface HttpProgressEvent {
|
|
13
|
+
readonly lengthComputable: boolean;
|
|
14
|
+
readonly loaded: number;
|
|
15
|
+
readonly total: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Callback invoked as request bytes are uploaded or response bytes are downloaded.
|
|
19
|
+
*/
|
|
20
|
+
type HttpProgressFn = (event: HttpProgressEvent) => Promise<void> | void;
|
|
21
|
+
/**
|
|
22
|
+
* Normalized outgoing HTTP request used by handlers, interceptors, and `fetchHandler`.
|
|
23
|
+
*
|
|
24
|
+
* After the request builder runs, `body` is already the wire value — for JSON that means a
|
|
25
|
+
* **JSON text string**. Sign HMAC / digests against that string (or other final bytes), not the
|
|
26
|
+
* original struct input.
|
|
27
|
+
*/
|
|
28
|
+
interface HttpRequest {
|
|
29
|
+
abort?: AbortSignal;
|
|
30
|
+
baseEndpoint?: string;
|
|
31
|
+
body?: Blob | ArrayBuffer | FormData | URLSearchParams | ReadableStream<Uint8Array> | object | string | number | boolean | null;
|
|
32
|
+
bodyContentType?: string | null;
|
|
33
|
+
/** @internal Tracks which body value produced bodyContentType so interceptors cannot leave stale metadata behind. */
|
|
34
|
+
bodyContentTypeSource?: unknown;
|
|
35
|
+
downloadProgress?: HttpProgressFn;
|
|
36
|
+
endpoint: string;
|
|
37
|
+
headers?: Headers;
|
|
38
|
+
method: string;
|
|
39
|
+
/** Static, low-cardinality endpoint identity for telemetry and diagnostics. */
|
|
40
|
+
operation?: string;
|
|
41
|
+
queryParams?: URLSearchParams;
|
|
42
|
+
queryString?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Representation for a 2xx body, derived from the endpoint `output` struct kind.
|
|
45
|
+
* Set only when `output` is declared. Interceptors that short-circuit with `makeResponse`
|
|
46
|
+
* read this to match the transport. Must not be changed. `undefined` leaves the 2xx body unread.
|
|
47
|
+
*/
|
|
48
|
+
readonly responseType?: HttpResponseType;
|
|
49
|
+
/**
|
|
50
|
+
* Representation for a non-2xx body, derived from the endpoint `error` struct kind.
|
|
51
|
+
* Set only when `error` is declared. Must not be changed. `undefined` leaves the non-2xx body
|
|
52
|
+
* unread and does not fall back to `responseType`.
|
|
53
|
+
*/
|
|
54
|
+
readonly errorResponseType?: HttpResponseType;
|
|
55
|
+
timeout?: number;
|
|
56
|
+
uploadProgress?: HttpProgressFn;
|
|
57
|
+
withCredentials?: boolean;
|
|
58
|
+
xsrf?: {
|
|
59
|
+
cookieName: string;
|
|
60
|
+
headerName: string;
|
|
61
|
+
tokenProvider?: (context: {
|
|
62
|
+
request: HttpRequest;
|
|
63
|
+
}) => string | null | undefined;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/internal/http_response.d.ts
|
|
68
|
+
declare const HTTP_RESPONSE: unique symbol;
|
|
69
|
+
/**
|
|
70
|
+
* Wire-shape HTTP response returned by transports and accepted by interceptors.
|
|
71
|
+
* `ok` is true for status codes in the 2xx range. A transport failure is a fault, never a response.
|
|
72
|
+
*/
|
|
73
|
+
type HttpResponse<R> = {
|
|
74
|
+
readonly [HTTP_RESPONSE]: true;
|
|
75
|
+
readonly url: string;
|
|
76
|
+
readonly status: number;
|
|
77
|
+
readonly statusText: string;
|
|
78
|
+
readonly headers: Headers;
|
|
79
|
+
/** Absent when no body was present. JSON `null` stays `null`. */
|
|
80
|
+
readonly body: R | null | undefined;
|
|
81
|
+
readonly ok: boolean;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Response metadata, available whenever a response reached the client.
|
|
85
|
+
*
|
|
86
|
+
* Carries no body: a body only exists once a declared struct decoded it.
|
|
87
|
+
*/
|
|
88
|
+
type HttpMeta = {
|
|
89
|
+
readonly headers: Headers;
|
|
90
|
+
readonly ok: boolean;
|
|
91
|
+
readonly status: number;
|
|
92
|
+
readonly statusText: string;
|
|
93
|
+
readonly url: string;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Response whose body decoded successfully against a declared struct.
|
|
97
|
+
*
|
|
98
|
+
* Reaching this type is the proof that decoding happened; a failed decode is reported
|
|
99
|
+
* as a fault carrying `HttpMeta` alone.
|
|
100
|
+
*/
|
|
101
|
+
type DecodedResponse<TBody> = HttpMeta & {
|
|
102
|
+
readonly body: TBody;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Fields accepted by `makeResponse` when building a synthetic `HttpResponse` (for example in interceptors).
|
|
106
|
+
*/
|
|
107
|
+
type MakeResponseOptions<R> = {
|
|
108
|
+
status?: number;
|
|
109
|
+
statusText?: string;
|
|
110
|
+
url?: string;
|
|
111
|
+
headers?: Headers;
|
|
112
|
+
body?: R | null;
|
|
113
|
+
request?: HttpRequest;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Build an `HttpResponse` value without performing a network call.
|
|
117
|
+
* Useful in interceptors that short-circuit `next`, and in tests.
|
|
118
|
+
*
|
|
119
|
+
* @param options - Status, headers, body, and an optional request to copy headers/url from; defaults yield status `0`.
|
|
120
|
+
* @returns An `HttpResponse` with `ok` derived from the status code.
|
|
121
|
+
*/
|
|
122
|
+
export declare function makeResponse<R>(options?: MakeResponseOptions<R>): HttpResponse<R>;
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/error/cause.d.ts
|
|
125
|
+
/** Shared cause/message sentinel for aborted requests. */
|
|
66
126
|
export declare const ERR_ABORTED: Error;
|
|
127
|
+
/** Shared cause/message sentinel for timed-out requests. */
|
|
67
128
|
export declare const ERR_TIMEOUT: Error;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/struct/errors.d.ts
|
|
131
|
+
/**
|
|
132
|
+
* Optional callback that rewrites a `StructIssue` message before it is stored.
|
|
133
|
+
*
|
|
134
|
+
* Return a string to replace the default message, or `undefined` to keep it.
|
|
135
|
+
*
|
|
136
|
+
* @param issue - Issue about to be recorded.
|
|
137
|
+
* @returns Replacement message, or `undefined` to keep the default.
|
|
138
|
+
*/
|
|
139
|
+
type ErrorMap = (issue: StructIssue) => string | undefined;
|
|
140
|
+
/**
|
|
141
|
+
* Aggregate of one or more `StructIssue`s from a failed parse.
|
|
142
|
+
*
|
|
143
|
+
* Use `format()`, `flatten()`, or `prettify()` to present issues to callers.
|
|
144
|
+
*/
|
|
145
|
+
export declare class StructError extends Error {
|
|
146
|
+
/** Issues collected for this failure, in encounter order. */
|
|
147
|
+
readonly issues: StructIssue[];
|
|
148
|
+
/**
|
|
149
|
+
* @param issues - Non-empty list of parse issues (empty lists still produce a generic message).
|
|
150
|
+
*/
|
|
151
|
+
constructor(issues: StructIssue[]);
|
|
152
|
+
/**
|
|
153
|
+
* Build a nested error tree keyed by path segments.
|
|
154
|
+
*
|
|
155
|
+
* @returns A `FormattedStructError` with `_errors` arrays at each node.
|
|
156
|
+
*/
|
|
157
|
+
format(): FormattedStructError;
|
|
158
|
+
/**
|
|
159
|
+
* Split issues into root `formErrors` and first-segment `fieldErrors`.
|
|
160
|
+
*
|
|
161
|
+
* @returns Flat bags suitable for form libraries.
|
|
162
|
+
*/
|
|
163
|
+
flatten(): FlattenedStructError;
|
|
164
|
+
/**
|
|
165
|
+
* Render a multi-line, human-readable summary of all issues.
|
|
166
|
+
*
|
|
167
|
+
* @returns One `× path: message` line per issue.
|
|
168
|
+
*/
|
|
169
|
+
prettify(): string;
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/struct/symbols.d.ts
|
|
173
|
+
/**
|
|
174
|
+
* Enumerable tag on objects produced while parsing endpoint input.
|
|
175
|
+
* Response decoding and `struct.parse` leave it unset. Internal to the outbound encoder.
|
|
176
|
+
*
|
|
177
|
+
* @internal
|
|
178
|
+
*/
|
|
179
|
+
declare const STRUCT: unique symbol;
|
|
180
|
+
//#endregion
|
|
181
|
+
//#region src/struct/types.d.ts
|
|
182
|
+
type Path = Array<number | string>;
|
|
183
|
+
/**
|
|
184
|
+
* Error-first parse tuple from `struct.parse`.
|
|
185
|
+
*
|
|
186
|
+
* On success the error is `null` and `value` is the parsed output. On failure
|
|
187
|
+
* the error is a `StructError` and `value` is always `undefined`.
|
|
188
|
+
*/
|
|
189
|
+
type ParseResult<O> = [error: null, value: O] | [error: StructError, value: undefined];
|
|
190
|
+
type LiteralValue = boolean | null | number | string;
|
|
191
|
+
interface StructTypes<Input = unknown, Output = unknown, OptionalOut extends boolean = false> {
|
|
192
|
+
input: Input;
|
|
193
|
+
optionalOut: OptionalOut extends true ? true : undefined;
|
|
194
|
+
output: Output;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Minimal structural brand carried by every struct instance.
|
|
198
|
+
*
|
|
199
|
+
* `_struct` holds input/output phantom types used by `Infer` and `StructInput`.
|
|
200
|
+
*/
|
|
201
|
+
interface StructLike<I = unknown, O = unknown, OO extends boolean = boolean> {
|
|
202
|
+
readonly _struct: StructTypes<I, O, OO>;
|
|
203
|
+
}
|
|
204
|
+
type OptionalOutputStruct = {
|
|
205
|
+
readonly _struct: {
|
|
206
|
+
readonly optionalOut: true;
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* A single validation failure produced while parsing a struct.
|
|
211
|
+
*/
|
|
212
|
+
interface StructIssue {
|
|
213
|
+
/** Machine-readable failure category. */
|
|
214
|
+
code: 'custom' | 'invalid_enum' | 'invalid_intersection' | 'invalid_literal' | 'invalid_type' | 'invalid_union' | 'missing_key';
|
|
215
|
+
/** Human-readable description of the expected type or value. */
|
|
216
|
+
expected: string;
|
|
217
|
+
/** Final message after optional `ErrorMap` rewriting. */
|
|
218
|
+
message: string;
|
|
219
|
+
/** Path from the parse root to the failing location. */
|
|
220
|
+
path: Path;
|
|
221
|
+
/** Value that failed validation at `path`. */
|
|
222
|
+
received: unknown;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Nested error tree returned by `StructError.format()`.
|
|
226
|
+
*
|
|
227
|
+
* Leaf messages live under `_errors`; nested keys mirror the failing path.
|
|
228
|
+
*/
|
|
229
|
+
interface FormattedStructError {
|
|
230
|
+
_errors: string[];
|
|
231
|
+
[key: string]: FormattedStructError | string[];
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Flat field/form error bags returned by `StructError.flatten()`.
|
|
235
|
+
*/
|
|
236
|
+
interface FlattenedStructError {
|
|
237
|
+
/** Messages whose path is empty (root-level issues). */
|
|
238
|
+
formErrors: string[];
|
|
239
|
+
/** Messages keyed by the first path segment. */
|
|
240
|
+
fieldErrors: {
|
|
241
|
+
[key: string]: string[];
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Chainable modifiers available on every `Struct` instance.
|
|
246
|
+
*/
|
|
247
|
+
interface StructMethods<I, O, OO extends boolean> {
|
|
248
|
+
/**
|
|
249
|
+
* Override the external wire name for this field without changing the TypeScript property name.
|
|
250
|
+
*
|
|
251
|
+
* @param name - Wire / protocol field name.
|
|
252
|
+
* @returns The same struct branded with the alias.
|
|
253
|
+
*/
|
|
254
|
+
alias(name: string): this;
|
|
255
|
+
/**
|
|
256
|
+
* Allow `null` in addition to the current input and output types.
|
|
257
|
+
*
|
|
258
|
+
* @returns A struct that accepts and emits `null`.
|
|
259
|
+
*/
|
|
260
|
+
null(): Struct<I | null, O | null, OO>;
|
|
261
|
+
/**
|
|
262
|
+
* Alias for {@link StructMethods.null}.
|
|
263
|
+
*
|
|
264
|
+
* @returns A struct that accepts and emits `null`.
|
|
265
|
+
*/
|
|
266
|
+
nullable(): Struct<I | null, O | null, OO>;
|
|
267
|
+
/**
|
|
268
|
+
* Allow `null` or `undefined`, marking the field optional in object output.
|
|
269
|
+
*
|
|
270
|
+
* @returns A struct that accepts `null`/`undefined` and treats the field as optional.
|
|
271
|
+
*/
|
|
272
|
+
nullish(): Struct<I | null | undefined, O | null | undefined, true>;
|
|
273
|
+
/**
|
|
274
|
+
* Allow `undefined`, marking the field optional in object shapes.
|
|
275
|
+
*
|
|
276
|
+
* @returns A struct that accepts `undefined` and treats the field as optional.
|
|
277
|
+
*/
|
|
278
|
+
optional(): Struct<I | undefined, O | undefined, true>;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Public struct contract: modifiers plus the `_struct` type brand.
|
|
282
|
+
*
|
|
283
|
+
* Built via the `struct` facade (`struct.string()`, `struct.object()`, …).
|
|
284
|
+
*/
|
|
285
|
+
type Struct<Input = unknown, Output = Input, OptionalOut extends boolean = false> = StructMethods<Input, Output, OptionalOut> & StructLike<Input, Output, OptionalOut>;
|
|
286
|
+
type PresentValue = NonNullable<unknown>;
|
|
287
|
+
declare const carriedStruct: unique symbol;
|
|
288
|
+
/** Keeps the struct that a nullish modifier wrapped, so builders still see its fields. */
|
|
289
|
+
type CarriedStruct<T> = {
|
|
290
|
+
readonly [carriedStruct]: T;
|
|
291
|
+
};
|
|
292
|
+
declare const unionStructOptions: unique symbol;
|
|
293
|
+
declare const intersectionStructOptions: unique symbol;
|
|
294
|
+
declare const discriminatedUnionOptions: unique symbol;
|
|
295
|
+
interface PreservedStruct<T, I, O, OO extends boolean> extends Struct<I, O, OO>, CarriedStruct<T> {
|
|
296
|
+
null(): PreservedStruct<T, I | null, O | null, OO>;
|
|
297
|
+
nullable(): PreservedStruct<T, I | null, O | null, OO>;
|
|
298
|
+
nullish(): PreservedStruct<T, I | null | undefined, O | null | undefined, true>;
|
|
299
|
+
optional(): PreservedStruct<T, I | undefined, O | undefined, true>;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Broad struct constraint for endpoint and client generics.
|
|
303
|
+
*
|
|
304
|
+
* Prefer a concrete `Struct<…>` when you need precise input/output inference.
|
|
305
|
+
*/
|
|
306
|
+
type AnyStruct = Struct<any, any, boolean>;
|
|
307
|
+
/**
|
|
308
|
+
* Infer the accepted input type of a struct.
|
|
309
|
+
*
|
|
310
|
+
* @typeParam T - A struct-like value with a `_struct.input` brand.
|
|
311
|
+
*/
|
|
312
|
+
type StructInput<T> = T extends {
|
|
313
|
+
readonly _struct: {
|
|
314
|
+
readonly input: unknown;
|
|
315
|
+
};
|
|
316
|
+
} ? T['_struct']['input'] : never;
|
|
317
|
+
type StructOutput<T> = T extends {
|
|
318
|
+
readonly _struct: {
|
|
319
|
+
readonly output: unknown;
|
|
320
|
+
};
|
|
321
|
+
} ? T['_struct']['output'] : never;
|
|
322
|
+
/**
|
|
323
|
+
* Infer the parsed output type of a struct (alias of the internal output brand).
|
|
324
|
+
*
|
|
325
|
+
* @typeParam T - A struct-like value with a `_struct.output` brand.
|
|
326
|
+
*/
|
|
327
|
+
type Infer<T> = StructOutput<T>;
|
|
328
|
+
type FieldOutput<S> = S extends StructLike<unknown, unknown, boolean> ? S extends OptionalOutputStruct ? Exclude<S['_struct']['output'], undefined> : S['_struct']['output'] : never;
|
|
329
|
+
type Simplify<T> = { [K in keyof T]: T[K]; } & {};
|
|
330
|
+
type ObjectShape = {
|
|
331
|
+
[key: string]: any;
|
|
332
|
+
};
|
|
333
|
+
type ObjectInput<T extends ObjectShape> = Simplify<{ -readonly [K in keyof T as T[K] extends OptionalOutputStruct ? never : K]: T[K]['_struct']['input']; } & { -readonly [K in keyof T as T[K] extends OptionalOutputStruct ? K : never]?: Exclude<T[K]['_struct']['input'], undefined>; }>;
|
|
334
|
+
type ObjectOutput<T extends ObjectShape> = Simplify<{ -readonly [K in keyof T as T[K] extends OptionalOutputStruct ? never : K]: FieldOutput<T[K]>; } & { -readonly [K in keyof T as T[K] extends OptionalOutputStruct ? K : never]?: FieldOutput<T[K]>; }>;
|
|
335
|
+
type TupleInput<T extends readonly StructLike<unknown, unknown, boolean>[]> = { -readonly [K in keyof T]: StructInput<T[K]>; };
|
|
336
|
+
type TupleOutput<T extends readonly StructLike<unknown, unknown, boolean>[]> = { -readonly [K in keyof T]: StructOutput<T[K]>; };
|
|
337
|
+
type UnionOutput<T extends readonly StructLike<unknown, unknown, boolean>[]> = Exclude<StructOutput<T[number]>, undefined>;
|
|
338
|
+
type UnionInput<T extends readonly StructLike<unknown, unknown, boolean>[]> = Exclude<StructInput<T[number]>, undefined>;
|
|
339
|
+
type IntersectionInputValue<T extends readonly StructLike<unknown, unknown, boolean>[]> = T extends readonly [infer Head extends StructLike<unknown, unknown, boolean>, ...infer Tail extends StructLike<unknown, unknown, boolean>[]] ? StructInput<Head> & IntersectionInputValue<Tail> : unknown;
|
|
340
|
+
type IntersectionInput<T extends readonly StructLike<unknown, unknown, boolean>[]> = Exclude<IntersectionInputValue<T>, undefined>;
|
|
341
|
+
type IntersectionOutputValue<T extends readonly StructLike<unknown, unknown, boolean>[]> = T extends readonly [infer Head extends StructLike<unknown, unknown, boolean>, ...infer Tail extends StructLike<unknown, unknown, boolean>[]] ? StructOutput<Head> & IntersectionOutputValue<Tail> : unknown;
|
|
342
|
+
type IntersectionOutput<T extends readonly StructLike<unknown, unknown, boolean>[]> = Exclude<IntersectionOutputValue<T>, undefined>;
|
|
343
|
+
type StringStruct = Struct<string, string>;
|
|
344
|
+
type NumberStruct = Struct<number, number>;
|
|
345
|
+
type UnknownStruct = Struct<PresentValue, unknown>;
|
|
346
|
+
type ArrayInput<S extends StructLike<unknown, unknown, boolean>> = StructInput<S>[];
|
|
347
|
+
type ArrayOutput<S extends StructLike<unknown, unknown, boolean>> = StructOutput<S>[];
|
|
348
|
+
interface ArrayStructTypes<S extends StructLike<unknown, unknown, boolean>> extends StructTypes<ArrayInput<S>, ArrayOutput<S>, false> {
|
|
349
|
+
input: ArrayInput<S>;
|
|
350
|
+
optionalOut: undefined;
|
|
351
|
+
output: ArrayOutput<S>;
|
|
352
|
+
}
|
|
353
|
+
interface ArrayStruct<S extends StructLike<unknown, unknown, boolean>> extends StructMethods<ArrayInput<S>, ArrayOutput<S>, false>, StructLike<ArrayInput<S>, ArrayOutput<S>, false> {
|
|
354
|
+
readonly _struct: ArrayStructTypes<S>;
|
|
355
|
+
null(): PreservedStruct<ArrayStruct<S>, ArrayInput<S> | null, ArrayOutput<S> | null, false>;
|
|
356
|
+
nullable(): PreservedStruct<ArrayStruct<S>, ArrayInput<S> | null, ArrayOutput<S> | null, false>;
|
|
357
|
+
nullish(): PreservedStruct<ArrayStruct<S>, ArrayInput<S> | null | undefined, ArrayOutput<S> | null | undefined, true>;
|
|
358
|
+
optional(): PreservedStruct<ArrayStruct<S>, ArrayInput<S> | undefined, ArrayOutput<S> | undefined, true>;
|
|
359
|
+
}
|
|
360
|
+
interface ObjectStructTypes<T extends ObjectShape> extends StructTypes<ObjectInput<T>, ObjectOutput<T>, false> {
|
|
361
|
+
input: ObjectInput<T>;
|
|
362
|
+
optionalOut: undefined;
|
|
363
|
+
output: ObjectOutput<T>;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Object-shaped struct produced by `struct.object(shape)`.
|
|
367
|
+
*
|
|
368
|
+
* Field presence follows each field's optional/nullish modifiers; wire names
|
|
369
|
+
* can differ from TypeScript keys via `.alias()`.
|
|
370
|
+
*/
|
|
371
|
+
interface ObjectStruct<T extends ObjectShape> extends StructMethods<ObjectInput<T>, ObjectOutput<T>, false>, StructLike<ObjectInput<T>, ObjectOutput<T>, false> {
|
|
372
|
+
readonly _struct: ObjectStructTypes<T>;
|
|
373
|
+
null(): PreservedStruct<ObjectStruct<T>, ObjectInput<T> | null, ObjectOutput<T> | null, false>;
|
|
374
|
+
nullable(): PreservedStruct<ObjectStruct<T>, ObjectInput<T> | null, ObjectOutput<T> | null, false>;
|
|
375
|
+
nullish(): PreservedStruct<ObjectStruct<T>, ObjectInput<T> | null | undefined, ObjectOutput<T> | null | undefined, true>;
|
|
376
|
+
optional(): PreservedStruct<ObjectStruct<T>, ObjectInput<T> | undefined, ObjectOutput<T> | undefined, true>;
|
|
377
|
+
}
|
|
378
|
+
declare const recordValueStruct: unique symbol;
|
|
379
|
+
declare const tupleItemStructs: unique symbol;
|
|
380
|
+
type RecordInput<S extends StructLike<unknown, unknown, boolean>> = {
|
|
381
|
+
[key: string]: StructInput<S>;
|
|
382
|
+
};
|
|
383
|
+
type RecordOutput<S extends StructLike<unknown, unknown, boolean>> = {
|
|
384
|
+
[key: string]: FieldOutput<S>;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* Value struct carried by `struct.record`.
|
|
388
|
+
* Tagged parsing stores this struct on the record object itself. `null` and `undefined` are not tagged.
|
|
389
|
+
*/
|
|
390
|
+
interface RecordStruct<S extends StructLike<unknown, unknown, boolean>> extends Struct<RecordInput<S>, RecordOutput<S>> {
|
|
391
|
+
readonly [recordValueStruct]: S;
|
|
392
|
+
null(): PreservedStruct<RecordStruct<S>, RecordInput<S> | null, RecordOutput<S> | null, false>;
|
|
393
|
+
nullable(): PreservedStruct<RecordStruct<S>, RecordInput<S> | null, RecordOutput<S> | null, false>;
|
|
394
|
+
nullish(): PreservedStruct<RecordStruct<S>, RecordInput<S> | null | undefined, RecordOutput<S> | null | undefined, true>;
|
|
395
|
+
optional(): PreservedStruct<RecordStruct<S>, RecordInput<S> | undefined, RecordOutput<S> | undefined, true>;
|
|
396
|
+
}
|
|
397
|
+
/** Item structs carried by `struct.tuple`, so builders tag each position. The tuple itself is not tagged. */
|
|
398
|
+
interface TupleStruct<T extends readonly StructLike<unknown, unknown, boolean>[]> extends Struct<TupleInput<T>, TupleOutput<T>> {
|
|
399
|
+
readonly [tupleItemStructs]: T;
|
|
400
|
+
null(): PreservedStruct<TupleStruct<T>, TupleInput<T> | null, TupleOutput<T> | null, false>;
|
|
401
|
+
nullable(): PreservedStruct<TupleStruct<T>, TupleInput<T> | null, TupleOutput<T> | null, false>;
|
|
402
|
+
nullish(): PreservedStruct<TupleStruct<T>, TupleInput<T> | null | undefined, TupleOutput<T> | null | undefined, true>;
|
|
403
|
+
optional(): PreservedStruct<TupleStruct<T>, TupleInput<T> | undefined, TupleOutput<T> | undefined, true>;
|
|
404
|
+
}
|
|
405
|
+
interface UnionStruct<T extends readonly StructLike<unknown, unknown, boolean>[]> extends Struct<UnionInput<T>, UnionOutput<T>> {
|
|
406
|
+
readonly [unionStructOptions]: T;
|
|
407
|
+
null(): PreservedStruct<UnionStruct<T>, UnionInput<T> | null, UnionOutput<T> | null, false>;
|
|
408
|
+
nullable(): PreservedStruct<UnionStruct<T>, UnionInput<T> | null, UnionOutput<T> | null, false>;
|
|
409
|
+
nullish(): PreservedStruct<UnionStruct<T>, UnionInput<T> | null | undefined, UnionOutput<T> | null | undefined, true>;
|
|
410
|
+
optional(): PreservedStruct<UnionStruct<T>, UnionInput<T> | undefined, UnionOutput<T> | undefined, true>;
|
|
411
|
+
}
|
|
412
|
+
interface DiscriminatedUnionStruct<TOptions extends readonly ObjectStruct<ObjectShape>[]> extends Struct<StructInput<TOptions[number]>, StructOutput<TOptions[number]>> {
|
|
413
|
+
readonly [discriminatedUnionOptions]: TOptions;
|
|
414
|
+
null(): PreservedStruct<DiscriminatedUnionStruct<TOptions>, StructInput<TOptions[number]> | null, StructOutput<TOptions[number]> | null, false>;
|
|
415
|
+
nullable(): PreservedStruct<DiscriminatedUnionStruct<TOptions>, StructInput<TOptions[number]> | null, StructOutput<TOptions[number]> | null, false>;
|
|
416
|
+
nullish(): PreservedStruct<DiscriminatedUnionStruct<TOptions>, StructInput<TOptions[number]> | null | undefined, StructOutput<TOptions[number]> | null | undefined, true>;
|
|
417
|
+
optional(): PreservedStruct<DiscriminatedUnionStruct<TOptions>, StructInput<TOptions[number]> | undefined, StructOutput<TOptions[number]> | undefined, true>;
|
|
418
|
+
}
|
|
419
|
+
interface IntersectionStruct<T extends readonly StructLike<unknown, unknown, boolean>[]> extends Struct<IntersectionInput<T>, IntersectionOutput<T>> {
|
|
420
|
+
readonly [intersectionStructOptions]: T;
|
|
421
|
+
null(): PreservedStruct<IntersectionStruct<T>, IntersectionInput<T> | null, IntersectionOutput<T> | null, false>;
|
|
422
|
+
nullable(): PreservedStruct<IntersectionStruct<T>, IntersectionInput<T> | null, IntersectionOutput<T> | null, false>;
|
|
423
|
+
nullish(): PreservedStruct<IntersectionStruct<T>, IntersectionInput<T> | null | undefined, IntersectionOutput<T> | null | undefined, true>;
|
|
424
|
+
optional(): PreservedStruct<IntersectionStruct<T>, IntersectionInput<T> | undefined, IntersectionOutput<T> | undefined, true>;
|
|
425
|
+
}
|
|
426
|
+
//#endregion
|
|
427
|
+
//#region src/error/types.d.ts
|
|
428
|
+
/**
|
|
429
|
+
* Every failure Defjs reports, as one closed set of codes.
|
|
430
|
+
*
|
|
431
|
+
* The prefix before the first `_` is the class; there is no separate `kind` field.
|
|
432
|
+
* Read the prefix for coarse triage and the whole code for an exact case:
|
|
433
|
+
*
|
|
434
|
+
* | Class | Meaning |
|
|
435
|
+
* | ------ | -------------------------------------------------------------- |
|
|
436
|
+
* | `HTTP` | The peer answered with a non-2xx status. |
|
|
437
|
+
* | `REQ` | The request never left: input, execute options, or build. |
|
|
438
|
+
* | `NET` | No usable response: cancel, timeout, connect, truncated body. |
|
|
439
|
+
* | `RES` | A response arrived but could not be read as declared. |
|
|
440
|
+
* | `EXT` | Code you attached to the pipeline threw. |
|
|
441
|
+
* | `CAP` | A declared buffer or queue limit was exceeded. |
|
|
442
|
+
* | `ENV` | The host runtime lacks a required capability. |
|
|
443
|
+
*
|
|
444
|
+
* The set is closed on purpose: it keeps `switch (fault.code)` exhaustive. Extensions
|
|
445
|
+
* report their own detail through `cause`, not through a new code.
|
|
446
|
+
*/
|
|
447
|
+
export type FaultCode = 'CAP_BUFFER_EXCEEDED' | 'CAP_QUEUE_OVERFLOW' | 'ENV_UNSUPPORTED' | 'EXT_HOOK_FAILED' | 'EXT_INTERCEPTOR_FAILED' | 'EXT_OBSERVER_FAILED' | 'HTTP_STATUS' | 'NET_ABORTED' | 'NET_BODY_INCOMPLETE' | 'NET_TIMEOUT' | 'NET_UNREACHABLE' | 'REQ_BUILD_FAILED' | 'REQ_INPUT_INVALID' | 'REQ_OPTIONS_INVALID' | 'RES_DECODE_FAILED' | 'RES_MEDIA_TYPE_INVALID' | 'RES_STRUCT_MISMATCH';
|
|
448
|
+
/**
|
|
449
|
+
* The class of a fault code: the segment before its first `_`.
|
|
450
|
+
*
|
|
451
|
+
* @typeParam C - A `FaultCode`, or a union of them.
|
|
452
|
+
*/
|
|
453
|
+
export type FaultClass<C extends string> = C extends `${infer TClass}_${string}` ? TClass : never;
|
|
454
|
+
/** Codes whose fault carries response metadata but no body. */
|
|
455
|
+
export type DecodeFaultCode = 'RES_DECODE_FAILED' | 'RES_MEDIA_TYPE_INVALID' | 'RES_STRUCT_MISMATCH';
|
|
456
|
+
/** Codes whose fault may never have reached a response. */
|
|
457
|
+
export type PreflightFaultCode = Exclude<FaultCode, DecodeFaultCode | 'HTTP_STATUS'>;
|
|
458
|
+
type ErrorBody<TErr> = [TErr] extends [undefined] ? undefined : Infer<TErr>;
|
|
459
|
+
/**
|
|
460
|
+
* `HttpStatusFault` expressed by its decoded body type instead of the struct that produced it.
|
|
461
|
+
*
|
|
462
|
+
* Factories work in decoded values, so they use this form; endpoint types use
|
|
463
|
+
* `HttpStatusFault` and let `Infer` bridge the two.
|
|
464
|
+
*/
|
|
465
|
+
export type HttpStatusFaultOf<TData> = Error & {
|
|
466
|
+
code: 'HTTP_STATUS';
|
|
467
|
+
data: TData;
|
|
468
|
+
response: [TData] extends [undefined] ? HttpMeta : DecodedResponse<TData>;
|
|
469
|
+
status: number;
|
|
470
|
+
};
|
|
471
|
+
/**
|
|
472
|
+
* The peer answered with a non-2xx status and the declared `error` struct decoded its body.
|
|
473
|
+
*
|
|
474
|
+
* Omitting `error` skips decoding, which leaves `data` as `undefined` and `response`
|
|
475
|
+
* without a `body` field.
|
|
476
|
+
*/
|
|
477
|
+
export type HttpStatusFault<TErr extends AnyStruct | undefined = undefined> = HttpStatusFaultOf<ErrorBody<TErr>>;
|
|
478
|
+
/**
|
|
479
|
+
* A response arrived but could not be read as declared.
|
|
480
|
+
*
|
|
481
|
+
* `response` is metadata only: a body is a decoded value, and decoding is what failed.
|
|
482
|
+
* The offending detail lives on `cause` (a `StructError` for a struct mismatch, the
|
|
483
|
+
* parser failure for an unreadable representation).
|
|
484
|
+
*/
|
|
485
|
+
export type DecodeFault = Error & {
|
|
486
|
+
cause: unknown;
|
|
487
|
+
code: DecodeFaultCode;
|
|
488
|
+
response: HttpMeta;
|
|
489
|
+
status: number;
|
|
490
|
+
};
|
|
491
|
+
/**
|
|
492
|
+
* A failure that may have happened before any response existed.
|
|
493
|
+
*
|
|
494
|
+
* `response` is present only where the transport already had metadata to report,
|
|
495
|
+
* such as a body that truncated mid-download.
|
|
496
|
+
*/
|
|
497
|
+
export type PreflightFault = Error & {
|
|
498
|
+
cause?: unknown;
|
|
499
|
+
code: PreflightFaultCode;
|
|
500
|
+
response?: HttpMeta;
|
|
501
|
+
};
|
|
502
|
+
/**
|
|
503
|
+
* Any failure returned by `client.execute`, expressed by its decoded error-body type.
|
|
504
|
+
*
|
|
505
|
+
* @typeParam TData - The decoded `error` body, or `undefined` when no error struct was declared.
|
|
506
|
+
*/
|
|
507
|
+
export type FaultOf<TData = undefined> = DecodeFault | HttpStatusFaultOf<TData> | PreflightFault;
|
|
508
|
+
/**
|
|
509
|
+
* Any failure returned by `client.execute`, discriminated by `code`.
|
|
510
|
+
*
|
|
511
|
+
* @typeParam TErr - The endpoint's declared `error` struct, or `undefined` when it declares none.
|
|
512
|
+
*/
|
|
513
|
+
export type Fault<TErr extends AnyStruct | undefined = undefined> = FaultOf<ErrorBody<TErr>>;
|
|
514
|
+
/**
|
|
515
|
+
* Any fault at all, whatever its decoded error-body type.
|
|
516
|
+
*
|
|
517
|
+
* Use it for handlers that classify faults without caring which endpoint produced them.
|
|
518
|
+
* Prefer `Fault<typeof yourErrorStruct>` where the body type matters.
|
|
519
|
+
*/
|
|
520
|
+
export type AnyFault = DecodeFault | HttpStatusFaultOf<undefined> | HttpStatusFaultOf<unknown> | PreflightFault;
|
|
521
|
+
//#endregion
|
|
522
|
+
//#region src/error/factory.d.ts
|
|
523
|
+
/**
|
|
524
|
+
* Build the fault for a non-2xx response whose body decoded against the declared `error` struct.
|
|
525
|
+
*
|
|
526
|
+
* @param response - The response, carrying the decoded body.
|
|
527
|
+
* @returns An `HTTP_STATUS` fault whose `data` is that body.
|
|
528
|
+
*/
|
|
529
|
+
export declare function createHttpStatusFault<TData>(response: DecodedResponse<TData>): HttpStatusFaultOf<TData>;
|
|
530
|
+
/**
|
|
531
|
+
* Build the fault for a non-2xx response that was never decoded, because the endpoint
|
|
532
|
+
* declared no `error` struct.
|
|
533
|
+
*
|
|
534
|
+
* @param response - Metadata of the response; no body was read.
|
|
535
|
+
* @returns An `HTTP_STATUS` fault whose `data` is `undefined`.
|
|
536
|
+
*/
|
|
537
|
+
export declare function createUndecodedHttpStatusFault(response: HttpMeta): HttpStatusFaultOf<undefined>;
|
|
538
|
+
/**
|
|
539
|
+
* Build the fault for a response that arrived but could not be read as declared.
|
|
540
|
+
*
|
|
541
|
+
* Carries metadata only: a body is a decoded value, and decoding is what failed.
|
|
542
|
+
*
|
|
543
|
+
* @param code - Which read step failed.
|
|
544
|
+
* @param cause - Underlying parser or struct failure.
|
|
545
|
+
* @param response - Metadata of the response that could not be read.
|
|
546
|
+
* @returns A decode fault with no body.
|
|
547
|
+
*/
|
|
548
|
+
export declare function createDecodeFault(code: DecodeFaultCode, cause: unknown, response: HttpMeta): DecodeFault;
|
|
549
|
+
/**
|
|
550
|
+
* Build a fault for a failure that may have happened before any response existed.
|
|
551
|
+
*
|
|
552
|
+
* @param code - The specific failure.
|
|
553
|
+
* @param cause - Underlying value, when there is one; the code becomes the message otherwise.
|
|
554
|
+
* @param response - Metadata, only where the transport already had some to report.
|
|
555
|
+
* @returns A preflight fault.
|
|
556
|
+
*/
|
|
557
|
+
export declare function createPreflightFault(code: PreflightFaultCode, cause?: unknown, response?: HttpMeta): PreflightFault;
|
|
558
|
+
/**
|
|
559
|
+
* Build a `NET_*` fault, choosing the code from the shape of `cause`.
|
|
560
|
+
*
|
|
561
|
+
* Recognizes the shared abort/timeout sentinels and the platform's `AbortError`/`TimeoutError`;
|
|
562
|
+
* anything else is reported as unreachable.
|
|
563
|
+
*
|
|
564
|
+
* @param cause - Underlying cancellation, timeout, or transport failure.
|
|
565
|
+
* @param response - Metadata, only where the transport already had some to report.
|
|
566
|
+
* @returns A `NET_ABORTED`, `NET_TIMEOUT`, or `NET_UNREACHABLE` fault.
|
|
567
|
+
*/
|
|
568
|
+
export declare function createNetworkFault(cause: unknown, response?: HttpMeta): PreflightFault;
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region src/struct/constructors.d.ts
|
|
571
|
+
declare function createStringStruct(): StringStruct;
|
|
572
|
+
declare function createNumberStruct(): NumberStruct;
|
|
573
|
+
declare function createBooleanStruct(): Struct<boolean, boolean>;
|
|
574
|
+
declare function createNullStruct(): Struct<null, null>;
|
|
575
|
+
declare function createAnyStruct(): Struct<PresentValue, any>;
|
|
576
|
+
declare function createUnknownStruct(): UnknownStruct;
|
|
577
|
+
declare function createLiteralStruct<const T extends LiteralValue>(value: T): Struct<T, T>;
|
|
578
|
+
declare function createArrayStruct<S extends StructLike<unknown, unknown, boolean>>(item: S): ArrayStruct<S>;
|
|
579
|
+
declare function createObjectStruct<T extends ObjectShape>(shape: T): ObjectStruct<T>;
|
|
580
|
+
declare function createUrlencodedBodyStruct<T extends ObjectShape>(shape: T): ObjectStruct<T>;
|
|
581
|
+
declare function createFormDataBodyStruct<T extends ObjectShape>(shape: T): ObjectStruct<T>;
|
|
582
|
+
declare function createRecordStruct<S extends StructLike<unknown, unknown, boolean>>(value: S): RecordStruct<S>;
|
|
583
|
+
declare function createTupleStruct<const T extends readonly [StructLike<unknown, unknown, boolean>, ...StructLike<unknown, unknown, boolean>[]]>(items: T): TupleStruct<T>;
|
|
584
|
+
type RequiredDiscriminatorOption<TDiscriminator extends string, TOption extends ObjectStruct<ObjectShape>> = TOption extends ObjectStruct<infer TShape> ? TDiscriminator extends keyof TShape ? TShape[TDiscriminator] extends StructLike<infer TInput, unknown, false> ? undefined extends TInput ? never : null extends TInput ? [TInput] extends [null] ? TOption : never : TOption : never : never : never;
|
|
585
|
+
type RequiredDiscriminatorOptions<TDiscriminator extends string, TOptions extends readonly ObjectStruct<ObjectShape>[]> = { [K in keyof TOptions]: TOptions[K] extends ObjectStruct<ObjectShape> ? RequiredDiscriminatorOption<TDiscriminator, TOptions[K]> : never; };
|
|
586
|
+
declare function createDiscriminatedUnionStruct<const TDiscriminator extends string, const TOptions extends readonly [ObjectStruct<ObjectShape>, ...ObjectStruct<ObjectShape>[]]>(discriminator: TDiscriminator, options: TOptions & RequiredDiscriminatorOptions<TDiscriminator, TOptions>): DiscriminatedUnionStruct<TOptions>;
|
|
587
|
+
declare function createBlobStruct(): Struct<Blob, Blob>;
|
|
588
|
+
declare function createBigIntStruct(): Struct<bigint | string, bigint>;
|
|
589
|
+
declare function createDateStruct(): Struct<Date | number | string, Date>;
|
|
590
|
+
declare function createIntersectionStruct<const T extends readonly [StructLike<unknown, unknown, boolean>, ...StructLike<unknown, unknown, boolean>[]]>(...structs: T): IntersectionStruct<T>;
|
|
591
|
+
declare function createFileStruct(): Struct<File, File>;
|
|
592
|
+
declare function createArrayBufferStruct(): Struct<ArrayBuffer, ArrayBuffer>;
|
|
593
|
+
//#endregion
|
|
594
|
+
//#region src/struct/introspection.d.ts
|
|
595
|
+
declare function parseStructTuple<S extends StructLike<unknown, unknown, boolean>>(struct: S, value: unknown, options?: {
|
|
596
|
+
aliases?: boolean;
|
|
597
|
+
errorMap?: ErrorMap;
|
|
598
|
+
}): ParseResult<S['_struct']['output']>;
|
|
599
|
+
//#endregion
|
|
600
|
+
//#region src/struct/facade.d.ts
|
|
601
|
+
type EnumValue<T> = T extends readonly (infer U extends string)[] ? U : T extends {
|
|
602
|
+
[key: string]: infer U extends number | string;
|
|
603
|
+
} ? U : never;
|
|
604
|
+
declare function structEnum<const T extends readonly [string, ...string[]]>(value: T): Struct<EnumValue<T>, EnumValue<T>>;
|
|
605
|
+
declare function structEnum<const T extends {
|
|
606
|
+
[key: string]: number | string;
|
|
607
|
+
}>(value: T): Struct<EnumValue<T>, EnumValue<T>>;
|
|
608
|
+
declare function structOr<const T extends readonly [StructLike, ...StructLike[]]>(...options: T): UnionStruct<T>;
|
|
609
|
+
/**
|
|
610
|
+
* Facade for building protocol-boundary structs and parsing values.
|
|
611
|
+
*
|
|
612
|
+
* Prefer this entry point over internal constructors. Compose shapes with
|
|
613
|
+
* `struct.object`, then parse with `struct.parse` or let HTTP/SSE/WebSocket
|
|
614
|
+
* endpoints apply the same contracts at the wire boundary.
|
|
615
|
+
*
|
|
616
|
+
* @example
|
|
617
|
+
* ```ts
|
|
618
|
+
* const User = struct.object({
|
|
619
|
+
* id: struct.number(),
|
|
620
|
+
* displayName: struct.string().alias('display_name'),
|
|
621
|
+
* })
|
|
622
|
+
*
|
|
623
|
+
* const getUser = defineRequest({
|
|
624
|
+
* method: 'GET',
|
|
625
|
+
* path: '/users/:id',
|
|
626
|
+
* input: struct.object({ id: struct.number() }),
|
|
627
|
+
* builder: (input) => ({ path: input }),
|
|
628
|
+
* output: User,
|
|
629
|
+
* })
|
|
630
|
+
*
|
|
631
|
+
* const [error, user] = struct.parse(User, { id: 1, displayName: 'Ada' })
|
|
632
|
+
* ```
|
|
633
|
+
*/
|
|
634
|
+
export declare const struct: {
|
|
635
|
+
readonly any: typeof createAnyStruct;
|
|
636
|
+
readonly array: typeof createArrayStruct;
|
|
637
|
+
readonly arrayBuffer: typeof createArrayBufferStruct;
|
|
638
|
+
readonly bigint: typeof createBigIntStruct;
|
|
639
|
+
readonly blob: typeof createBlobStruct;
|
|
640
|
+
readonly boolean: typeof createBooleanStruct;
|
|
641
|
+
readonly date: typeof createDateStruct;
|
|
642
|
+
readonly discriminatedUnion: typeof createDiscriminatedUnionStruct;
|
|
643
|
+
readonly enum: typeof structEnum;
|
|
644
|
+
readonly file: typeof createFileStruct;
|
|
645
|
+
readonly formData: typeof createFormDataBodyStruct;
|
|
646
|
+
readonly intersection: typeof createIntersectionStruct;
|
|
647
|
+
readonly literal: typeof createLiteralStruct;
|
|
648
|
+
readonly null: typeof createNullStruct;
|
|
649
|
+
readonly number: typeof createNumberStruct;
|
|
650
|
+
readonly object: typeof createObjectStruct;
|
|
651
|
+
readonly or: typeof structOr;
|
|
652
|
+
readonly parse: typeof parseStructTuple;
|
|
653
|
+
readonly record: typeof createRecordStruct;
|
|
654
|
+
readonly string: typeof createStringStruct;
|
|
655
|
+
readonly tuple: typeof createTupleStruct;
|
|
656
|
+
readonly unknown: typeof createUnknownStruct;
|
|
657
|
+
readonly urlencoded: typeof createUrlencodedBodyStruct;
|
|
658
|
+
};
|
|
659
|
+
//#endregion
|
|
660
|
+
//#region src/sse/transport/parser.d.ts
|
|
661
|
+
/**
|
|
662
|
+
* Portions of this file are adapted from Azure/fetch-event-source.
|
|
663
|
+
* See packages/core/THIRD_PARTY_NOTICES.md for the license text.
|
|
664
|
+
*/
|
|
665
|
+
interface EventStreamMessage {
|
|
666
|
+
id: string;
|
|
667
|
+
event: string;
|
|
668
|
+
data: string;
|
|
669
|
+
}
|
|
670
|
+
//#endregion
|
|
671
|
+
//#region src/sse/transport/event_stream.d.ts
|
|
672
|
+
/** Metadata available after an SSE response opens successfully. */
|
|
673
|
+
interface EventStreamOpenInfo {
|
|
674
|
+
response: HttpResponse<unknown>;
|
|
675
|
+
url: string;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Fault codes an event stream can end with, drawn from the one shared `FaultCode` namespace.
|
|
679
|
+
*
|
|
680
|
+
* SSE used to carry a parallel set with no mapping to the request error model.
|
|
681
|
+
*/
|
|
682
|
+
type EventStreamFaultCode = Extract<FaultCode, 'CAP_BUFFER_EXCEEDED' | 'CAP_QUEUE_OVERFLOW' | 'EXT_HOOK_FAILED' | 'EXT_OBSERVER_FAILED' | 'NET_TIMEOUT' | 'NET_UNREACHABLE' | 'RES_DECODE_FAILED' | 'RES_MEDIA_TYPE_INVALID'>;
|
|
683
|
+
interface EventStreamCloseInfoBase {
|
|
684
|
+
reason?: string;
|
|
685
|
+
cause?: unknown;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* How an SSE stream ended: clean EOF, abort, or an error carrying its fault `code`.
|
|
689
|
+
*
|
|
690
|
+
* The discriminant is `kind` so that `code` can mean the same thing it means on a fault.
|
|
691
|
+
*/
|
|
692
|
+
type EventStreamCloseInfo = (EventStreamCloseInfoBase & {
|
|
693
|
+
kind: 'eof';
|
|
694
|
+
}) | (EventStreamCloseInfoBase & {
|
|
695
|
+
kind: 'aborted';
|
|
696
|
+
}) | (EventStreamCloseInfoBase & {
|
|
697
|
+
code: EventStreamFaultCode;
|
|
698
|
+
kind: 'error';
|
|
699
|
+
});
|
|
700
|
+
/** Open SSE stream: iterate events, inspect open metadata, and close early. */
|
|
701
|
+
interface EventStreamHandle<TEvent = EventStreamMessage> extends AsyncIterable<TEvent>, AsyncDisposable {
|
|
702
|
+
readonly open: EventStreamOpenInfo;
|
|
703
|
+
readonly closed: Promise<EventStreamCloseInfo>;
|
|
704
|
+
close(reason?: unknown): void;
|
|
705
|
+
[Symbol.asyncDispose](): PromiseLike<void>;
|
|
706
|
+
}
|
|
707
|
+
//#endregion
|
|
708
|
+
//#region src/internal/abort.d.ts
|
|
709
|
+
type UseCancellationConfig = {
|
|
710
|
+
abort?: AbortSignal;
|
|
711
|
+
timeout?: never;
|
|
712
|
+
} | {
|
|
713
|
+
abort?: never;
|
|
714
|
+
timeout?: number;
|
|
715
|
+
};
|
|
716
|
+
//#endregion
|
|
717
|
+
//#region src/internal/endpoint_input.d.ts
|
|
718
|
+
type EndpointInput<TInput extends AnyStruct | undefined> = TInput extends AnyStruct ? StructInput<TInput> : unknown;
|
|
719
|
+
//#endregion
|
|
720
|
+
//#region src/internal/endpoint_command.d.ts
|
|
721
|
+
type IsEndpointInputOptional<TInput extends AnyStruct | undefined> = [TInput] extends [undefined] ? true : undefined extends EndpointInput<TInput> ? true : false;
|
|
722
|
+
type EndpointCallable<TInput extends AnyStruct | undefined, TCommand> = [TInput] extends [undefined] ? () => TCommand : IsEndpointInputOptional<TInput> extends true ? (input?: EndpointInput<TInput>) => TCommand : (input: EndpointInput<TInput>) => TCommand;
|
|
723
|
+
//#endregion
|
|
724
|
+
//#region src/internal/builder_types.d.ts
|
|
725
|
+
/** Object produced by endpoint input parsing. The symbol points at the struct that produced the node. */
|
|
726
|
+
type Typed = {
|
|
727
|
+
readonly [STRUCT]: AnyStruct;
|
|
728
|
+
};
|
|
729
|
+
type Scalar = string | number | bigint | boolean | Date;
|
|
730
|
+
type FlatValue = Scalar | readonly Scalar[] | undefined;
|
|
731
|
+
type FlatRecord = {
|
|
732
|
+
readonly [key: string]: FlatValue;
|
|
733
|
+
};
|
|
734
|
+
type QueryValue = Scalar | readonly QueryValue[] | {
|
|
735
|
+
readonly [key: string]: QueryValue;
|
|
736
|
+
} | undefined;
|
|
737
|
+
type QueryRecord = {
|
|
738
|
+
readonly [key: string]: QueryValue;
|
|
739
|
+
};
|
|
740
|
+
type PathParams<P extends string> = P extends `${string}:${infer Name}/${infer Rest}` ? Name | PathParams<`/${Rest}`> : P extends `${string}:${infer Name}` ? Name : never;
|
|
741
|
+
type PathValue<P extends string> = [PathParams<P>] extends [never] ? never : ({ readonly [K in PathParams<P>]: Scalar; } & {
|
|
742
|
+
readonly [STRUCT]?: never;
|
|
743
|
+
}) | (Typed & {
|
|
744
|
+
readonly [key: string]: Scalar;
|
|
745
|
+
});
|
|
746
|
+
type HttpRequestShape<P extends string, M extends string> = {
|
|
747
|
+
body?: Uppercase<M> extends 'GET' | 'HEAD' ? never : unknown;
|
|
748
|
+
headers?: HeadersInit | FlatRecord;
|
|
749
|
+
path?: PathValue<P>;
|
|
750
|
+
query?: URLSearchParams | QueryRecord;
|
|
751
|
+
};
|
|
752
|
+
type WebSocketRequestShape<P extends string> = {
|
|
753
|
+
body?: never;
|
|
754
|
+
headers?: never;
|
|
755
|
+
path?: PathValue<P>;
|
|
756
|
+
query?: URLSearchParams | QueryRecord;
|
|
757
|
+
};
|
|
758
|
+
type EventStreamRequestShape<P extends string, M extends string> = HttpRequestShape<P, M>;
|
|
759
|
+
type NullishBuilderInput<S, Inner> = null extends Infer<S> ? undefined extends Infer<S> ? BuilderInput<Inner> | null | undefined : BuilderInput<Inner> | null : undefined extends Infer<S> ? BuilderInput<Inner> | undefined : BuilderInput<Inner>;
|
|
760
|
+
type IntersectBuilderInputs<T extends readonly StructLike<unknown, unknown, boolean>[]> = T extends readonly [infer Head extends StructLike<unknown, unknown, boolean>, ...infer Tail extends readonly StructLike<unknown, unknown, boolean>[]] ? BuilderInput<Head> & (Tail['length'] extends 0 ? unknown : IntersectBuilderInputs<Tail>) : unknown;
|
|
761
|
+
/**
|
|
762
|
+
* Parsed endpoint input seen by a builder.
|
|
763
|
+
*
|
|
764
|
+
* Object nodes are intersected with {@link Typed}. Record entries and tuple items are too.
|
|
765
|
+
* At runtime a record container is also tagged when the parsed value is an object, whether or not it
|
|
766
|
+
* was merged. Array and tuple containers are not. `null` and `undefined` are never tagged.
|
|
767
|
+
* Modifiers recover the struct they wrapped. Union options are distributed; intersection options are combined.
|
|
768
|
+
*/
|
|
769
|
+
type BuilderInput<S> = S extends CarriedStruct<infer Inner> ? NullishBuilderInput<S, Inner> : S extends UnionStruct<infer Options> ? BuilderInput<Options[number]> : S extends DiscriminatedUnionStruct<infer Options> ? BuilderInput<Options[number]> : S extends IntersectionStruct<infer Options> ? IntersectBuilderInputs<Options> : S extends RecordStruct<infer Value> ? {
|
|
770
|
+
[key: string]: BuilderInput<Value>;
|
|
771
|
+
} : S extends TupleStruct<infer Items> ? { [K in keyof Items]: Items[K] extends StructLike<unknown, unknown, boolean> ? BuilderInput<Items[K]> : Items[K]; } : S extends ArrayStruct<infer Item> ? BuilderInput<Item>[] : S extends ObjectStruct<infer Shape> ? { [K in keyof Shape]: BuilderInput<Shape[K]>; } & Typed : Infer<S>;
|
|
772
|
+
type BuilderField<TInput, TShape> = [TInput] extends [undefined] ? {
|
|
773
|
+
builder?: () => TShape;
|
|
774
|
+
} : BuilderInput<TInput> extends TShape ? {
|
|
775
|
+
builder?: (input: BuilderInput<TInput>) => TShape;
|
|
776
|
+
} : {
|
|
777
|
+
builder: (input: BuilderInput<TInput>) => TShape;
|
|
778
|
+
};
|
|
779
|
+
//#endregion
|
|
780
|
+
//#region src/internal/outbound_request.d.ts
|
|
781
|
+
/** Accepts any concrete builder. `never` keeps the parameter contravariant. */
|
|
782
|
+
type OutboundBuilder = (input: never) => unknown;
|
|
783
|
+
//#endregion
|
|
784
|
+
//#region src/http/http.d.ts
|
|
785
|
+
/**
|
|
786
|
+
* Per-request options for HTTP execution: progress callbacks and cancellation.
|
|
787
|
+
* Cancellation is either `abort` or `timeout` (not both).
|
|
788
|
+
*/
|
|
789
|
+
export type UseRequestConfig = {
|
|
790
|
+
onDownloadProgress?: HttpProgressFn;
|
|
791
|
+
onUploadProgress?: HttpProgressFn;
|
|
792
|
+
} & UseCancellationConfig;
|
|
793
|
+
/**
|
|
794
|
+
* Executable HTTP command produced by a `defineRequest` endpoint.
|
|
795
|
+
* Carries the request definition and optional typed input for `client.execute`.
|
|
796
|
+
*/
|
|
797
|
+
export interface HttpCommand<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined = undefined> extends BaseCommand<typeof HTTP_COMMAND> {
|
|
798
|
+
readonly definition: RequestDefinition<TInput, TOutput, TError>;
|
|
799
|
+
readonly input: EndpointInput<TInput> | undefined;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Options passed to `client.execute` / `executeHttpCommand` for a single HTTP call.
|
|
803
|
+
* `signal` combines with `abort` or `timeout`; it is not an alias for `abort`.
|
|
804
|
+
* `abort` and `timeout` are mutually exclusive (`abort` XOR `timeout`).
|
|
805
|
+
*/
|
|
806
|
+
export type HttpExecuteOptions = UseRequestConfig & {
|
|
807
|
+
signal?: AbortSignal;
|
|
808
|
+
};
|
|
809
|
+
/**
|
|
810
|
+
* Endpoint returned by `defineRequest`; call with input to create an `HttpCommand`.
|
|
811
|
+
*/
|
|
812
|
+
export type RequestEndpoint<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined = undefined> = EndpointCallable<TInput, HttpCommand<TInput, TOutput, TError>>;
|
|
813
|
+
type DeclaredBody<TStruct> = [TStruct] extends [undefined] ? undefined : Infer<TStruct>;
|
|
814
|
+
type DeclaredResponse<TStruct> = [TStruct] extends [undefined] ? HttpMeta : DecodedResponse<Infer<TStruct>>;
|
|
815
|
+
/** Inferred success body for the declared `output` struct, or `undefined` when none is declared. */
|
|
816
|
+
export type RequestSuccessData<TOutput extends AnyStruct | undefined> = DeclaredBody<TOutput>;
|
|
817
|
+
/** Inferred error body for the declared `error` struct, or `undefined` when none is declared. */
|
|
818
|
+
export type RequestErrorData<TError extends AnyStruct | undefined> = DeclaredBody<TError>;
|
|
819
|
+
type ResponseDeclaration<TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined> = ([TOutput] extends [undefined] ? {
|
|
820
|
+
output?: never;
|
|
821
|
+
} : {
|
|
822
|
+
output: TOutput;
|
|
823
|
+
}) & ([TError] extends [undefined] ? {
|
|
824
|
+
error?: never;
|
|
825
|
+
} : {
|
|
826
|
+
error: TError;
|
|
827
|
+
});
|
|
828
|
+
/**
|
|
829
|
+
* Contract for an HTTP endpoint: method, path, optional input struct, and the structs that
|
|
830
|
+
* decode its bodies.
|
|
831
|
+
*
|
|
832
|
+
* `output` declares the body for a 2xx response, `error` the body for anything else. Only one
|
|
833
|
+
* of the two ever runs, and omitting one means that body is never read. Pass to `defineRequest`
|
|
834
|
+
* to get a typed endpoint.
|
|
835
|
+
*/
|
|
836
|
+
export type RequestDefinition<TInput extends AnyStruct | undefined = undefined, TOutput extends AnyStruct | undefined = undefined, TError extends AnyStruct | undefined = undefined> = ResponseDeclaration<TOutput, TError> & {
|
|
837
|
+
builder?: OutboundBuilder;
|
|
838
|
+
input?: TInput;
|
|
839
|
+
method: string;
|
|
840
|
+
operation?: string;
|
|
841
|
+
path: string;
|
|
842
|
+
};
|
|
843
|
+
/**
|
|
844
|
+
* Await-result tuple for an HTTP call.
|
|
845
|
+
*
|
|
846
|
+
* Success is `[null, data, response]`; failure is `[fault, undefined, undefined]` because the
|
|
847
|
+
* fault carries whatever response metadata existed.
|
|
848
|
+
*/
|
|
849
|
+
export type HttpAwaitResult<TData = undefined, TErrorData = undefined> = [error: null, result: TData, response: [TData] extends [undefined] ? HttpMeta : DecodedResponse<TData>] | [error: FaultOf<TErrorData>, result: undefined, response: undefined];
|
|
850
|
+
type HttpExecuteAwaitResult<TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined> = [error: null, result: RequestSuccessData<TOutput>, response: DeclaredResponse<TOutput>] | [error: Fault<TError>, result: undefined, response: undefined];
|
|
851
|
+
/**
|
|
852
|
+
* Declare a typed HTTP request endpoint.
|
|
853
|
+
*
|
|
854
|
+
* Pass method, path, an optional input struct, and the single `output` and `error` structs.
|
|
855
|
+
* Call the returned endpoint with input to get an `HttpCommand` for `client.execute`.
|
|
856
|
+
*
|
|
857
|
+
* @param definition - Request contract (method, path, input, builder, output).
|
|
858
|
+
* @returns An endpoint that creates `HttpCommand` values from input.
|
|
859
|
+
*
|
|
860
|
+
* @example
|
|
861
|
+
* ```ts
|
|
862
|
+
* const getUser = defineRequest({
|
|
863
|
+
* method: 'GET',
|
|
864
|
+
* path: '/users/:id',
|
|
865
|
+
* input: struct.object({ id: struct.number() }),
|
|
866
|
+
* builder: (input) => ({ path: { id: input.id } }),
|
|
867
|
+
* output: struct.object({ id: struct.number(), name: struct.string() }),
|
|
868
|
+
* error: struct.object({ message: struct.string() }),
|
|
869
|
+
* })
|
|
870
|
+
* ```
|
|
871
|
+
*/
|
|
872
|
+
export declare function defineRequest<const M extends string, const P extends string, TInput extends AnyStruct | undefined = undefined, TOutput extends AnyStruct | undefined = undefined, TError extends AnyStruct | undefined = undefined>(definition: ResponseDeclaration<TOutput, TError> & {
|
|
873
|
+
input?: TInput;
|
|
874
|
+
method: M;
|
|
875
|
+
operation?: string;
|
|
876
|
+
path: P;
|
|
877
|
+
} & BuilderField<NoInfer<TInput>, HttpRequestShape<NoInfer<P>, NoInfer<M>>>): RequestEndpoint<TInput, TOutput, TError>;
|
|
878
|
+
/**
|
|
879
|
+
* Run an `HttpCommand` against client config: validate input, send the request, parse the response.
|
|
880
|
+
* Prefer `client.execute(command)` in application code; this is the underlying implementation.
|
|
881
|
+
*
|
|
882
|
+
* @param clientConfig - Resolved HTTP client configuration (endpoint, interceptors, handler).
|
|
883
|
+
* @param command - Command from a `defineRequest` endpoint.
|
|
884
|
+
* @param options - Per-request progress and cancellation options.
|
|
885
|
+
* @returns An await-result tuple of success body or typed request error.
|
|
886
|
+
*/
|
|
887
|
+
export declare function executeHttpCommand<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined>(clientConfig: HttpClientConfig, command: HttpCommand<TInput, TOutput, TError>, options?: HttpExecuteOptions): Promise<HttpExecuteAwaitResult<TOutput, TError>>;
|
|
888
|
+
//#endregion
|
|
889
|
+
//#region src/sse/sse.d.ts
|
|
890
|
+
/** Map of SSE event names to payload structs. Declare `__proto__` with a computed own key. */
|
|
891
|
+
export type EventStructs = {
|
|
892
|
+
[key: string]: AnyStruct;
|
|
893
|
+
};
|
|
894
|
+
type EventName<TKey extends string | number> = `${TKey}`;
|
|
895
|
+
type KnownEventUnion<TEvents extends EventStructs> = { [K in keyof TEvents & (number | string)]: EventName<K> extends 'default' ? never : {
|
|
896
|
+
data: Infer<TEvents[K]>;
|
|
897
|
+
event: EventName<K>;
|
|
898
|
+
id?: string;
|
|
899
|
+
}; }[keyof TEvents & (number | string)];
|
|
900
|
+
type DefaultEventUnion<TEvents extends EventStructs> = 'default' extends keyof TEvents ? {
|
|
901
|
+
data: Infer<TEvents['default']>;
|
|
902
|
+
event: string;
|
|
903
|
+
id?: string;
|
|
141
904
|
} : never;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
export
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
905
|
+
/** Parsed SSE event payload inferred from an `EventStructs` map. */
|
|
906
|
+
export type EventStreamData<TEvents extends EventStructs> = TEvents extends EventStructs ? KnownEventUnion<TEvents> | DefaultEventUnion<TEvents> : never;
|
|
907
|
+
interface EventStreamDefinitionBase<TEvents extends EventStructs = EventStructs> {
|
|
908
|
+
events: TEvents;
|
|
909
|
+
maxBufferSize: number;
|
|
910
|
+
maxQueueSize: number;
|
|
911
|
+
method?: string;
|
|
912
|
+
operation?: string;
|
|
913
|
+
path: string;
|
|
914
|
+
}
|
|
915
|
+
/** Makes `error` required only when an error struct is declared, so omission stays `Fault<undefined>`. */
|
|
916
|
+
type EventStreamErrorField<TError extends AnyStruct | undefined> = [TError] extends [undefined] ? {
|
|
917
|
+
error?: never;
|
|
918
|
+
} : {
|
|
919
|
+
error: TError;
|
|
920
|
+
};
|
|
921
|
+
/** Contract describing an SSE endpoint: path, events, and buffer/queue limits. */
|
|
922
|
+
export type EventStreamDefinition<TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined> = EventStreamDefinitionBase<TEvents> & EventStreamErrorField<TError> & {
|
|
923
|
+
builder?: OutboundBuilder;
|
|
924
|
+
input?: TInput;
|
|
925
|
+
};
|
|
926
|
+
/** Await-result tuple from opening an SSE stream via `client.execute`. */
|
|
927
|
+
export type StreamAwaitResult<TEvent, TError extends AnyStruct | undefined = undefined> = [error: null, stream: EventStreamHandle<TEvent>, open: EventStreamOpenInfo] | [error: Fault<TError>, stream: undefined, open: EventStreamOpenInfo | undefined];
|
|
928
|
+
/** Executable SSE command produced by an `EventStreamEndpoint`. */
|
|
929
|
+
export interface EventStreamCommand<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined> extends BaseCommand<typeof EVENT_STREAM_COMMAND> {
|
|
930
|
+
readonly endpoint: ResolvedEventStreamDefinition<TInput, TEvents, TError>;
|
|
931
|
+
readonly input: EndpointInput<TInput> | undefined;
|
|
932
|
+
}
|
|
933
|
+
/** Per-execute options for SSE commands (abort, timeout). */
|
|
934
|
+
export type EventStreamExecuteOptions = UseCancellationConfig & {
|
|
935
|
+
signal?: AbortSignal;
|
|
936
|
+
};
|
|
937
|
+
/** Endpoint returned by `defineEventStream`; call it to create an `EventStreamCommand`. */
|
|
938
|
+
export type EventStreamEndpoint<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined> = EndpointCallable<TInput, EventStreamCommand<TInput, TEvents, TError>>;
|
|
939
|
+
type ResolvedEventStreamDefinition<TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined> = EventStreamDefinition<TInput, TEvents, TError> & {
|
|
940
|
+
readonly method: string;
|
|
941
|
+
};
|
|
942
|
+
/**
|
|
943
|
+
* Declare a typed Server-Sent Events endpoint.
|
|
944
|
+
*
|
|
945
|
+
* Pass path, event structs, and buffer/queue limits. Call the returned endpoint
|
|
946
|
+
* with input to get an `EventStreamCommand` for `client.execute`.
|
|
947
|
+
*
|
|
948
|
+
* @param definition - SSE contract (path, events, buffer limits, optional input).
|
|
949
|
+
* @returns An endpoint that creates `EventStreamCommand` values from input.
|
|
950
|
+
*
|
|
951
|
+
* @example
|
|
952
|
+
* ```ts
|
|
953
|
+
* const useEvents = defineEventStream({
|
|
954
|
+
* maxBufferSize: 1024,
|
|
955
|
+
* maxQueueSize: 16,
|
|
956
|
+
* path: '/events',
|
|
957
|
+
* events: { message: struct.object({ text: struct.string() }) },
|
|
958
|
+
* })
|
|
959
|
+
* ```
|
|
960
|
+
*/
|
|
961
|
+
export declare function defineEventStream<const P extends string, const M extends string = 'GET', TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined>(definition: Omit<EventStreamDefinitionBase<TEvents>, 'method' | 'path'> & EventStreamErrorField<TError> & {
|
|
962
|
+
input?: TInput;
|
|
963
|
+
method?: M;
|
|
964
|
+
path: P;
|
|
965
|
+
} & BuilderField<NoInfer<TInput>, EventStreamRequestShape<NoInfer<P>, NoInfer<M>>>): EventStreamEndpoint<TInput, TEvents, TError>;
|
|
966
|
+
/**
|
|
967
|
+
* Open an SSE command against the given client config.
|
|
968
|
+
*
|
|
969
|
+
* Prefer `client.execute(command)` in application code; this is the low-level entry used by the client.
|
|
970
|
+
*
|
|
971
|
+
* @param clientConfig - Resolved client configuration.
|
|
972
|
+
* @param command - SSE command from an `EventStreamEndpoint`.
|
|
973
|
+
* @param options - Optional execute options (abort, timeout).
|
|
974
|
+
* @returns Await-result tuple of `[error, stream, open]`.
|
|
975
|
+
*/
|
|
976
|
+
export declare function executeEventStreamCommand<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined>(clientConfig: ClientConfig, command: EventStreamCommand<TInput, TEvents, TError>, options?: EventStreamExecuteOptions): Promise<StreamAwaitResult<EventStreamData<TEvents>, TError>>;
|
|
977
|
+
//#endregion
|
|
978
|
+
//#region src/client/command.d.ts
|
|
979
|
+
declare const COMMAND_TYPE: unique symbol;
|
|
980
|
+
declare const HTTP_COMMAND: unique symbol;
|
|
981
|
+
declare const EVENT_STREAM_COMMAND: unique symbol;
|
|
982
|
+
declare const WEB_SOCKET_COMMAND: unique symbol;
|
|
983
|
+
/** The command's own runner, so `client.execute` never imports a transport the app does not use. */
|
|
984
|
+
declare const COMMAND_EXECUTE: unique symbol;
|
|
985
|
+
type CommandExecutor = (config: ClientConfig, command: never, options?: never) => Promise<unknown>;
|
|
986
|
+
type CommandType = typeof HTTP_COMMAND | typeof EVENT_STREAM_COMMAND | typeof WEB_SOCKET_COMMAND;
|
|
987
|
+
interface BaseCommand<TCommandType extends CommandType> {
|
|
988
|
+
readonly [COMMAND_EXECUTE]: CommandExecutor;
|
|
989
|
+
readonly [COMMAND_TYPE]: TCommandType;
|
|
990
|
+
}
|
|
991
|
+
//#endregion
|
|
992
|
+
//#region src/web_socket/codec.d.ts
|
|
993
|
+
interface WebSocketCloseSnapshot {
|
|
994
|
+
cause?: unknown;
|
|
995
|
+
code?: number;
|
|
996
|
+
reason?: string;
|
|
997
|
+
wasClean?: boolean;
|
|
998
|
+
}
|
|
999
|
+
//#endregion
|
|
1000
|
+
//#region src/web_socket/web_socket.d.ts
|
|
1001
|
+
/** Lifecycle state of a managed WebSocket session. */
|
|
1002
|
+
export type WebSocketState = 'aborted' | 'closed' | 'closing' | 'connecting' | 'error' | 'idle' | 'open' | 'reconnecting';
|
|
1003
|
+
/** Decoded incoming frame. Alias fields use their logical names. */
|
|
1004
|
+
export type WebSocketIncomingData<TIncoming extends AnyStruct> = Infer<TIncoming>;
|
|
1005
|
+
/** Value accepted by `session.send`. `never` when the endpoint declares no outgoing struct. */
|
|
1006
|
+
export type WebSocketOutgoingData<TOutgoing extends AnyStruct | undefined> = TOutgoing extends AnyStruct ? StructInput<TOutgoing> : never;
|
|
1007
|
+
interface WebSocketDefinitionBase<TIncoming extends AnyStruct = AnyStruct, TOutgoing extends AnyStruct | undefined = undefined> {
|
|
1008
|
+
incoming: TIncoming;
|
|
1009
|
+
maxIncomingQueueSize: number;
|
|
1010
|
+
maxOutgoingQueueSize?: number;
|
|
1011
|
+
operation?: string;
|
|
1012
|
+
outgoing?: TOutgoing;
|
|
1013
|
+
path: string;
|
|
1014
|
+
protocols?: readonly string[];
|
|
1015
|
+
}
|
|
1016
|
+
/** Contract describing a WebSocket endpoint: path, message structs, and queue limits. */
|
|
1017
|
+
export type WebSocketDefinition<TInput extends AnyStruct | undefined = undefined, TIncoming extends AnyStruct = AnyStruct, TOutgoing extends AnyStruct | undefined = undefined> = WebSocketDefinitionBase<TIncoming, TOutgoing> & {
|
|
1018
|
+
builder?: OutboundBuilder;
|
|
1019
|
+
input?: TInput;
|
|
1020
|
+
};
|
|
1021
|
+
/** Connection metadata for the current WebSocket generation. */
|
|
1022
|
+
export interface WebSocketConnectionInfo {
|
|
1023
|
+
extensions?: string;
|
|
1024
|
+
generation: number;
|
|
1025
|
+
protocol?: string;
|
|
1026
|
+
url?: string;
|
|
1027
|
+
}
|
|
1028
|
+
/** How a WebSocket session ended: closed, aborted, or error. */
|
|
1029
|
+
export type WebSocketCloseInfo = {
|
|
1030
|
+
kind: 'closed';
|
|
1031
|
+
code?: number;
|
|
1032
|
+
reason?: string;
|
|
1033
|
+
wasClean?: boolean;
|
|
1034
|
+
} | {
|
|
1035
|
+
kind: 'aborted';
|
|
1036
|
+
cause?: unknown;
|
|
1037
|
+
code?: number;
|
|
1038
|
+
reason?: string;
|
|
1039
|
+
wasClean?: boolean;
|
|
1040
|
+
} | {
|
|
1041
|
+
kind: 'error';
|
|
1042
|
+
cause: unknown;
|
|
1043
|
+
code?: number;
|
|
1044
|
+
reason?: string;
|
|
1045
|
+
wasClean?: boolean;
|
|
1046
|
+
};
|
|
1047
|
+
/** Typed WebSocket session: send/receive messages, observe state, and close. */
|
|
1048
|
+
export interface WebSocketSession<TIncoming = unknown, TOutgoing = never> extends AsyncDisposable {
|
|
1049
|
+
readonly bufferedAmount: number;
|
|
1050
|
+
readonly connection: WebSocketConnectionInfo;
|
|
1051
|
+
readonly closed: Promise<WebSocketCloseInfo>;
|
|
1052
|
+
readonly receive: AsyncIterable<TIncoming>;
|
|
1053
|
+
readonly state: WebSocketState;
|
|
1054
|
+
close(code?: number, reason?: string): void;
|
|
1055
|
+
[Symbol.asyncDispose](): PromiseLike<void>;
|
|
1056
|
+
onRuntimeError(listener: (error: unknown) => void): () => void;
|
|
1057
|
+
onStateChange(listener: (state: WebSocketState) => void): () => void;
|
|
1058
|
+
send(message: TOutgoing): void;
|
|
1059
|
+
}
|
|
1060
|
+
/** Await-result tuple from opening a WebSocket via `client.execute`. */
|
|
1061
|
+
export type SocketAwaitResult<TIncoming, TOutgoing = never> = [error: null, socket: WebSocketSession<TIncoming, TOutgoing>, connection: WebSocketConnectionInfo] | [error: Fault<undefined>, socket: undefined, connection: WebSocketConnectionInfo | undefined];
|
|
1062
|
+
interface UseWebSocketBaseConfig<TIncoming = unknown, TOutgoing = unknown> {
|
|
1063
|
+
beforeConnect?: ClientWebSocketOptions['beforeConnect'];
|
|
1064
|
+
heartbeat?: WebSocketHeartbeatConfig<TIncoming, TOutgoing>;
|
|
1065
|
+
protocols?: readonly string[];
|
|
1066
|
+
reconnect?: ClientWebSocketOptions['reconnect'];
|
|
1067
|
+
}
|
|
1068
|
+
/** Client configuration for WebSocket execute (heartbeat, reconnect, abort). */
|
|
1069
|
+
export type UseWebSocketConfig<TIncoming = unknown, TOutgoing = unknown> = UseWebSocketBaseConfig<TIncoming, TOutgoing> & UseCancellationConfig;
|
|
1070
|
+
/** Per-execute options for WebSocket commands, including an optional `AbortSignal`. */
|
|
1071
|
+
export type WebSocketExecuteOptions<TIncoming = unknown, TOutgoing = unknown> = UseWebSocketConfig<TIncoming, TOutgoing> & {
|
|
1072
|
+
signal?: AbortSignal;
|
|
1073
|
+
};
|
|
1074
|
+
/** Executable WebSocket command produced by a `WebSocketEndpoint`. */
|
|
1075
|
+
export interface WebSocketCommand<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined> extends BaseCommand<typeof WEB_SOCKET_COMMAND> {
|
|
1076
|
+
readonly endpoint: WebSocketDefinition<TInput, TIncoming, TOutgoing>;
|
|
1077
|
+
readonly input: EndpointInput<TInput> | undefined;
|
|
1078
|
+
}
|
|
1079
|
+
/** Endpoint returned by `defineWebSocket`; call it to create a `WebSocketCommand`. */
|
|
1080
|
+
export type WebSocketEndpoint<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined> = EndpointCallable<TInput, WebSocketCommand<TInput, TIncoming, TOutgoing>>;
|
|
1081
|
+
/** Reason recorded when the session is closed via `session.close()`. */
|
|
1082
|
+
export type ManualSocketCloseReason = {
|
|
1083
|
+
code?: number;
|
|
1084
|
+
kind: 'manual-web-socket-close';
|
|
1085
|
+
reason?: string;
|
|
1086
|
+
};
|
|
1087
|
+
/** Heartbeat ping/ack configuration for a live WebSocket session. */
|
|
1088
|
+
export interface WebSocketHeartbeatConfig<TIncoming = unknown, TOutgoing = unknown> {
|
|
1089
|
+
intervalMs: number;
|
|
1090
|
+
isAck?: (message: TIncoming) => boolean;
|
|
1091
|
+
message?: () => TOutgoing;
|
|
1092
|
+
timeoutMs?: number;
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Declare a typed WebSocket endpoint.
|
|
1096
|
+
*
|
|
1097
|
+
* Pass path, incoming (and optional outgoing) message structs, and queue limits.
|
|
1098
|
+
* Call the returned endpoint with input to get a `WebSocketCommand` for `client.execute`.
|
|
1099
|
+
*
|
|
1100
|
+
* @param definition - WebSocket contract (path, structs, queue limits, optional input).
|
|
1101
|
+
* @returns An endpoint that creates `WebSocketCommand` values from input.
|
|
1102
|
+
*
|
|
1103
|
+
* @example
|
|
1104
|
+
* ```ts
|
|
1105
|
+
* const useChat = defineWebSocket({
|
|
1106
|
+
* maxIncomingQueueSize: 16,
|
|
1107
|
+
* path: '/ws/chat',
|
|
1108
|
+
* incoming: struct.object({ text: struct.string(), type: struct.literal('message') }),
|
|
1109
|
+
* outgoing: struct.object({ text: struct.string(), type: struct.literal('message') }),
|
|
1110
|
+
* })
|
|
1111
|
+
* ```
|
|
1112
|
+
*/
|
|
1113
|
+
export declare function defineWebSocket<const P extends string, TInput extends AnyStruct | undefined = undefined, TIncoming extends AnyStruct = AnyStruct, TOutgoing extends AnyStruct | undefined = undefined>(definition: Omit<WebSocketDefinitionBase<TIncoming, TOutgoing>, 'path'> & {
|
|
1114
|
+
input?: TInput;
|
|
1115
|
+
path: P;
|
|
1116
|
+
} & BuilderField<NoInfer<TInput>, WebSocketRequestShape<NoInfer<P>>>): WebSocketEndpoint<TInput, TIncoming, TOutgoing>;
|
|
1117
|
+
/**
|
|
1118
|
+
* Open a WebSocket command against the given client config.
|
|
1119
|
+
*
|
|
1120
|
+
* Prefer `client.execute(command)` in application code; this is the low-level entry used by the client.
|
|
1121
|
+
*
|
|
1122
|
+
* @param clientConfig - Resolved client configuration.
|
|
1123
|
+
* @param command - WebSocket command from a `WebSocketEndpoint`.
|
|
1124
|
+
* @param options - Optional execute options (heartbeat, reconnect, abort).
|
|
1125
|
+
* @returns Await-result tuple of `[error, socket, connection]`.
|
|
1126
|
+
*/
|
|
1127
|
+
export declare function executeWebSocketCommand<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined>(clientConfig: ClientConfig, command: WebSocketCommand<TInput, TIncoming, TOutgoing>, options?: WebSocketExecuteOptions<WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>): Promise<SocketAwaitResult<WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>>;
|
|
1128
|
+
/** Outcome of a single WebSocket connect attempt used by reconnect logic. */
|
|
1129
|
+
export type SocketLifecycleOutcome = {
|
|
1130
|
+
closeInfo: WebSocketCloseSnapshot;
|
|
1131
|
+
connection?: WebSocketConnectionInfo;
|
|
1132
|
+
cause?: unknown;
|
|
1133
|
+
opened: boolean;
|
|
1134
|
+
};
|
|
1135
|
+
//#endregion
|
|
1136
|
+
//#region src/interceptor/interceptor.d.ts
|
|
1137
|
+
/**
|
|
1138
|
+
* Continuation that runs the rest of the HTTP interceptor chain (or the handler).
|
|
1139
|
+
*
|
|
1140
|
+
* `next(req)` only goes **inward** — remaining interceptors registered after this one,
|
|
1141
|
+
* then the Fetch handler. It is not a re-dispatch of `client.execute` / `axios(config)`
|
|
1142
|
+
* from the outside of the onion. Call `next` again for a safe replay (for example one
|
|
1143
|
+
* 401 refresh) from the same interceptor; outer layers do not run a second time.
|
|
1144
|
+
*/
|
|
1145
|
+
type HttpInterceptorNext = (req: HttpRequest) => Promise<HttpResponse<unknown>>;
|
|
1146
|
+
/**
|
|
1147
|
+
* HTTP interceptor function: may inspect/modify the request, then call `next`.
|
|
1148
|
+
*/
|
|
1149
|
+
type InterceptorFn = (req: HttpRequest, next: HttpInterceptorNext) => Promise<HttpResponse<unknown>>;
|
|
1150
|
+
/**
|
|
1151
|
+
* Tagged HTTP interceptor for client option lists.
|
|
1152
|
+
*/
|
|
1153
|
+
interface HttpInterceptor {
|
|
1154
|
+
kind: 'http';
|
|
1155
|
+
fn: InterceptorFn;
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* Wrap an `InterceptorFn` as a tagged `HttpInterceptor`.
|
|
1159
|
+
*
|
|
1160
|
+
* @param fn - HTTP interceptor function.
|
|
1161
|
+
* @returns An `HttpInterceptor` with `kind: 'http'`.
|
|
1162
|
+
*/
|
|
1163
|
+
export declare function createHttpInterceptor(fn: InterceptorFn): HttpInterceptor;
|
|
1164
|
+
/**
|
|
1165
|
+
* Terminal SSE handler that opens an event stream for the given request.
|
|
1166
|
+
*/
|
|
1167
|
+
type SSEHandler = (req: HttpRequest) => Promise<EventStreamHandle<unknown>>;
|
|
1168
|
+
/**
|
|
1169
|
+
* SSE interceptor function: may inspect/modify the request, then call `next`.
|
|
1170
|
+
*/
|
|
1171
|
+
type SSEInterceptorFn = (req: HttpRequest, next: SSEHandler) => Promise<EventStreamHandle<unknown>>;
|
|
1172
|
+
/**
|
|
1173
|
+
* Tagged SSE interceptor for client option lists.
|
|
1174
|
+
*/
|
|
1175
|
+
interface SSEInterceptor {
|
|
1176
|
+
kind: 'sse';
|
|
1177
|
+
fn: SSEInterceptorFn;
|
|
1178
|
+
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Wrap an `SSEInterceptorFn` as a tagged `SSEInterceptor`.
|
|
1181
|
+
*
|
|
1182
|
+
* @param fn - SSE interceptor function.
|
|
1183
|
+
* @returns An `SSEInterceptor` with `kind: 'sse'`.
|
|
1184
|
+
*/
|
|
1185
|
+
export declare function createSSEInterceptor(fn: SSEInterceptorFn): SSEInterceptor;
|
|
1186
|
+
/**
|
|
1187
|
+
* Minimal WebSocket session surface used by interceptors.
|
|
1188
|
+
*
|
|
1189
|
+
* Structurally compatible with `WebSocketSession` without importing that type
|
|
1190
|
+
* (avoids a circular dependency between interceptors and WebSocket).
|
|
1191
|
+
*/
|
|
1192
|
+
interface WebSocketSessionLike extends AsyncDisposable {
|
|
1193
|
+
readonly bufferedAmount: number;
|
|
1194
|
+
readonly connection: {
|
|
1195
|
+
extensions?: string;
|
|
1196
|
+
generation: number;
|
|
1197
|
+
protocol?: string;
|
|
1198
|
+
url?: string;
|
|
1199
|
+
};
|
|
1200
|
+
readonly closed: Promise<WebSocketCloseInfo>;
|
|
1201
|
+
readonly receive: AsyncIterable<unknown>;
|
|
1202
|
+
readonly state: WebSocketState;
|
|
1203
|
+
close(code?: number, reason?: string): void;
|
|
1204
|
+
[Symbol.asyncDispose](): PromiseLike<void>;
|
|
1205
|
+
onRuntimeError(listener: (error: unknown) => void): () => void;
|
|
1206
|
+
onStateChange(listener: (state: WebSocketState) => void): () => void;
|
|
1207
|
+
send(message: unknown): void;
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Terminal WebSocket handler that opens a session for the given request.
|
|
1211
|
+
*/
|
|
1212
|
+
type WebSocketHandler = (req: HttpRequest) => Promise<WebSocketSessionLike>;
|
|
1213
|
+
/**
|
|
1214
|
+
* WebSocket interceptor function: may inspect/modify the request, then call `next`.
|
|
1215
|
+
*/
|
|
1216
|
+
type WebSocketInterceptorFn = (req: HttpRequest, next: WebSocketHandler) => Promise<WebSocketSessionLike>;
|
|
1217
|
+
/**
|
|
1218
|
+
* Tagged WebSocket interceptor for client option lists.
|
|
1219
|
+
*/
|
|
1220
|
+
interface WebSocketInterceptor {
|
|
1221
|
+
kind: 'web-socket';
|
|
1222
|
+
fn: WebSocketInterceptorFn;
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Wrap a `WebSocketInterceptorFn` as a tagged `WebSocketInterceptor`.
|
|
1226
|
+
*
|
|
1227
|
+
* @param fn - WebSocket interceptor function.
|
|
1228
|
+
* @returns A `WebSocketInterceptor` with `kind: 'web-socket'`.
|
|
1229
|
+
*/
|
|
1230
|
+
export declare function createWebSocketInterceptor(fn: WebSocketInterceptorFn): WebSocketInterceptor;
|
|
1231
|
+
/**
|
|
1232
|
+
* Any tagged interceptor accepted by client interceptor options.
|
|
1233
|
+
*/
|
|
1234
|
+
type Interceptor = HttpInterceptor | SSEInterceptor | WebSocketInterceptor;
|
|
1235
|
+
//#endregion
|
|
1236
|
+
//#region src/client/config.d.ts
|
|
1237
|
+
/**
|
|
1238
|
+
* Serializes an encoded query object into a query string.
|
|
1239
|
+
*
|
|
1240
|
+
* `query` is the wire object: aliases already applied, `Date` values already ISO
|
|
1241
|
+
* strings, `bigint` values already strings. Nested objects and arrays are preserved.
|
|
1242
|
+
* The returned string is used verbatim and is not passed through `URLSearchParams`.
|
|
1243
|
+
*
|
|
1244
|
+
* @param query - Encoded query object.
|
|
1245
|
+
* @returns The query string without a leading `?`.
|
|
1246
|
+
*/
|
|
1247
|
+
type QuerySerializer = (query: {
|
|
1248
|
+
[key: string]: unknown;
|
|
1249
|
+
}) => string;
|
|
1250
|
+
/**
|
|
1251
|
+
* Fetch-compatible function used as an HTTP or SSE handle.
|
|
1252
|
+
*
|
|
1253
|
+
* This is the `(input, init?) => Promise<Response>` call signature Defjs invokes,
|
|
1254
|
+
* not `typeof fetch`, so mocks do not need host extras such as `preconnect`.
|
|
1255
|
+
*/
|
|
1256
|
+
type FetchHandle = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
1257
|
+
/**
|
|
1258
|
+
* Minimal WebSocket-like handle used by the client transport.
|
|
1259
|
+
*
|
|
1260
|
+
* Omits browser event-handler properties so custom implementations only need
|
|
1261
|
+
* the send/close/state surface Defjs relies on.
|
|
1262
|
+
*/
|
|
1263
|
+
type WebSocketHandle = Omit<WebSocket, 'binaryType' | 'CLOSED' | 'CLOSING' | 'CONNECTING' | 'dispatchEvent' | 'onclose' | 'onerror' | 'onmessage' | 'onopen' | 'OPEN' | 'readyState'> & {
|
|
1264
|
+
readonly readyState: number;
|
|
181
1265
|
};
|
|
1266
|
+
/** Constructor for a `WebSocketHandle`, including the `OPEN` ready-state constant. */
|
|
1267
|
+
type WebSocketHandleConstructor = {
|
|
1268
|
+
readonly OPEN: number;
|
|
1269
|
+
} & (new (...args: never[]) => WebSocketHandle);
|
|
1270
|
+
/** Optional WebSocket settings applied when creating a client. */
|
|
1271
|
+
interface ClientWebSocketOptions {
|
|
1272
|
+
/** WebSocket constructor; defaults to `globalThis.WebSocket`. */
|
|
1273
|
+
handle?: WebSocketHandleConstructor;
|
|
1274
|
+
/** Hook before each connect/reconnect attempt. */
|
|
1275
|
+
beforeConnect?: (context: {
|
|
1276
|
+
attempt: number;
|
|
1277
|
+
signal: AbortSignal;
|
|
1278
|
+
}) => void | Promise<void>;
|
|
1279
|
+
/** Periodic heartbeat ping and optional ACK matching. */
|
|
1280
|
+
heartbeat?: {
|
|
1281
|
+
/** Delay between heartbeat messages. */
|
|
1282
|
+
intervalMs: number;
|
|
1283
|
+
/** Returns whether an incoming message acknowledges the heartbeat. */
|
|
1284
|
+
isAck?: (message: unknown) => boolean;
|
|
1285
|
+
/** Builds the outbound heartbeat payload. */
|
|
1286
|
+
message?: <T = unknown>() => T | unknown;
|
|
1287
|
+
/** Time to wait for an ACK before treating the connection as unhealthy. */
|
|
1288
|
+
timeoutMs?: number;
|
|
1289
|
+
};
|
|
1290
|
+
/** Subprotocols passed to the WebSocket constructor. */
|
|
1291
|
+
protocols?: readonly string[];
|
|
1292
|
+
/** Automatic reconnect policy after unexpected closes. */
|
|
1293
|
+
reconnect?: {
|
|
1294
|
+
/** Retry budget after the first connect. Defaults to 3 when `reconnect` is set. `0` disables. Omitting this field is not unlimited. */
|
|
1295
|
+
attempts?: number;
|
|
1296
|
+
/** Initial backoff delay in milliseconds. */
|
|
1297
|
+
delayMs?: number;
|
|
1298
|
+
/** Multiplier applied to the delay after each failed attempt. */
|
|
1299
|
+
factor?: number;
|
|
1300
|
+
/** Random jitter factor applied to the delay (0–1). */
|
|
1301
|
+
jitter?: number;
|
|
1302
|
+
/** Upper bound for computed backoff delay. */
|
|
1303
|
+
maxDelayMs?: number;
|
|
1304
|
+
/** Return `false` to skip reconnecting for this close. */
|
|
1305
|
+
shouldReconnect?: (context: {
|
|
1306
|
+
attempt: number;
|
|
1307
|
+
cause?: unknown;
|
|
1308
|
+
code?: number;
|
|
1309
|
+
reason?: string;
|
|
1310
|
+
wasClean?: boolean;
|
|
1311
|
+
}) => boolean;
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
/** Optional SSE settings applied when creating a client. */
|
|
1315
|
+
interface ClientSSEOptions {
|
|
1316
|
+
/** Fetch implementation used to open the event stream. */
|
|
1317
|
+
handle?: FetchHandle;
|
|
1318
|
+
/** Called when an event has no matching struct or fails validation. */
|
|
1319
|
+
onInvalidEvent?: (context: {
|
|
1320
|
+
reason: 'missing-struct' | 'validation-failed';
|
|
1321
|
+
message: {
|
|
1322
|
+
id: string;
|
|
1323
|
+
event: string;
|
|
1324
|
+
data: string;
|
|
1325
|
+
};
|
|
1326
|
+
cause?: unknown;
|
|
1327
|
+
signal: AbortSignal;
|
|
1328
|
+
}) => unknown;
|
|
1329
|
+
/** Automatic reconnect policy after stream failures. */
|
|
1330
|
+
reconnect?: {
|
|
1331
|
+
/** Retry budget after the first attempt. Defaults to 3 when `reconnect` is set. `0` disables. Omitting this field is not unlimited. */
|
|
1332
|
+
attempts?: number;
|
|
1333
|
+
/** Initial backoff delay in milliseconds. */
|
|
1334
|
+
delayMs?: number;
|
|
1335
|
+
/** Multiplier applied to the delay after each failed attempt. */
|
|
1336
|
+
factor?: number;
|
|
1337
|
+
/** Random jitter factor applied to the delay (0–1). */
|
|
1338
|
+
jitter?: number;
|
|
1339
|
+
/** Upper bound for computed backoff delay. */
|
|
1340
|
+
maxDelayMs?: number;
|
|
1341
|
+
/** Return `false` to skip reconnecting for this failure. */
|
|
1342
|
+
shouldReconnect?: (context: {
|
|
1343
|
+
attempt: number;
|
|
1344
|
+
cause?: unknown;
|
|
1345
|
+
lastEventId: string;
|
|
1346
|
+
open?: {
|
|
1347
|
+
response: {
|
|
1348
|
+
status: number;
|
|
1349
|
+
statusText: string;
|
|
1350
|
+
url: string;
|
|
1351
|
+
};
|
|
1352
|
+
url: string;
|
|
1353
|
+
};
|
|
1354
|
+
}) => boolean | Promise<boolean>;
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
/** Resolved SSE config with a required `handle`. */
|
|
1358
|
+
interface ClientSSEConfig extends ClientSSEOptions {
|
|
1359
|
+
/** Fetch implementation used to open the event stream. */
|
|
1360
|
+
handle: FetchHandle;
|
|
1361
|
+
}
|
|
1362
|
+
/** User-facing HTTP client options before defaults are applied. */
|
|
1363
|
+
interface HttpClientOptions {
|
|
1364
|
+
/** Base URL prepended to relative request paths. */
|
|
1365
|
+
endpoint: string;
|
|
1366
|
+
/** Static default headers merged under command headers for HTTP/SSE. */
|
|
1367
|
+
headers?: Headers;
|
|
1368
|
+
/** HTTP transport overrides. */
|
|
1369
|
+
http?: {
|
|
1370
|
+
handle?: FetchHandle;
|
|
1371
|
+
};
|
|
1372
|
+
/** Interceptors applied in registration order. */
|
|
1373
|
+
interceptors?: Interceptor[];
|
|
1374
|
+
/** Serializes encoded query objects. Omit to use `URLSearchParams`. */
|
|
1375
|
+
querySerializer?: QuerySerializer;
|
|
1376
|
+
/** Default HTTP execute timeout in milliseconds (SSE/WebSocket ignore this). */
|
|
1377
|
+
timeout?: number;
|
|
1378
|
+
/** XSRF cookie/header mapping and optional token provider. */
|
|
1379
|
+
xsrf?: {
|
|
1380
|
+
/** Cookie name that stores the XSRF token. */
|
|
1381
|
+
cookieName?: string;
|
|
1382
|
+
/** Request header name that receives the token. */
|
|
1383
|
+
headerName?: string;
|
|
1384
|
+
/** Supplies a token instead of reading the cookie. */
|
|
1385
|
+
tokenProvider?: (context: {
|
|
1386
|
+
request: HttpRequest;
|
|
1387
|
+
}) => string | null | undefined;
|
|
1388
|
+
};
|
|
1389
|
+
/** When `true`, credentials are included with requests. */
|
|
1390
|
+
withCredentials?: boolean;
|
|
1391
|
+
}
|
|
1392
|
+
/** User-facing options for `createClient`, including SSE and WebSocket. */
|
|
1393
|
+
interface ClientOptions extends HttpClientOptions {
|
|
1394
|
+
/** SSE transport and reconnect options. */
|
|
1395
|
+
sse?: ClientSSEOptions;
|
|
1396
|
+
/** WebSocket transport, heartbeat, and reconnect options. */
|
|
1397
|
+
webSocket?: ClientWebSocketOptions;
|
|
1398
|
+
}
|
|
1399
|
+
/** Resolved HTTP client config after defaults and options are applied. */
|
|
1400
|
+
interface HttpClientConfig {
|
|
1401
|
+
/** Base URL prepended to relative request paths. */
|
|
1402
|
+
endpoint: string;
|
|
1403
|
+
/** Static default headers merged under command headers for HTTP/SSE. */
|
|
1404
|
+
headers?: Headers;
|
|
1405
|
+
/** HTTP transport with a required fetch handle. */
|
|
1406
|
+
http: {
|
|
1407
|
+
handle: FetchHandle;
|
|
1408
|
+
};
|
|
1409
|
+
/** Interceptors applied in registration order. */
|
|
1410
|
+
interceptors: Interceptor[];
|
|
1411
|
+
/** Serializes encoded query objects. Omit to use `URLSearchParams`. */
|
|
1412
|
+
querySerializer?: QuerySerializer;
|
|
1413
|
+
/** Default HTTP execute timeout in milliseconds (SSE/WebSocket ignore this). */
|
|
1414
|
+
timeout?: number;
|
|
1415
|
+
/** Resolved XSRF settings when enabled. */
|
|
1416
|
+
xsrf?: {
|
|
1417
|
+
/** Cookie name that stores the XSRF token. */
|
|
1418
|
+
cookieName: string;
|
|
1419
|
+
/** Request header name that receives the token. */
|
|
1420
|
+
headerName: string;
|
|
1421
|
+
/** Supplies a token instead of reading the cookie. */
|
|
1422
|
+
tokenProvider?: (context: {
|
|
1423
|
+
request: HttpRequest;
|
|
1424
|
+
}) => string | null | undefined;
|
|
1425
|
+
};
|
|
1426
|
+
/** When `true`, credentials are included with requests. */
|
|
1427
|
+
withCredentials?: boolean;
|
|
1428
|
+
}
|
|
1429
|
+
/** Resolved client config held by instances from `createClient`. */
|
|
1430
|
+
interface ClientConfig extends HttpClientConfig {
|
|
1431
|
+
/** Resolved SSE configuration. */
|
|
1432
|
+
sse: ClientSSEConfig;
|
|
1433
|
+
/** Resolved WebSocket configuration. */
|
|
1434
|
+
webSocket: ClientWebSocketOptions;
|
|
1435
|
+
}
|
|
1436
|
+
//#endregion
|
|
1437
|
+
//#region src/client/option.d.ts
|
|
1438
|
+
/** Mutates `ClientConfig` when applied by `createClient`. */
|
|
1439
|
+
type ClientOption = (config: ClientConfig) => void;
|
|
1440
|
+
/**
|
|
1441
|
+
* Sets the base URL prepended to relative request paths.
|
|
1442
|
+
*
|
|
1443
|
+
* @param endpoint - Absolute or relative base endpoint.
|
|
1444
|
+
* @returns An option that writes `config.endpoint`.
|
|
1445
|
+
*/
|
|
1446
|
+
export declare function withEndpoint(endpoint: string): ClientOption;
|
|
1447
|
+
/**
|
|
1448
|
+
* Sets static default headers for HTTP/SSE requests built by this client.
|
|
1449
|
+
*
|
|
1450
|
+
* Builder `headers` override the same names. HMAC and
|
|
1451
|
+
* dynamic Bearer tokens still belong in interceptors (they need the serialized body
|
|
1452
|
+
* or a refreshed credential).
|
|
1453
|
+
*
|
|
1454
|
+
* @param headers - `HeadersInit` bag cloned onto the client config.
|
|
1455
|
+
* @returns An option that writes `config.headers`.
|
|
1456
|
+
*/
|
|
1457
|
+
export declare function withHeaders(headers: HeadersInit): ClientOption;
|
|
1458
|
+
/**
|
|
1459
|
+
* Sets the default timeout for HTTP `execute` only.
|
|
1460
|
+
*
|
|
1461
|
+
* Timeout is applied before the interceptor chain (`mergeAbortSignals`). Execute
|
|
1462
|
+
* `{ timeout }` overrides this default. Execute `{ abort }` combines with the
|
|
1463
|
+
* default (abort → `ABORTED`, timer → `TIMEOUT`). SSE and WebSocket ignore this
|
|
1464
|
+
* option. XOR still rejects execute options that pass both `abort` and `timeout`.
|
|
1465
|
+
*
|
|
1466
|
+
* @param ms - Positive safe integer timeout in milliseconds.
|
|
1467
|
+
* @returns An option that writes `config.timeout`.
|
|
1468
|
+
*/
|
|
1469
|
+
export declare function withTimeout(ms: number): ClientOption;
|
|
1470
|
+
/**
|
|
1471
|
+
* Appends interceptors to the client interceptor chain.
|
|
1472
|
+
*
|
|
1473
|
+
* @param interceptors - Interceptors applied in registration order.
|
|
1474
|
+
* @returns An option that pushes onto `config.interceptors`.
|
|
1475
|
+
*/
|
|
1476
|
+
export declare function withInterceptors(...interceptors: Interceptor[]): ClientOption;
|
|
1477
|
+
/**
|
|
1478
|
+
* Sets the query serializer for HTTP, SSE, and WebSocket requests.
|
|
1479
|
+
*
|
|
1480
|
+
* The function receives the encoded wire object and its string is used verbatim.
|
|
1481
|
+
* Without this option, queries use `URLSearchParams`: arrays repeat keys and a nested
|
|
1482
|
+
* object fails. A builder that returns `URLSearchParams` skips this serializer.
|
|
1483
|
+
*
|
|
1484
|
+
* @param serializer - Function that turns an encoded query object into a string.
|
|
1485
|
+
* @returns An option that sets `config.querySerializer`.
|
|
1486
|
+
*/
|
|
1487
|
+
export declare function withQuerySerializer(serializer: QuerySerializer): ClientOption;
|
|
1488
|
+
/**
|
|
1489
|
+
* Overrides the Fetch-compatible function used for HTTP requests.
|
|
1490
|
+
*
|
|
1491
|
+
* @param fetchImpl - `(input, init?) => Promise<Response>`. Not `typeof fetch`, so
|
|
1492
|
+
* a mock does not need host extras such as `preconnect`.
|
|
1493
|
+
* @returns An option that sets `config.http.handle`.
|
|
1494
|
+
*/
|
|
1495
|
+
export declare function withHTTPHandle(fetchImpl: FetchHandle): ClientOption;
|
|
1496
|
+
/**
|
|
1497
|
+
* Overrides the Fetch-compatible function used for SSE connections.
|
|
1498
|
+
*
|
|
1499
|
+
* @param fetchImpl - `(input, init?) => Promise<Response>`. Not `typeof fetch`, so
|
|
1500
|
+
* a mock does not need host extras such as `preconnect`.
|
|
1501
|
+
* @returns An option that sets `config.sse.handle`.
|
|
1502
|
+
*/
|
|
1503
|
+
export declare function withSSEHandle(fetchImpl: FetchHandle): ClientOption;
|
|
1504
|
+
/**
|
|
1505
|
+
* Overrides the WebSocket constructor used for socket connections.
|
|
1506
|
+
*
|
|
1507
|
+
* @param WebSocketImpl - Constructor that returns a `WebSocketHandle`.
|
|
1508
|
+
* @returns An option that sets `config.webSocket.handle`.
|
|
1509
|
+
*/
|
|
1510
|
+
export declare function withWebSocketHandle(WebSocketImpl: WebSocketHandleConstructor): ClientOption;
|
|
1511
|
+
/**
|
|
1512
|
+
* Runs logic before each WebSocket connect or reconnect attempt.
|
|
1513
|
+
*
|
|
1514
|
+
* @param beforeConnect - Hook receiving attempt index and abort signal.
|
|
1515
|
+
* @returns An option that sets `config.webSocket.beforeConnect`.
|
|
1516
|
+
*/
|
|
1517
|
+
export declare function withWebSocketBeforeConnect(beforeConnect: ClientWebSocketOptions['beforeConnect']): ClientOption;
|
|
1518
|
+
/**
|
|
1519
|
+
* Configure WebSocket subprotocols for the connection handshake.
|
|
1520
|
+
*
|
|
1521
|
+
* `protocols` are passed as the second argument to the `WebSocket` constructor
|
|
1522
|
+
* and participate in the RFC 6455 subprotocol negotiation. They are only
|
|
1523
|
+
* meaningful when the server requires a specific protocol (for example,
|
|
1524
|
+
* `['json']` or `['v1']` to select a message encoding version).
|
|
1525
|
+
*
|
|
1526
|
+
* @param protocols - Subprotocol list for the WebSocket constructor.
|
|
1527
|
+
* @returns An option that sets `config.webSocket.protocols`.
|
|
1528
|
+
*/
|
|
1529
|
+
export declare function withWebSocketProtocols(protocols: readonly string[]): ClientOption;
|
|
1530
|
+
/**
|
|
1531
|
+
* Enables WebSocket heartbeat pings and optional ACK detection.
|
|
1532
|
+
*
|
|
1533
|
+
* @param options - Heartbeat interval, payload, timeout, and ACK predicate.
|
|
1534
|
+
* @returns An option that sets `config.webSocket.heartbeat`.
|
|
1535
|
+
*/
|
|
1536
|
+
export declare function withWebSocketHeartbeat(options: ClientWebSocketOptions['heartbeat']): ClientOption;
|
|
1537
|
+
/**
|
|
1538
|
+
* Configures automatic WebSocket reconnection after unexpected closes.
|
|
1539
|
+
*
|
|
1540
|
+
* @param options - Retry budget, backoff, and `shouldReconnect` gate.
|
|
1541
|
+
* @returns An option that sets `config.webSocket.reconnect`.
|
|
1542
|
+
*/
|
|
1543
|
+
export declare function withWebSocketReconnect(options: ClientWebSocketOptions['reconnect']): ClientOption;
|
|
1544
|
+
/**
|
|
1545
|
+
* Handles SSE events that lack a matching struct or fail validation.
|
|
1546
|
+
*
|
|
1547
|
+
* @param handler - Callback for invalid events; may throw or return a value.
|
|
1548
|
+
* @returns An option that sets `config.sse.onInvalidEvent`.
|
|
1549
|
+
*/
|
|
1550
|
+
export declare function withSSEOnInvalidEvent(handler: ClientSSEOptions['onInvalidEvent']): ClientOption;
|
|
1551
|
+
/**
|
|
1552
|
+
* Configures automatic SSE reconnection after stream failures.
|
|
1553
|
+
*
|
|
1554
|
+
* @param options - Retry budget, backoff, and `shouldReconnect` gate.
|
|
1555
|
+
* @returns An option that sets `config.sse.reconnect`.
|
|
1556
|
+
*/
|
|
1557
|
+
export declare function withSSEReconnect(options: ClientSSEOptions['reconnect']): ClientOption;
|
|
1558
|
+
/**
|
|
1559
|
+
* Enables XSRF cookie-to-header token forwarding for HTTP requests.
|
|
1560
|
+
*
|
|
1561
|
+
* Defaults to cookie `XSRF-TOKEN` and header `X-XSRF-TOKEN` when names are omitted.
|
|
1562
|
+
*
|
|
1563
|
+
* @param options - Cookie/header names and optional token provider.
|
|
1564
|
+
* @returns An option that sets `config.xsrf`.
|
|
1565
|
+
*/
|
|
1566
|
+
export declare function withXSRF(options?: HttpClientOptions['xsrf']): ClientOption;
|
|
1567
|
+
/**
|
|
1568
|
+
* Sets whether HTTP/SSE requests should include credentials (cookies).
|
|
1569
|
+
*
|
|
1570
|
+
* @param value - When `true`, credentials are sent with cross-origin requests.
|
|
1571
|
+
* @returns An option that sets `config.withCredentials`.
|
|
1572
|
+
*/
|
|
1573
|
+
export declare function withCredentials(value: boolean): ClientOption;
|
|
1574
|
+
//#endregion
|
|
1575
|
+
//#region src/client/client.d.ts
|
|
182
1576
|
declare const CLIENT: unique symbol;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
1577
|
+
/**
|
|
1578
|
+
* Defjs client: holds config and `execute`s HTTP, SSE, and WebSocket commands.
|
|
1579
|
+
*/
|
|
1580
|
+
type Client = {
|
|
1581
|
+
readonly [CLIENT]: ClientConfig;
|
|
1582
|
+
/** Open an SSE command and return stream open/await results. */
|
|
1583
|
+
execute<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined>(command: EventStreamCommand<TInput, TEvents, TError>, options?: EventStreamExecuteOptions): Promise<StreamAwaitResult<EventStreamData<TEvents>, TError>>;
|
|
1584
|
+
/** Open a WebSocket command and return session await results. */
|
|
1585
|
+
execute<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined>(command: WebSocketCommand<TInput, TIncoming, TOutgoing>, options?: WebSocketExecuteOptions<WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>): Promise<SocketAwaitResult<WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>>;
|
|
1586
|
+
/** Run an HTTP command and return an await-result tuple. */
|
|
1587
|
+
execute<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined>(command: HttpCommand<TInput, TOutput, TError>, options?: HttpExecuteOptions): ReturnType<typeof executeHttpCommand<TInput, TOutput, TError>>;
|
|
1588
|
+
};
|
|
1589
|
+
/**
|
|
1590
|
+
* Create a Defjs client from option helpers.
|
|
1591
|
+
*
|
|
1592
|
+
* Options are applied in order. Prefer creating the client inside the
|
|
1593
|
+
* request boundary when interceptors close over auth or tenants.
|
|
1594
|
+
*
|
|
1595
|
+
* @param options - Client option helpers such as `withEndpoint`.
|
|
1596
|
+
* @returns A client that can `execute` HTTP, SSE, and WebSocket commands.
|
|
1597
|
+
*
|
|
1598
|
+
* @example
|
|
1599
|
+
* ```ts
|
|
1600
|
+
* const client = createClient(withEndpoint('https://api.example.com'))
|
|
1601
|
+
* ```
|
|
1602
|
+
*/
|
|
1603
|
+
export declare function createClient(...options: ClientOption[]): Client;
|
|
1604
|
+
//#endregion
|
|
1605
|
+
//#region src/http/transport/fetch.d.ts
|
|
1606
|
+
/**
|
|
1607
|
+
* Default HTTP transport: perform `httpRequest` with `fetch` and return an `HttpResponse`.
|
|
1608
|
+
* Used by the client unless `withHTTPHandle` replaces it; also usable in tests and custom handlers.
|
|
1609
|
+
*
|
|
1610
|
+
* @param httpRequest - Normalized request (URL, headers, body, abort, progress hooks).
|
|
1611
|
+
* @param fetchImpl - Fetch implementation; defaults to global `fetch`. The library default handle is called as
|
|
1612
|
+
* `(url, init)` and its body is read in one piece unless download progress is observed. Any other handle receives a
|
|
1613
|
+
* `Request` and its body is read chunk by chunk.
|
|
1614
|
+
* @returns Parsed `HttpResponse`. Rejects when no response reached the client, or when reading the
|
|
1615
|
+
* body failed — a transport failure is a fault, never a response.
|
|
1616
|
+
*/
|
|
1617
|
+
export declare function fetchHandler(httpRequest: HttpRequest, fetchImpl?: FetchHandle): Promise<HttpResponse<unknown>>;
|
|
1618
|
+
//#endregion
|
|
1619
|
+
//#region src/internal/url.d.ts
|
|
1620
|
+
export declare function createResolvedRequestUrl(baseEndpoint: string, path: string, queryString?: string): URL;
|
|
1621
|
+
//#endregion
|
|
1622
|
+
//#region src/interceptor/basic_auth.d.ts
|
|
1623
|
+
type BasicCredential = {
|
|
1624
|
+
username: string;
|
|
1625
|
+
password: string;
|
|
1626
|
+
};
|
|
1627
|
+
/**
|
|
1628
|
+
* Options for basic-auth interceptors, including a custom credential encoder.
|
|
1629
|
+
*/
|
|
1630
|
+
type BasicAuthInterceptorOptions = {
|
|
1631
|
+
encode?: (credential: BasicCredential) => string;
|
|
1632
|
+
};
|
|
1633
|
+
/**
|
|
1634
|
+
* HTTP interceptor that sets an `Authorization: Basic …` header from credentials.
|
|
1635
|
+
*
|
|
1636
|
+
* @param fn - Factory returning username/password for each request.
|
|
1637
|
+
* @param options - Optional custom encoder (defaults to `btoa`).
|
|
1638
|
+
* @returns An `HttpInterceptor` that injects basic auth.
|
|
1639
|
+
*/
|
|
1640
|
+
export declare function basicAuthHttpInterceptor(fn: () => BasicCredential, options?: BasicAuthInterceptorOptions): HttpInterceptor;
|
|
1641
|
+
/**
|
|
1642
|
+
* SSE interceptor that sets an `Authorization: Basic …` header from credentials.
|
|
1643
|
+
*
|
|
1644
|
+
* @param fn - Factory returning username/password for each request.
|
|
1645
|
+
* @param options - Optional custom encoder (defaults to `btoa`).
|
|
1646
|
+
* @returns An `SSEInterceptor` that injects basic auth.
|
|
1647
|
+
*/
|
|
1648
|
+
export declare function basicAuthSSEInterceptor(fn: () => BasicCredential, options?: BasicAuthInterceptorOptions): SSEInterceptor;
|
|
1649
|
+
//#endregion
|
|
1650
|
+
export type { AnyStruct, BasicAuthInterceptorOptions, BuilderInput, Client, ClientConfig, ClientOption, ClientOptions, ClientSSEConfig, ClientSSEOptions, ClientWebSocketOptions, DecodedResponse, ErrorMap, EventStreamCloseInfo, EventStreamFaultCode, EventStreamHandle, EventStreamOpenInfo, EventStreamRequestShape, FetchHandle, FlattenedStructError, FormattedStructError, HttpInterceptor, HttpInterceptorNext, HttpMeta, HttpProgressEvent, HttpProgressFn, HttpRequest, HttpRequestShape, HttpResponse, HttpResponseType, Infer, Interceptor, InterceptorFn, MakeResponseOptions, ObjectStruct, ParseResult, QuerySerializer, SSEHandler, SSEInterceptor, SSEInterceptorFn, STRUCT, Struct, StructInput, StructIssue, StructLike, StructMethods, WebSocketHandle, WebSocketHandleConstructor, WebSocketHandler, WebSocketInterceptor, WebSocketInterceptorFn, WebSocketRequestShape, WebSocketSessionLike };
|