kinetex 1.2.0 → 1.4.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 +1164 -453
- package/dist/browser/kinetex.esm.js +38 -22
- package/dist/browser/kinetex.js +3127 -715
- package/dist/browser/kinetex.min.js +38 -22
- package/dist/cjs/aws-sigv4.js +137 -20
- package/dist/cjs/cache.js +101 -21
- package/dist/cjs/circuit-breaker.js +69 -7
- package/dist/cjs/client.js +838 -191
- package/dist/cjs/cookie-parser.js +110 -9
- package/dist/cjs/cookie-store.js +141 -36
- package/dist/cjs/core.js +501 -63
- package/dist/cjs/dedup.js +58 -18
- package/dist/cjs/digest.js +185 -23
- package/dist/cjs/graphql.js +164 -24
- package/dist/cjs/headers.js +362 -48
- package/dist/cjs/interceptors.js +285 -29
- package/dist/cjs/lifecycle.js +89 -40
- package/dist/cjs/logging.js +169 -16
- package/dist/cjs/mod.js +3 -2
- package/dist/cjs/pagination.js +261 -28
- package/dist/cjs/progress.js +282 -52
- package/dist/cjs/proxy.js +412 -0
- package/dist/cjs/response.js +316 -47
- package/dist/cjs/socks5.js +167 -36
- package/dist/cjs/sse.js +201 -34
- package/dist/cjs/url.js +191 -45
- package/dist/cjs/utils.js +222 -48
- package/dist/cjs/worker.js +6 -6
- package/dist/cjs/ws.js +32 -16
- package/dist/esm/aws-sigv4.js +137 -20
- package/dist/esm/aws-sigv4.js.map +1 -1
- package/dist/esm/cache.js +101 -21
- package/dist/esm/cache.js.map +1 -1
- package/dist/esm/circuit-breaker.js +69 -7
- package/dist/esm/circuit-breaker.js.map +1 -1
- package/dist/esm/client.js +838 -191
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/cookie-parser.js +110 -9
- package/dist/esm/cookie-parser.js.map +1 -1
- package/dist/esm/cookie-store.js +141 -36
- package/dist/esm/cookie-store.js.map +1 -1
- package/dist/esm/core.js +501 -63
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/dedup.js +58 -18
- package/dist/esm/dedup.js.map +1 -1
- package/dist/esm/digest.js +185 -23
- package/dist/esm/digest.js.map +1 -1
- package/dist/esm/graphql.js +164 -24
- package/dist/esm/graphql.js.map +1 -1
- package/dist/esm/headers.js +362 -48
- package/dist/esm/headers.js.map +1 -1
- package/dist/esm/interceptors.js +285 -29
- package/dist/esm/interceptors.js.map +1 -1
- package/dist/esm/lifecycle.js +89 -40
- package/dist/esm/lifecycle.js.map +1 -1
- package/dist/esm/logging.js +169 -16
- package/dist/esm/logging.js.map +1 -1
- package/dist/esm/mod.js +3 -2
- package/dist/esm/mod.js.map +1 -1
- package/dist/esm/pagination.js +261 -28
- package/dist/esm/pagination.js.map +1 -1
- package/dist/esm/progress.js +282 -52
- package/dist/esm/progress.js.map +1 -1
- package/dist/esm/proxy.js +413 -0
- package/dist/esm/proxy.js.map +1 -0
- package/dist/esm/response.js +316 -47
- package/dist/esm/response.js.map +1 -1
- package/dist/esm/socks5.js +167 -36
- package/dist/esm/socks5.js.map +1 -1
- package/dist/esm/sse.js +201 -34
- package/dist/esm/sse.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/url.js +191 -45
- package/dist/esm/url.js.map +1 -1
- package/dist/esm/utils.js +222 -48
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/worker.js +6 -6
- package/dist/esm/worker.js.map +1 -1
- package/dist/esm/ws.js +32 -16
- package/dist/esm/ws.js.map +1 -1
- package/dist/types/aws-sigv4.d.ts.map +1 -1
- package/dist/types/cache.d.ts +27 -2
- package/dist/types/cache.d.ts.map +1 -1
- package/dist/types/circuit-breaker.d.ts +14 -1
- package/dist/types/circuit-breaker.d.ts.map +1 -1
- package/dist/types/client.d.ts +98 -23
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/cookie-parser.d.ts +0 -17
- package/dist/types/cookie-parser.d.ts.map +1 -1
- package/dist/types/cookie-store.d.ts.map +1 -1
- package/dist/types/core.d.ts +109 -25
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/dedup.d.ts +0 -7
- package/dist/types/dedup.d.ts.map +1 -1
- package/dist/types/digest.d.ts +31 -37
- package/dist/types/digest.d.ts.map +1 -1
- package/dist/types/graphql.d.ts.map +1 -1
- package/dist/types/headers.d.ts +62 -29
- package/dist/types/headers.d.ts.map +1 -1
- package/dist/types/interceptors.d.ts +102 -0
- package/dist/types/interceptors.d.ts.map +1 -1
- package/dist/types/lifecycle.d.ts +19 -2
- package/dist/types/lifecycle.d.ts.map +1 -1
- package/dist/types/logging.d.ts +23 -4
- package/dist/types/logging.d.ts.map +1 -1
- package/dist/types/mod.d.ts +5 -3
- package/dist/types/mod.d.ts.map +1 -1
- package/dist/types/pagination.d.ts +0 -25
- package/dist/types/pagination.d.ts.map +1 -1
- package/dist/types/progress.d.ts +1 -1
- package/dist/types/progress.d.ts.map +1 -1
- package/dist/types/proxy.d.ts +50 -0
- package/dist/types/proxy.d.ts.map +1 -0
- package/dist/types/response.d.ts +7 -1
- package/dist/types/response.d.ts.map +1 -1
- package/dist/types/socks5.d.ts.map +1 -1
- package/dist/types/sse.d.ts.map +1 -1
- package/dist/types/types.d.ts +139 -5
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/url.d.ts +0 -14
- package/dist/types/url.d.ts.map +1 -1
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/types/worker.d.ts +6 -6
- package/dist/types/worker.d.ts.map +1 -1
- package/dist/types/ws.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/cjs/logging.js
CHANGED
|
@@ -120,6 +120,17 @@ const DEFAULT_REDACT_PARAMS = [
|
|
|
120
120
|
* Requests/responses with other content-types will have their body replaced
|
|
121
121
|
* with a short indicator (e.g. "[binary]") instead of being logged verbatim.
|
|
122
122
|
*/
|
|
123
|
+
/**
|
|
124
|
+
* Is this a JSON media type?
|
|
125
|
+
*
|
|
126
|
+
* `application/json` and every `+json` structured suffix, case-insensitively
|
|
127
|
+
* and ignoring parameters, because RFC 9110 makes media types
|
|
128
|
+
* case-insensitive and `application/JSON; charset=utf-8` is the same type.
|
|
129
|
+
*/
|
|
130
|
+
function isJSONContentType(contentType) {
|
|
131
|
+
const type = contentType.split(";", 1)[0].trim().toLowerCase();
|
|
132
|
+
return type === "application/json" || type === "text/json" || type.endsWith("+json");
|
|
133
|
+
}
|
|
123
134
|
const DEFAULT_ALLOWED_BODY_TYPES = [
|
|
124
135
|
"application/json",
|
|
125
136
|
"application/x-www-form-urlencoded",
|
|
@@ -137,12 +148,14 @@ export class ConsoleTransport {
|
|
|
137
148
|
/**
|
|
138
149
|
* @param opts - Console transport options
|
|
139
150
|
*/
|
|
140
|
-
constructor(opts = {
|
|
141
|
-
pretty
|
|
142
|
-
|
|
143
|
-
|
|
151
|
+
constructor(opts = {}) {
|
|
152
|
+
// `pretty` resolves the same way whether the caller passed nothing, `{}`, or
|
|
153
|
+
// a full options object. The old default parameter hard-coded `pretty: false`
|
|
154
|
+
// for the no-argument form only, so `new ConsoleTransport()` emitted JSON
|
|
155
|
+
// while `new ConsoleTransport({ onWrite })` emitted pretty output outside
|
|
156
|
+
// production — the opposite of the documented default.
|
|
144
157
|
this.pretty = opts.pretty ?? getNodeEnv() !== "production";
|
|
145
|
-
this.onWrite = opts.onWrite;
|
|
158
|
+
this.onWrite = opts.onWrite ?? ((output) => console.log(output));
|
|
146
159
|
// useColors reserved for future ANSI colorization
|
|
147
160
|
void opts.useColors;
|
|
148
161
|
}
|
|
@@ -254,6 +267,16 @@ export class BatchingTransport {
|
|
|
254
267
|
}
|
|
255
268
|
/** Internal flush — sends all buffered entries to inner transport. */
|
|
256
269
|
_flush() {
|
|
270
|
+
// A size-triggered flush has to disarm the pending timer as well. Leaving
|
|
271
|
+
// it armed meant `write()`'s `if (!this.timer)` guard stayed false for the
|
|
272
|
+
// next entry, so nothing scheduled a fresh interval: entries written after
|
|
273
|
+
// a full batch waited out the remainder of the previous batch's timer, and a
|
|
274
|
+
// process that hit `maxBatch` and then went quiet held the interval for the
|
|
275
|
+
// whole `flushMs` with an empty buffer.
|
|
276
|
+
if (this.timer !== null) {
|
|
277
|
+
clearTimeout(this.timer);
|
|
278
|
+
this.timer = null;
|
|
279
|
+
}
|
|
257
280
|
if (this.buffer.length === 0)
|
|
258
281
|
return;
|
|
259
282
|
const batch = this.buffer.splice(0);
|
|
@@ -302,6 +325,12 @@ export class RemoteTransport {
|
|
|
302
325
|
}
|
|
303
326
|
/** Fire-and-forget flush with error handling. */
|
|
304
327
|
_flush() {
|
|
328
|
+
// Same disarming as BatchingTransport: a size-triggered flush must not
|
|
329
|
+
// leave the next entry without a timer of its own.
|
|
330
|
+
if (this.timer !== null) {
|
|
331
|
+
clearTimeout(this.timer);
|
|
332
|
+
this.timer = null;
|
|
333
|
+
}
|
|
305
334
|
this._flushAsync().catch(this.options.onError ?? ((err) => console.error("[logging] Flush error:", err)));
|
|
306
335
|
}
|
|
307
336
|
/** Async flush implementation — sends batch via HTTP POST. */
|
|
@@ -439,7 +468,16 @@ export class Redactor {
|
|
|
439
468
|
}
|
|
440
469
|
return out;
|
|
441
470
|
}
|
|
442
|
-
/**
|
|
471
|
+
/**
|
|
472
|
+
* Redact sensitive query parameters from a URL.
|
|
473
|
+
*
|
|
474
|
+
* Absolute URLs go through `URL`, which also normalises the result. A URL the
|
|
475
|
+
* `URL` constructor rejects — every relative form, and relative forms are what
|
|
476
|
+
* `HTTPLogger.child`'s own example logs — used to be returned untouched, so
|
|
477
|
+
* `logRequest(id, "GET", "/users?token=abc", ...)` wrote the token in clear
|
|
478
|
+
* while the absolute spelling of the same request redacted it. Those fall back
|
|
479
|
+
* to a textual scan of the query string below.
|
|
480
|
+
*/
|
|
443
481
|
redactURL(url) {
|
|
444
482
|
try {
|
|
445
483
|
const u = new URL(url);
|
|
@@ -451,9 +489,39 @@ export class Redactor {
|
|
|
451
489
|
return u.toString();
|
|
452
490
|
}
|
|
453
491
|
catch {
|
|
454
|
-
return url;
|
|
492
|
+
return this._redactRelativeQuery(url);
|
|
455
493
|
}
|
|
456
494
|
}
|
|
495
|
+
/** Redact the query string of a URL the `URL` constructor cannot parse. */
|
|
496
|
+
_redactRelativeQuery(url) {
|
|
497
|
+
const q = url.indexOf("?");
|
|
498
|
+
if (q === -1)
|
|
499
|
+
return url;
|
|
500
|
+
const base = url.slice(0, q);
|
|
501
|
+
const rest = url.slice(q + 1);
|
|
502
|
+
const hash = rest.indexOf("#");
|
|
503
|
+
const fragment = hash === -1 ? "" : rest.slice(hash);
|
|
504
|
+
const query = hash === -1 ? rest : rest.slice(0, hash);
|
|
505
|
+
const params = query.split("&").map((pair) => {
|
|
506
|
+
if (pair === "")
|
|
507
|
+
return pair;
|
|
508
|
+
const eq = pair.indexOf("=");
|
|
509
|
+
const name = eq === -1 ? pair : pair.slice(0, eq);
|
|
510
|
+
let decoded = name;
|
|
511
|
+
try {
|
|
512
|
+
decoded = decodeURIComponent(name);
|
|
513
|
+
}
|
|
514
|
+
catch {
|
|
515
|
+
/* keep the raw name if it is not valid percent-encoding */
|
|
516
|
+
}
|
|
517
|
+
if (!this.paramSet.has(decoded.toLowerCase()))
|
|
518
|
+
return pair;
|
|
519
|
+
// A valueless parameter (`?token`) is redacted to `token=***` so the
|
|
520
|
+
// redaction is visible rather than leaving the bare name behind.
|
|
521
|
+
return eq === -1 ? `${name}=***` : `${name}=***`;
|
|
522
|
+
});
|
|
523
|
+
return `${base}?${params.join("&")}${fragment}`;
|
|
524
|
+
}
|
|
457
525
|
/**
|
|
458
526
|
* Redact and optionally truncate a request or response body.
|
|
459
527
|
*
|
|
@@ -470,6 +538,12 @@ export class Redactor {
|
|
|
470
538
|
if (!allowed) {
|
|
471
539
|
return { body: `[${ct || "binary"}]`, size: body ? bodySize(body) : null };
|
|
472
540
|
}
|
|
541
|
+
// The size of the body *as received*, measured before any lossy decoding.
|
|
542
|
+
// Two invalid UTF-8 bytes decode to two U+FFFD characters that re-encode to
|
|
543
|
+
// 6 bytes, and reporting 6 for a 2-byte body is a size of nothing the caller
|
|
544
|
+
// sent. `maxBodyLength` is applied to the re-encoded form below, which is
|
|
545
|
+
// what actually gets written out.
|
|
546
|
+
const size = bodySize(body);
|
|
473
547
|
let str;
|
|
474
548
|
if (body instanceof Uint8Array) {
|
|
475
549
|
try {
|
|
@@ -482,9 +556,14 @@ export class Redactor {
|
|
|
482
556
|
else {
|
|
483
557
|
str = body;
|
|
484
558
|
}
|
|
485
|
-
|
|
486
|
-
//
|
|
487
|
-
|
|
559
|
+
// Redact body fields (JSON). The test has to be at least as wide as the
|
|
560
|
+
// `allowedBodyTypes` gate above: that one uses `startsWith` on a
|
|
561
|
+
// caller-configured list, so a config of `["application/"]` lets a
|
|
562
|
+
// `application/vnd.api+json` body through — and this narrower
|
|
563
|
+
// `includes("application/json")` then logged its `password` field in the
|
|
564
|
+
// clear. `+json` is the registered suffix form (RFC 6839) and this library
|
|
565
|
+
// already parses it as JSON elsewhere, so the redactor has to agree.
|
|
566
|
+
if (isJSONContentType(ct) && this.bodyFields.length > 0) {
|
|
488
567
|
try {
|
|
489
568
|
// FIX (H6): log bodies are untrusted — sanitize before mutation so a
|
|
490
569
|
// crafted payload cannot smuggle __proto__ paths into redaction writes.
|
|
@@ -501,9 +580,12 @@ export class Redactor {
|
|
|
501
580
|
for (const pattern of this.patterns) {
|
|
502
581
|
str = str.replace(pattern, "***");
|
|
503
582
|
}
|
|
504
|
-
// Truncate
|
|
505
|
-
|
|
506
|
-
|
|
583
|
+
// Truncate by UTF-8 bytes, which is the unit `maxBodyLength` is documented
|
|
584
|
+
// in, and never split a multi-byte character in half.
|
|
585
|
+
const afterRedaction = bodySize(str);
|
|
586
|
+
if (afterRedaction > this.maxBody) {
|
|
587
|
+
const cut = truncateToBytes(str, this.maxBody);
|
|
588
|
+
str = `${cut.text}... [truncated ${cut.removed} bytes]`;
|
|
507
589
|
}
|
|
508
590
|
return { body: str, size };
|
|
509
591
|
}
|
|
@@ -512,6 +594,15 @@ export class Redactor {
|
|
|
512
594
|
function redactObjectPath(obj, path) {
|
|
513
595
|
if (!obj || typeof obj !== "object" || path.length === 0)
|
|
514
596
|
return;
|
|
597
|
+
// A JSON array was skipped outright: `bodyFields: ["password"]` only ever
|
|
598
|
+
// matched a top-level key, so a bulk payload — `[{"password":"…"}]`, the
|
|
599
|
+
// shape of most collection endpoints — logged its secrets in clear while
|
|
600
|
+
// the identical object form was redacted. Apply the path to every element.
|
|
601
|
+
if (Array.isArray(obj)) {
|
|
602
|
+
for (const item of obj)
|
|
603
|
+
redactObjectPath(item, path);
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
515
606
|
const [head, ...rest] = path;
|
|
516
607
|
if (head === undefined)
|
|
517
608
|
return;
|
|
@@ -642,6 +733,13 @@ export class HTTPLogger {
|
|
|
642
733
|
const dur = active ? perfNow() - active.startMs : 0;
|
|
643
734
|
const method = active?.method ?? "GET";
|
|
644
735
|
const url = active?.url ?? "";
|
|
736
|
+
// The active ID is released before the filter runs, not after. A response
|
|
737
|
+
// dropped by `statuses` / `level` / `excludeURLs` / sampling returned early
|
|
738
|
+
// and left its entry in `activeIds` forever: the only cleanup is a
|
|
739
|
+
// size-triggered sweep inside `logRequest`, so a service logging with a
|
|
740
|
+
// narrow status filter accumulated one dead entry per request until it
|
|
741
|
+
// reached 10000 and started evicting live ones.
|
|
742
|
+
this.activeIds.delete(requestId);
|
|
645
743
|
if (!this._shouldLog("INFO", method, url, status))
|
|
646
744
|
return;
|
|
647
745
|
const ct = headers["content-type"] ?? headers["Content-Type"] ?? null;
|
|
@@ -665,7 +763,6 @@ export class HTTPLogger {
|
|
|
665
763
|
cached,
|
|
666
764
|
meta: { ...this.cfg.context, ...meta },
|
|
667
765
|
};
|
|
668
|
-
this.activeIds.delete(requestId);
|
|
669
766
|
this._write(entry);
|
|
670
767
|
}
|
|
671
768
|
/**
|
|
@@ -682,6 +779,8 @@ export class HTTPLogger {
|
|
|
682
779
|
const dur = active ? perfNow() - active.startMs : 0;
|
|
683
780
|
const method = active?.method ?? "GET";
|
|
684
781
|
const url = active?.url ?? "";
|
|
782
|
+
// Released before the filter, for the same reason as `logResponse`.
|
|
783
|
+
this.activeIds.delete(requestId);
|
|
685
784
|
if (!this._shouldLog("ERROR", method, url))
|
|
686
785
|
return;
|
|
687
786
|
const entry = {
|
|
@@ -698,7 +797,6 @@ export class HTTPLogger {
|
|
|
698
797
|
attempt,
|
|
699
798
|
meta: { ...this.cfg.context, ...meta },
|
|
700
799
|
};
|
|
701
|
-
this.activeIds.delete(requestId);
|
|
702
800
|
this._write(entry);
|
|
703
801
|
}
|
|
704
802
|
// ── §7.2 ID management ────────────────────────────────────────────────────
|
|
@@ -723,7 +821,7 @@ export class HTTPLogger {
|
|
|
723
821
|
* ```ts
|
|
724
822
|
* const logger = createProductionLogger();
|
|
725
823
|
* const child = logger.child({ requestId: "req-123", userId: "user-456" });
|
|
726
|
-
* child.logRequest(
|
|
824
|
+
* child.logRequest("req-123", "GET", "/users", {}, null, 1); // Logs include both requestId and userId
|
|
727
825
|
* ```
|
|
728
826
|
*/
|
|
729
827
|
child(context) {
|
|
@@ -838,8 +936,63 @@ function serializeError(err) {
|
|
|
838
936
|
...(errStack !== undefined ? { stack: errStack } : {}),
|
|
839
937
|
};
|
|
840
938
|
}
|
|
939
|
+
// Anything else was `String(err)`, which for a rejected object — the shape a
|
|
940
|
+
// custom fetch, a GraphQL client or a worker produces — is literally
|
|
941
|
+
// "[object Object]". The entry recorded no message and no `code`, so the log
|
|
942
|
+
// said only that something had failed. An error-shaped object keeps its
|
|
943
|
+
// `name`, `message`, `code` and `stack`; anything else is stringified
|
|
944
|
+
// structurally.
|
|
945
|
+
if (err !== null && typeof err === "object") {
|
|
946
|
+
const o = err;
|
|
947
|
+
const out = {
|
|
948
|
+
name: typeof o.name === "string" && o.name !== "" ? o.name : "Error",
|
|
949
|
+
message: typeof o.message === "string" ? o.message : safeStringify(err),
|
|
950
|
+
};
|
|
951
|
+
if (typeof o.code === "string" || typeof o.code === "number")
|
|
952
|
+
out.code = String(o.code);
|
|
953
|
+
if (typeof o.stack === "string")
|
|
954
|
+
out.stack = o.stack;
|
|
955
|
+
return out;
|
|
956
|
+
}
|
|
841
957
|
return { name: "Error", message: String(err) };
|
|
842
958
|
}
|
|
959
|
+
/** `JSON.stringify` that never throws — falls back for circular values. */
|
|
960
|
+
function safeStringify(value) {
|
|
961
|
+
try {
|
|
962
|
+
const seen = new WeakSet();
|
|
963
|
+
return (JSON.stringify(value, (_k, v) => {
|
|
964
|
+
if (v !== null && typeof v === "object") {
|
|
965
|
+
if (seen.has(v))
|
|
966
|
+
return "[circular]";
|
|
967
|
+
seen.add(v);
|
|
968
|
+
}
|
|
969
|
+
return v;
|
|
970
|
+
}) ?? String(value));
|
|
971
|
+
}
|
|
972
|
+
catch {
|
|
973
|
+
return String(value);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Truncate a string to at most `maxBytes` UTF-8 bytes, never splitting a
|
|
978
|
+
* character, and report how many bytes were actually removed.
|
|
979
|
+
*/
|
|
980
|
+
function truncateToBytes(str, maxBytes) {
|
|
981
|
+
const enc = new TextEncoder();
|
|
982
|
+
const total = enc.encode(str).byteLength;
|
|
983
|
+
if (total <= maxBytes)
|
|
984
|
+
return { text: str, removed: 0 };
|
|
985
|
+
let used = 0;
|
|
986
|
+
let end = 0;
|
|
987
|
+
for (const ch of str) {
|
|
988
|
+
const width = enc.encode(ch).byteLength;
|
|
989
|
+
if (used + width > maxBytes)
|
|
990
|
+
break;
|
|
991
|
+
used += width;
|
|
992
|
+
end += ch.length;
|
|
993
|
+
}
|
|
994
|
+
return { text: str.slice(0, end), removed: total - used };
|
|
995
|
+
}
|
|
843
996
|
/** Cross-runtime high-resolution timer. Falls back to Date.now() when performance.now() is unavailable. */
|
|
844
997
|
function perfNow() {
|
|
845
998
|
return typeof performance !== "undefined" ? performance.now() : Date.now();
|
package/dist/cjs/mod.js
CHANGED
|
@@ -44,13 +44,13 @@ export { parseCookieDate, getPublicSuffix, getRegistrableDomain, isPublicSuffix,
|
|
|
44
44
|
// core.ts exports
|
|
45
45
|
export { HAS_NATIVE_FETCH, createTransport, parseBody, sendWithTimeout, readRawBody, decompressBodyStream, } from "./core.js";
|
|
46
46
|
// digest.ts exports
|
|
47
|
-
export { parseDigestChallenge, computeDigestResponse, formatDigestAuth, createDigestAuthorization, } from "./digest.js";
|
|
47
|
+
export { parseDigestChallenge, computeDigestResponse, computeUsernameStar, formatDigestAuth, createDigestAuthorization, } from "./digest.js";
|
|
48
48
|
// graphql.ts exports
|
|
49
49
|
export { clearAPQCache, getAPQMetrics, authLink, errorLink, loggingLink, retryLink, } from "./graphql.js";
|
|
50
50
|
// headers.ts exports
|
|
51
51
|
export { HeaderName, formatContentType, parseContentDisposition, formatContentDisposition, parseWWWAuthenticate, formatBearer, formatBasic, parseAccept, parseAcceptEncoding, parseAcceptLanguage, negotiateContentType, parseRange, parseContentRange, formatLinkHeader, parseForwarded, normalizeForwardedHeaders, getClientIP, parseRetryAfter, parseHSTS, formatHSTS, parseCSP, formatCSP, parseServerTiming, formatServerTiming, parseAltSvc, parseContentLanguage, parseWarning, parseParams, fromNodeHeaders, toNodeHeaders, fromWebHeaders, securityHeaders, corsHeaders, RichHeaders, createHeaders, createRequestHeaders, createResponseHeaders, createImmutableHeaders, } from "./headers.js";
|
|
52
52
|
// interceptors.ts exports
|
|
53
|
-
export { createRetryInterceptor, createAuthInterceptor, createTimeoutInterceptor, createLoggingInterceptor, createCacheInterceptor, createDedupeInterceptor, createRateLimitInterceptor, RateLimitError, createHARInterceptor, createMetricsInterceptor, createInterceptorSuite, computeBodySize, } from "./interceptors.js";
|
|
53
|
+
export { createRetryInterceptor, createAuthInterceptor, createTimeoutInterceptor, createLoggingInterceptor, createCacheInterceptor, createDedupeInterceptor, createRateLimitInterceptor, RateLimitError, ConcurrencyLimiter, CONCURRENCY_DEFAULTS, ConcurrencyLimitError, createHARInterceptor, createMetricsInterceptor, createInterceptorSuite, computeBodySize, } from "./interceptors.js";
|
|
54
54
|
// lifecycle.ts exports
|
|
55
55
|
export { RedirectTracker, TooManyRedirectsError, tap, injectHeaders, withBaseURL, throwOnHTTPError, validateResponse, HTTPError, ResponseValidationError, composeBeforeRequest, composeBeforeResponse, composeAround, createLoggingHooks, createTimingHook, createBodyNormalizationHook, createAbortHook, createHookContext, } from "./lifecycle.js";
|
|
56
56
|
// logging.ts exports
|
|
@@ -94,5 +94,6 @@ export { InterceptorManager } from "./interceptors.js";
|
|
|
94
94
|
export { HookRegistry, HookEmitter } from "./lifecycle.js";
|
|
95
95
|
export { CircuitBreaker, CircuitBreakerRegistry, CircuitOpenError, createCircuitBreaker, createCircuitBreakerRegistry, } from "./circuit-breaker.js";
|
|
96
96
|
export { DedupMap, createDedupMap } from "./dedup.js";
|
|
97
|
+
export { generateIdempotencyKey, isValidIdempotencyKey } from "./headers.js";
|
|
97
98
|
// ── Utilities ────────────────────────────────────────────────────────────────
|
|
98
99
|
export { safeJSONParse, tryParseJSON, parseUntrustedJSON, sanitizeParsedJSON, isUint8Array, isArrayBuffer, isReadableStream, isHeaders, isAbortSignal, isPlainObject, isFormData, isBlob, isURLSearchParams, isValidHeaderName, isValidHeaderValue, isSafeURL, sanitizeURL, createStructuredError, formatError, perfNow, sleep, concatUint8Arrays, toUint8Array, uint8ArrayToBase64, deepClone, normalizeHeaders, mergeSignals, isAbortError, getRuntime, isNodeEnvironment, isBrowserEnvironment, hasNativeFetch, } from "./utils.js";
|