kinetex 1.3.0 → 1.5.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 +413 -52
- package/dist/browser/kinetex.esm.js +38 -22
- package/dist/browser/kinetex.js +3134 -787
- package/dist/browser/kinetex.min.js +38 -22
- package/dist/cjs/aws-sigv4.js +140 -33
- package/dist/cjs/cache.js +58 -7
- package/dist/cjs/circuit-breaker.js +53 -4
- package/dist/cjs/client.js +726 -188
- package/dist/cjs/cookie-parser.js +131 -6
- package/dist/cjs/cookie-store.js +125 -28
- package/dist/cjs/core.js +691 -70
- package/dist/cjs/dedup.js +142 -21
- package/dist/cjs/digest.js +195 -38
- package/dist/cjs/graphql.js +166 -35
- package/dist/cjs/headers.js +327 -46
- package/dist/cjs/interceptors.js +227 -24
- package/dist/cjs/lifecycle.js +92 -59
- package/dist/cjs/logging.js +160 -24
- package/dist/cjs/mod.js +3 -2
- package/dist/cjs/pagination.js +247 -22
- package/dist/cjs/progress.js +178 -30
- package/dist/cjs/proxy.js +429 -0
- package/dist/cjs/response.js +506 -110
- package/dist/cjs/socks5.js +136 -15
- package/dist/cjs/sse.js +173 -43
- package/dist/cjs/url.js +191 -45
- package/dist/cjs/utils.js +335 -73
- package/dist/cjs/ws.js +62 -12
- package/dist/esm/aws-sigv4.js +140 -33
- package/dist/esm/aws-sigv4.js.map +1 -1
- package/dist/esm/cache.js +58 -7
- package/dist/esm/cache.js.map +1 -1
- package/dist/esm/circuit-breaker.js +53 -4
- package/dist/esm/circuit-breaker.js.map +1 -1
- package/dist/esm/client.js +726 -188
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/cookie-parser.js +131 -6
- package/dist/esm/cookie-parser.js.map +1 -1
- package/dist/esm/cookie-store.js +125 -28
- package/dist/esm/cookie-store.js.map +1 -1
- package/dist/esm/core.js +691 -70
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/dedup.js +142 -21
- package/dist/esm/dedup.js.map +1 -1
- package/dist/esm/digest.js +195 -38
- package/dist/esm/digest.js.map +1 -1
- package/dist/esm/graphql.js +166 -35
- package/dist/esm/graphql.js.map +1 -1
- package/dist/esm/headers.js +327 -46
- package/dist/esm/headers.js.map +1 -1
- package/dist/esm/interceptors.js +227 -24
- package/dist/esm/interceptors.js.map +1 -1
- package/dist/esm/lifecycle.js +92 -59
- package/dist/esm/lifecycle.js.map +1 -1
- package/dist/esm/logging.js +160 -24
- 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 +247 -22
- package/dist/esm/pagination.js.map +1 -1
- package/dist/esm/progress.js +178 -30
- package/dist/esm/progress.js.map +1 -1
- package/dist/esm/proxy.js +430 -0
- package/dist/esm/proxy.js.map +1 -0
- package/dist/esm/response.js +506 -110
- package/dist/esm/response.js.map +1 -1
- package/dist/esm/socks5.js +136 -15
- package/dist/esm/socks5.js.map +1 -1
- package/dist/esm/sse.js +173 -43
- 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 +335 -73
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/ws.js +62 -12
- package/dist/esm/ws.js.map +1 -1
- package/dist/types/aws-sigv4.d.ts.map +1 -1
- package/dist/types/cache.d.ts +19 -1
- package/dist/types/cache.d.ts.map +1 -1
- package/dist/types/circuit-breaker.d.ts +15 -2
- package/dist/types/circuit-breaker.d.ts.map +1 -1
- package/dist/types/client.d.ts +69 -11
- 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 +216 -25
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/dedup.d.ts +38 -3
- package/dist/types/dedup.d.ts.map +1 -1
- package/dist/types/digest.d.ts +17 -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 +68 -31
- package/dist/types/headers.d.ts.map +1 -1
- package/dist/types/interceptors.d.ts +126 -38
- 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 +22 -3
- 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 +49 -2
- 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 +219 -26
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/url.d.ts +0 -25
- package/dist/types/url.d.ts.map +1 -1
- package/dist/types/utils.d.ts +69 -1
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/types/ws.d.ts +0 -1
- package/dist/types/ws.d.ts.map +1 -1
- package/package.json +10 -4
package/dist/cjs/logging.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
// FIX (H6): logged bodies are untrusted — parsed JSON is stripped of
|
|
29
29
|
// prototype-pollution keys before redaction writes (see sanitizeParsedJSON).
|
|
30
|
-
import { sanitizeParsedJSON } from "./utils.js";
|
|
30
|
+
import { sanitizeParsedJSON, perfNow, redactHeaders, safeStringify as stringifySafely, } from "./utils.js";
|
|
31
31
|
// Cross-runtime: safely detect Node.js process.env
|
|
32
32
|
const getNodeEnv = () => {
|
|
33
33
|
try {
|
|
@@ -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. */
|
|
@@ -433,13 +462,18 @@ export class Redactor {
|
|
|
433
462
|
}
|
|
434
463
|
/** Redact sensitive header values, replacing them with "***". */
|
|
435
464
|
redactHeaders(headers) {
|
|
436
|
-
|
|
437
|
-
for (const [k, v] of Object.entries(headers)) {
|
|
438
|
-
out[k] = this.headerSet.has(k.toLowerCase()) ? "***" : v;
|
|
439
|
-
}
|
|
440
|
-
return out;
|
|
465
|
+
return redactHeaders(headers, this.headerSet, "***");
|
|
441
466
|
}
|
|
442
|
-
/**
|
|
467
|
+
/**
|
|
468
|
+
* Redact sensitive query parameters from a URL.
|
|
469
|
+
*
|
|
470
|
+
* Absolute URLs go through `URL`, which also normalises the result. A URL the
|
|
471
|
+
* `URL` constructor rejects — every relative form, and relative forms are what
|
|
472
|
+
* `HTTPLogger.child`'s own example logs — used to be returned untouched, so
|
|
473
|
+
* `logRequest(id, "GET", "/users?token=abc", ...)` wrote the token in clear
|
|
474
|
+
* while the absolute spelling of the same request redacted it. Those fall back
|
|
475
|
+
* to a textual scan of the query string below.
|
|
476
|
+
*/
|
|
443
477
|
redactURL(url) {
|
|
444
478
|
try {
|
|
445
479
|
const u = new URL(url);
|
|
@@ -451,9 +485,41 @@ export class Redactor {
|
|
|
451
485
|
return u.toString();
|
|
452
486
|
}
|
|
453
487
|
catch {
|
|
454
|
-
return url;
|
|
488
|
+
return this._redactRelativeQuery(url);
|
|
455
489
|
}
|
|
456
490
|
}
|
|
491
|
+
/** Redact the query string of a URL the `URL` constructor cannot parse. */
|
|
492
|
+
_redactRelativeQuery(url) {
|
|
493
|
+
const q = url.indexOf("?");
|
|
494
|
+
if (q === -1)
|
|
495
|
+
return url;
|
|
496
|
+
const base = url.slice(0, q);
|
|
497
|
+
const rest = url.slice(q + 1);
|
|
498
|
+
const hash = rest.indexOf("#");
|
|
499
|
+
const fragment = hash === -1 ? "" : rest.slice(hash);
|
|
500
|
+
const query = hash === -1 ? rest : rest.slice(0, hash);
|
|
501
|
+
const params = query.split("&").map((pair) => {
|
|
502
|
+
if (pair === "")
|
|
503
|
+
return pair;
|
|
504
|
+
const eq = pair.indexOf("=");
|
|
505
|
+
const name = eq === -1 ? pair : pair.slice(0, eq);
|
|
506
|
+
let decoded = name;
|
|
507
|
+
try {
|
|
508
|
+
decoded = decodeURIComponent(name);
|
|
509
|
+
}
|
|
510
|
+
catch {
|
|
511
|
+
/* keep the raw name if it is not valid percent-encoding */
|
|
512
|
+
}
|
|
513
|
+
if (!this.paramSet.has(decoded.toLowerCase()))
|
|
514
|
+
return pair;
|
|
515
|
+
// A valueless parameter (`?token`) is redacted to `token=***` rather than
|
|
516
|
+
// left as the bare name, so the redaction stays visible. The value, when
|
|
517
|
+
// there is one, is discarded either way — which is why this used to be
|
|
518
|
+
// written as a ternary whose two arms were the same string.
|
|
519
|
+
return `${name}=***`;
|
|
520
|
+
});
|
|
521
|
+
return `${base}?${params.join("&")}${fragment}`;
|
|
522
|
+
}
|
|
457
523
|
/**
|
|
458
524
|
* Redact and optionally truncate a request or response body.
|
|
459
525
|
*
|
|
@@ -470,6 +536,12 @@ export class Redactor {
|
|
|
470
536
|
if (!allowed) {
|
|
471
537
|
return { body: `[${ct || "binary"}]`, size: body ? bodySize(body) : null };
|
|
472
538
|
}
|
|
539
|
+
// The size of the body *as received*, measured before any lossy decoding.
|
|
540
|
+
// Two invalid UTF-8 bytes decode to two U+FFFD characters that re-encode to
|
|
541
|
+
// 6 bytes, and reporting 6 for a 2-byte body is a size of nothing the caller
|
|
542
|
+
// sent. `maxBodyLength` is applied to the re-encoded form below, which is
|
|
543
|
+
// what actually gets written out.
|
|
544
|
+
const size = bodySize(body);
|
|
473
545
|
let str;
|
|
474
546
|
if (body instanceof Uint8Array) {
|
|
475
547
|
try {
|
|
@@ -482,9 +554,14 @@ export class Redactor {
|
|
|
482
554
|
else {
|
|
483
555
|
str = body;
|
|
484
556
|
}
|
|
485
|
-
|
|
486
|
-
//
|
|
487
|
-
|
|
557
|
+
// Redact body fields (JSON). The test has to be at least as wide as the
|
|
558
|
+
// `allowedBodyTypes` gate above: that one uses `startsWith` on a
|
|
559
|
+
// caller-configured list, so a config of `["application/"]` lets a
|
|
560
|
+
// `application/vnd.api+json` body through — and this narrower
|
|
561
|
+
// `includes("application/json")` then logged its `password` field in the
|
|
562
|
+
// clear. `+json` is the registered suffix form (RFC 6839) and this library
|
|
563
|
+
// already parses it as JSON elsewhere, so the redactor has to agree.
|
|
564
|
+
if (isJSONContentType(ct) && this.bodyFields.length > 0) {
|
|
488
565
|
try {
|
|
489
566
|
// FIX (H6): log bodies are untrusted — sanitize before mutation so a
|
|
490
567
|
// crafted payload cannot smuggle __proto__ paths into redaction writes.
|
|
@@ -501,9 +578,12 @@ export class Redactor {
|
|
|
501
578
|
for (const pattern of this.patterns) {
|
|
502
579
|
str = str.replace(pattern, "***");
|
|
503
580
|
}
|
|
504
|
-
// Truncate
|
|
505
|
-
|
|
506
|
-
|
|
581
|
+
// Truncate by UTF-8 bytes, which is the unit `maxBodyLength` is documented
|
|
582
|
+
// in, and never split a multi-byte character in half.
|
|
583
|
+
const afterRedaction = bodySize(str);
|
|
584
|
+
if (afterRedaction > this.maxBody) {
|
|
585
|
+
const cut = truncateToBytes(str, this.maxBody);
|
|
586
|
+
str = `${cut.text}... [truncated ${cut.removed} bytes]`;
|
|
507
587
|
}
|
|
508
588
|
return { body: str, size };
|
|
509
589
|
}
|
|
@@ -512,6 +592,15 @@ export class Redactor {
|
|
|
512
592
|
function redactObjectPath(obj, path) {
|
|
513
593
|
if (!obj || typeof obj !== "object" || path.length === 0)
|
|
514
594
|
return;
|
|
595
|
+
// A JSON array was skipped outright: `bodyFields: ["password"]` only ever
|
|
596
|
+
// matched a top-level key, so a bulk payload — `[{"password":"…"}]`, the
|
|
597
|
+
// shape of most collection endpoints — logged its secrets in clear while
|
|
598
|
+
// the identical object form was redacted. Apply the path to every element.
|
|
599
|
+
if (Array.isArray(obj)) {
|
|
600
|
+
for (const item of obj)
|
|
601
|
+
redactObjectPath(item, path);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
515
604
|
const [head, ...rest] = path;
|
|
516
605
|
if (head === undefined)
|
|
517
606
|
return;
|
|
@@ -642,6 +731,13 @@ export class HTTPLogger {
|
|
|
642
731
|
const dur = active ? perfNow() - active.startMs : 0;
|
|
643
732
|
const method = active?.method ?? "GET";
|
|
644
733
|
const url = active?.url ?? "";
|
|
734
|
+
// The active ID is released before the filter runs, not after. A response
|
|
735
|
+
// dropped by `statuses` / `level` / `excludeURLs` / sampling returned early
|
|
736
|
+
// and left its entry in `activeIds` forever: the only cleanup is a
|
|
737
|
+
// size-triggered sweep inside `logRequest`, so a service logging with a
|
|
738
|
+
// narrow status filter accumulated one dead entry per request until it
|
|
739
|
+
// reached 10000 and started evicting live ones.
|
|
740
|
+
this.activeIds.delete(requestId);
|
|
645
741
|
if (!this._shouldLog("INFO", method, url, status))
|
|
646
742
|
return;
|
|
647
743
|
const ct = headers["content-type"] ?? headers["Content-Type"] ?? null;
|
|
@@ -665,7 +761,6 @@ export class HTTPLogger {
|
|
|
665
761
|
cached,
|
|
666
762
|
meta: { ...this.cfg.context, ...meta },
|
|
667
763
|
};
|
|
668
|
-
this.activeIds.delete(requestId);
|
|
669
764
|
this._write(entry);
|
|
670
765
|
}
|
|
671
766
|
/**
|
|
@@ -682,6 +777,8 @@ export class HTTPLogger {
|
|
|
682
777
|
const dur = active ? perfNow() - active.startMs : 0;
|
|
683
778
|
const method = active?.method ?? "GET";
|
|
684
779
|
const url = active?.url ?? "";
|
|
780
|
+
// Released before the filter, for the same reason as `logResponse`.
|
|
781
|
+
this.activeIds.delete(requestId);
|
|
685
782
|
if (!this._shouldLog("ERROR", method, url))
|
|
686
783
|
return;
|
|
687
784
|
const entry = {
|
|
@@ -698,7 +795,6 @@ export class HTTPLogger {
|
|
|
698
795
|
attempt,
|
|
699
796
|
meta: { ...this.cfg.context, ...meta },
|
|
700
797
|
};
|
|
701
|
-
this.activeIds.delete(requestId);
|
|
702
798
|
this._write(entry);
|
|
703
799
|
}
|
|
704
800
|
// ── §7.2 ID management ────────────────────────────────────────────────────
|
|
@@ -838,11 +934,51 @@ function serializeError(err) {
|
|
|
838
934
|
...(errStack !== undefined ? { stack: errStack } : {}),
|
|
839
935
|
};
|
|
840
936
|
}
|
|
937
|
+
// Anything else was `String(err)`, which for a rejected object — the shape a
|
|
938
|
+
// custom fetch, a GraphQL client or a worker produces — is literally
|
|
939
|
+
// "[object Object]". The entry recorded no message and no `code`, so the log
|
|
940
|
+
// said only that something had failed. An error-shaped object keeps its
|
|
941
|
+
// `name`, `message`, `code` and `stack`; anything else is stringified
|
|
942
|
+
// structurally.
|
|
943
|
+
if (err !== null && typeof err === "object") {
|
|
944
|
+
const o = err;
|
|
945
|
+
const out = {
|
|
946
|
+
name: typeof o.name === "string" && o.name !== "" ? o.name : "Error",
|
|
947
|
+
message: typeof o.message === "string" ? o.message : safeStringify(err),
|
|
948
|
+
};
|
|
949
|
+
if (typeof o.code === "string" || typeof o.code === "number")
|
|
950
|
+
out.code = String(o.code);
|
|
951
|
+
if (typeof o.stack === "string")
|
|
952
|
+
out.stack = o.stack;
|
|
953
|
+
return out;
|
|
954
|
+
}
|
|
841
955
|
return { name: "Error", message: String(err) };
|
|
842
956
|
}
|
|
843
|
-
/**
|
|
844
|
-
|
|
845
|
-
|
|
957
|
+
/** `JSON.stringify` that never throws — falls back for circular values. */
|
|
958
|
+
// The marker is lowercase here and capitalised in the shared helper. Both are
|
|
959
|
+
// asserted by tests and both appear in log output, so this converges on one
|
|
960
|
+
// implementation without converging on one string.
|
|
961
|
+
const CIRCULAR_MARKER = "[circular]";
|
|
962
|
+
const safeStringify = (value) => stringifySafely(value, CIRCULAR_MARKER);
|
|
963
|
+
/**
|
|
964
|
+
* Truncate a string to at most `maxBytes` UTF-8 bytes, never splitting a
|
|
965
|
+
* character, and report how many bytes were actually removed.
|
|
966
|
+
*/
|
|
967
|
+
function truncateToBytes(str, maxBytes) {
|
|
968
|
+
const enc = new TextEncoder();
|
|
969
|
+
const total = enc.encode(str).byteLength;
|
|
970
|
+
if (total <= maxBytes)
|
|
971
|
+
return { text: str, removed: 0 };
|
|
972
|
+
let used = 0;
|
|
973
|
+
let end = 0;
|
|
974
|
+
for (const ch of str) {
|
|
975
|
+
const width = enc.encode(ch).byteLength;
|
|
976
|
+
if (used + width > maxBytes)
|
|
977
|
+
break;
|
|
978
|
+
used += width;
|
|
979
|
+
end += ch.length;
|
|
980
|
+
}
|
|
981
|
+
return { text: str.slice(0, end), removed: total - used };
|
|
846
982
|
}
|
|
847
983
|
// ============================================================================
|
|
848
984
|
// §10 FACTORY HELPERS
|
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";
|