arthron 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -50
- package/dist/index-C3lylSNd.d.cts +333 -0
- package/dist/index-C3lylSNd.d.mts +333 -0
- package/dist/index.cjs +67 -697
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -240
- package/dist/index.d.mts +16 -240
- package/dist/index.mjs +54 -684
- package/dist/index.mjs.map +1 -1
- package/dist/plugins-CHCMxtAE.mjs +1166 -0
- package/dist/plugins-CHCMxtAE.mjs.map +1 -0
- package/dist/plugins-Cigqz2SS.cjs +1279 -0
- package/dist/plugins-Cigqz2SS.cjs.map +1 -0
- package/dist/plugins.cjs +7 -0
- package/dist/plugins.d.cts +2 -0
- package/dist/plugins.d.mts +2 -0
- package/dist/plugins.mjs +1 -0
- package/llms.txt +15 -15
- package/package.json +12 -1
- package/plugins/package.json +6 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,169 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* What plugins see and return. `init.headers` is always a plain record with
|
|
4
|
-
* lowercased names — spread it, read it, add to it — and the pipeline puts
|
|
5
|
-
* it back into that shape after every request interceptor.
|
|
6
|
-
*/
|
|
7
|
-
interface RequestContext {
|
|
8
|
-
url: string;
|
|
9
|
-
init: Omit<RequestInit, "headers"> & {
|
|
10
|
-
headers: Record<string, string>;
|
|
11
|
-
};
|
|
12
|
-
/** Per-call settings for plugins (`RequestOptions.meta`); never sent. */
|
|
13
|
-
meta: ArthronMeta;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Per-call settings for plugins, passed as `api.get(path, { meta })` and
|
|
17
|
-
* carried next to `init` — never sent to fetch. The built-in plugins read
|
|
18
|
-
* `retry` and `timeout`; your own add keys by augmentation:
|
|
19
|
-
*
|
|
20
|
-
* ```ts
|
|
21
|
-
* declare module "arthron" {
|
|
22
|
-
* interface ArthronMeta { skipAuth?: boolean }
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
interface ArthronMeta {
|
|
27
|
-
/** `false` turns `retry()` off for this call; an object overrides its options. */
|
|
28
|
-
retry?: false | Omit<RetryOptions, "sleep">;
|
|
29
|
-
/** Deadline for this call in ms, overriding `timeout(ms)`. `Infinity` lifts it. */
|
|
30
|
-
timeout?: number;
|
|
31
|
-
}
|
|
32
|
-
type RetryOptions = {
|
|
33
|
-
/** Number of retries after the first attempt. Default 2 (3 requests total). */
|
|
34
|
-
retries?: number;
|
|
35
|
-
/** Statuses worth retrying. Network errors (status 0) always are. */
|
|
36
|
-
retryOn?: readonly number[];
|
|
37
|
-
/** Methods safe to repeat (QUERY is, per RFC 10008). Compared case-insensitively. */
|
|
38
|
-
methods?: readonly string[];
|
|
39
|
-
/**
|
|
40
|
-
* Backoff in ms for retry number `retry` (0-based). Default "full jitter":
|
|
41
|
-
* a random share of 300 · 2^retry, so clients that failed together do not
|
|
42
|
-
* retry together.
|
|
43
|
-
*/
|
|
44
|
-
delay?: (retry: number, error: unknown) => number;
|
|
45
|
-
/**
|
|
46
|
-
* Your own verdict on one failure: `true` retries, `false` stops,
|
|
47
|
-
* `undefined` leaves it to `retryOn`/`methods`. It sees every error — a
|
|
48
|
-
* TimeoutError from a `timeout()` placed after `retry()` included — but
|
|
49
|
-
* cannot exceed `retries`, resend a `ReadableStream` body, or retry a call
|
|
50
|
-
* the caller aborted.
|
|
51
|
-
*/
|
|
52
|
-
shouldRetry?: (error: unknown, attempt: number, ctx: RequestContext) => boolean | undefined;
|
|
53
|
-
/** Called before each wait, for logs and metrics. */
|
|
54
|
-
onRetry?: (error: unknown, attempt: number, waitMs: number) => void;
|
|
55
|
-
/** Injectable for tests. Default `setTimeout`; rejects with the abort reason. */
|
|
56
|
-
sleep?: (ms: number, signal?: AbortSignal | null) => Promise<void>;
|
|
57
|
-
/**
|
|
58
|
-
* Longest `Retry-After` (ms) worth honouring. Beyond it the request is not
|
|
59
|
-
* retried at all. Default 60 000.
|
|
60
|
-
*/
|
|
61
|
-
maxRetryAfter?: number;
|
|
62
|
-
};
|
|
63
|
-
type QueryValue = string | number | boolean | null | undefined;
|
|
64
|
-
/**
|
|
65
|
-
* Query parameters. `null`/`undefined` values are skipped, an array becomes
|
|
66
|
-
* repeated keys (`ids=1&ids=2`), and a `URLSearchParams` is used as is.
|
|
67
|
-
*/
|
|
68
|
-
type QueryParams = Record<string, QueryValue | readonly QueryValue[]> | URLSearchParams;
|
|
69
|
-
/**
|
|
70
|
-
* Headers as config and per-call options accept them: anything fetch's
|
|
71
|
-
* `headers` takes, or a plain object whose `null`/`undefined` values delete
|
|
72
|
-
* that header from the layer underneath (a client default, an inherited
|
|
73
|
-
* header). Not spelled `HeadersInit`: that name exists only in the DOM lib,
|
|
74
|
-
* and a Node project typed with `@types/node` alone does not have it.
|
|
75
|
-
*/
|
|
76
|
-
type HeadersOption = NonNullable<RequestInit["headers"]> | Record<string, string | null | undefined>;
|
|
77
|
-
//#endregion
|
|
78
|
-
//#region src/error/arthron-error.d.ts
|
|
79
|
-
type ArthronErrorInit = {
|
|
80
|
-
message: string;
|
|
81
|
-
status: number;
|
|
82
|
-
statusText: string;
|
|
83
|
-
headers: Headers;
|
|
84
|
-
data: unknown;
|
|
85
|
-
detail?: string | undefined;
|
|
86
|
-
request: RequestContext;
|
|
87
|
-
response?: Response;
|
|
88
|
-
cause?: unknown;
|
|
89
|
-
};
|
|
90
|
-
/**
|
|
91
|
-
* The only error arthron itself produces. Two sources: a response with
|
|
92
|
-
* `ok === false`, or fetch rejecting outright (network failure, `status` 0).
|
|
93
|
-
* Everything else — cancellation, interceptor bugs — is rethrown untouched.
|
|
94
|
-
*/
|
|
95
|
-
export declare class ArthronError extends Error {
|
|
96
|
-
readonly name = "ArthronError";
|
|
97
|
-
/** HTTP status of the failed response; `0` when fetch itself failed (network). */
|
|
98
|
-
readonly status: number;
|
|
99
|
-
readonly statusText: string;
|
|
100
|
-
/** Response headers; empty for network failures. Not enumerable — kept out of logs. */
|
|
101
|
-
readonly headers: Headers;
|
|
102
|
-
/** Parsed body: JSON if it parses, else the text, else `undefined`. */
|
|
103
|
-
readonly data: unknown;
|
|
104
|
-
/**
|
|
105
|
-
* The server's own explanation, picked out of `data` (by default
|
|
106
|
-
* `message` → `error` → `error.message` → `detail`; see the `errorDetail`
|
|
107
|
-
* config). `undefined` when the body had none. Untrusted server text: show
|
|
108
|
-
* it to users as text, never as HTML. `message`, by contrast, is written by
|
|
109
|
-
* arthron — method, URL without query, status — and is meant for logs.
|
|
110
|
-
*/
|
|
111
|
-
readonly detail: string | undefined;
|
|
112
|
-
/**
|
|
113
|
-
* The context that was sent — url and init after request interceptors.
|
|
114
|
-
* Not enumerable: it holds credentials, so `JSON.stringify`, `console.error`
|
|
115
|
-
* and error trackers leave it out. Read it directly when you need it.
|
|
116
|
-
*/
|
|
117
|
-
readonly request: RequestContext;
|
|
118
|
-
/** The failed Response, still readable — its body holds what arthron read (at most 64 KiB). Absent for network failures. Not enumerable. */
|
|
119
|
-
readonly response: Response | undefined;
|
|
120
|
-
/** The underlying error for network failures. */
|
|
121
|
-
readonly cause: unknown;
|
|
122
|
-
constructor(init: ArthronErrorInit);
|
|
123
|
-
/** `instanceof ArthronError` holds for an error from any copy of the package. */
|
|
124
|
-
static [Symbol.hasInstance](value: unknown): boolean;
|
|
125
|
-
/** What serializers see: no headers, no body, no query or userinfo. */
|
|
126
|
-
toJSON(): {
|
|
127
|
-
name: string;
|
|
128
|
-
message: string;
|
|
129
|
-
detail: string | undefined;
|
|
130
|
-
status: number;
|
|
131
|
-
statusText: string;
|
|
132
|
-
method: string;
|
|
133
|
-
url: string;
|
|
134
|
-
data: unknown;
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
/** `true` for errors arthron produced: a `!ok` response or a network failure. Cancellations and plugin bugs are not ArthronErrors. */
|
|
138
|
-
export declare function isArthronError(error: unknown): error is ArthronError;
|
|
139
|
-
//#endregion
|
|
140
|
-
//#region src/types/plugin.types.d.ts
|
|
141
|
-
/** Runs before each attempt. Returns the context to send (may be a new object). */
|
|
142
|
-
type RequestInterceptor = (ctx: RequestContext) => RequestContext | Promise<RequestContext>;
|
|
143
|
-
/** Runs after a successful attempt. The body is single-use — `clone()` to peek. */
|
|
144
|
-
type ResponseInterceptor = (res: Response, ctx: RequestContext) => Response | Promise<Response>;
|
|
145
|
-
/** Runs after a failed attempt. Returns the error to throw; it is always thrown. */
|
|
146
|
-
type ErrorInterceptor = (err: ArthronError, ctx: RequestContext) => ArthronError | Promise<ArthronError>;
|
|
147
|
-
/**
|
|
148
|
-
* Wraps the whole call. `next` runs everything below it (request interceptors →
|
|
149
|
-
* fetch → response/error interceptors) and may be called again to retry.
|
|
150
|
-
* `next` rejects with an `ArthronError`, or with the untouched original when the
|
|
151
|
-
* failure was a cancellation or a bug in a plugin.
|
|
152
|
-
*/
|
|
153
|
-
type Middleware = (ctx: RequestContext, next: (ctx: RequestContext) => Promise<Response>) => Promise<Response>;
|
|
154
|
-
interface Plugin {
|
|
155
|
-
/**
|
|
156
|
-
* Identity within a client: `use`/`extend` replace the plugin of the same
|
|
157
|
-
* name in place, `without(name)` removes it. The built-ins are named
|
|
158
|
-
* "retry", "timeout" and "logging". Leave it out to always append.
|
|
159
|
-
*/
|
|
160
|
-
name?: string;
|
|
161
|
-
middleware?: Middleware;
|
|
162
|
-
request?: RequestInterceptor;
|
|
163
|
-
response?: ResponseInterceptor;
|
|
164
|
-
error?: ErrorInterceptor;
|
|
165
|
-
}
|
|
166
|
-
//#endregion
|
|
1
|
+
import { _ as ArthronMeta, a as logging$1, b as RequestContext, d as Middleware, f as Plugin, g as isArthronError, h as ArthronError, i as retry$1, m as ResponseInterceptor, n as timeout$1, o as LogEvent$1, p as RequestInterceptor, r as TimeoutOptions$1, s as LoggingOptions$1, u as ErrorInterceptor, v as HeadersOption, x as RetryOptions, y as QueryParams } from "./index-C3lylSNd.mjs";
|
|
167
2
|
//#region src/types/response.types.d.ts
|
|
168
3
|
interface ArthronPromise extends Promise<Response> {
|
|
169
4
|
/** The body as JSON. `T` is a cast — nothing checks it. */
|
|
@@ -355,79 +190,6 @@ export declare const defineInterceptor: {
|
|
|
355
190
|
/** Identity helper: type-checks a plugin object literal without an annotation. */
|
|
356
191
|
export declare const definePlugin: (plugin: Plugin) => Plugin;
|
|
357
192
|
//#endregion
|
|
358
|
-
//#region src/plugins/logging/logging.types.d.ts
|
|
359
|
-
type LogEventBase = {
|
|
360
|
-
method: string;
|
|
361
|
-
path: string;
|
|
362
|
-
};
|
|
363
|
-
type LogEvent = ({
|
|
364
|
-
phase: "start";
|
|
365
|
-
} & LogEventBase) | ({
|
|
366
|
-
phase: "success";
|
|
367
|
-
status: number;
|
|
368
|
-
ms: number;
|
|
369
|
-
} & LogEventBase) | ({
|
|
370
|
-
phase: "error";
|
|
371
|
-
/** HTTP status for an ArthronError (0 = network); undefined for anything else. */
|
|
372
|
-
status: number | undefined;
|
|
373
|
-
ms: number;
|
|
374
|
-
error: unknown;
|
|
375
|
-
} & LogEventBase);
|
|
376
|
-
type LoggingOptions = {
|
|
377
|
-
/** Default `true`. The library never reads `NODE_ENV` — pass `isDev` yourself. */
|
|
378
|
-
enabled?: boolean;
|
|
379
|
-
logger?: Pick<Console, "log" | "error">;
|
|
380
|
-
/** Receive structured events instead of the default console lines. */
|
|
381
|
-
onEvent?: (event: LogEvent) => void;
|
|
382
|
-
/** Clock in ms. Injectable for tests. */
|
|
383
|
-
now?: () => number;
|
|
384
|
-
};
|
|
385
|
-
//#endregion
|
|
386
|
-
//#region src/plugins/logging/logging.d.ts
|
|
387
|
-
/**
|
|
388
|
-
* One event when a request starts, one when it settles, with status and
|
|
389
|
-
* elapsed time. Wraps the whole call, so retries are included in the time.
|
|
390
|
-
* Default output is a console line per event; pass `onEvent` to get the
|
|
391
|
-
* structured event instead. Cancellations are not reported.
|
|
392
|
-
*/
|
|
393
|
-
export declare function logging(options?: LoggingOptions): Plugin;
|
|
394
|
-
//#endregion
|
|
395
|
-
//#region src/plugins/retry/retry.d.ts
|
|
396
|
-
/**
|
|
397
|
-
* Retry on network errors and the configured statuses by calling `next`
|
|
398
|
-
* again — the whole attempt (request interceptors included) is re-run.
|
|
399
|
-
* Only `ArthronError` is considered; cancellation and plugin bugs pass through.
|
|
400
|
-
* A call can turn it off or override its options with `meta.retry`.
|
|
401
|
-
*/
|
|
402
|
-
export declare function retry(options?: RetryOptions): Plugin;
|
|
403
|
-
//#endregion
|
|
404
|
-
//#region src/plugins/timeout/timeout.types.d.ts
|
|
405
|
-
type TimeoutOptions = {
|
|
406
|
-
/**
|
|
407
|
-
* Also abort when no data has arrived for this many ms — while waiting for
|
|
408
|
-
* the headers and between body chunks. Unlike the total deadline, a stream
|
|
409
|
-
* that keeps flowing is never cut off: `timeout(Infinity, { idle: 30_000 })`.
|
|
410
|
-
*/
|
|
411
|
-
idle?: number;
|
|
412
|
-
};
|
|
413
|
-
//#endregion
|
|
414
|
-
//#region src/plugins/timeout/timeout.d.ts
|
|
415
|
-
/**
|
|
416
|
-
* Abort the request when it takes longer than `ms` — counted from the start
|
|
417
|
-
* of the attempt until the body has been fully read, so a server that sends
|
|
418
|
-
* headers and then stalls still trips it. With `idle`, also abort once no
|
|
419
|
-
* data has arrived for that long. Rejects with a `TimeoutError` (a
|
|
420
|
-
* `DOMException`, like `AbortSignal.timeout()` would give); it is not an
|
|
421
|
-
* `ArthronError`, so error interceptors and `retry` leave it alone.
|
|
422
|
-
*
|
|
423
|
-
* A call can change the total deadline with `meta.timeout`.
|
|
424
|
-
*
|
|
425
|
-
* Deadlines are timers on an AbortController — not `AbortSignal.timeout`,
|
|
426
|
-
* since the idle one restarts — joined to the caller's signal with
|
|
427
|
-
* `AbortSignal.any`.
|
|
428
|
-
*/
|
|
429
|
-
export declare function timeout(ms: number, options?: TimeoutOptions): Plugin;
|
|
430
|
-
//#endregion
|
|
431
193
|
//#region src/response/schema-validation.d.ts
|
|
432
194
|
/**
|
|
433
195
|
* `.json(schema)` got a body that does not match. Not an ArthronError: the
|
|
@@ -440,5 +202,19 @@ export declare class SchemaError extends Error {
|
|
|
440
202
|
constructor(issues: readonly SchemaIssue[]);
|
|
441
203
|
}
|
|
442
204
|
//#endregion
|
|
443
|
-
|
|
205
|
+
//#region src/index.d.ts
|
|
206
|
+
/** @deprecated Import from "arthron/plugins"; this export goes in the next major. */
|
|
207
|
+
export declare const logging: typeof logging$1;
|
|
208
|
+
/** @deprecated Import from "arthron/plugins"; this export goes in the next major. */
|
|
209
|
+
export declare const retry: typeof retry$1;
|
|
210
|
+
/** @deprecated Import from "arthron/plugins"; this export goes in the next major. */
|
|
211
|
+
export declare const timeout: typeof timeout$1;
|
|
212
|
+
/** @deprecated Import from "arthron/plugins"; this export goes in the next major. */
|
|
213
|
+
export type LogEvent = LogEvent$1;
|
|
214
|
+
/** @deprecated Import from "arthron/plugins"; this export goes in the next major. */
|
|
215
|
+
export type LoggingOptions = LoggingOptions$1;
|
|
216
|
+
/** @deprecated Import from "arthron/plugins"; this export goes in the next major. */
|
|
217
|
+
export type TimeoutOptions = TimeoutOptions$1;
|
|
218
|
+
//#endregion
|
|
219
|
+
export { type Arthron, type ArthronConfig, ArthronError, type ArthronMeta, type ArthronPromise, type ErrorDetailResolver, type ErrorInterceptor, type HeadersOption, type HttpMethod, type InferOutput, type Middleware, type NdjsonOptions, type Plugin, type QueryParams, type RequestContext, type RequestInitWithBody, type RequestInterceptor, type RequestOptions, type ResponseInterceptor, type RetryOptions, type SchemaIssue, type SseEvent, type SseOptions, type StandardSchemaV1, isArthronError };
|
|
444
220
|
//# sourceMappingURL=index.d.mts.map
|