@credal/sdk 0.1.10 → 0.1.11
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/dist/cjs/BaseClient.d.ts +4 -0
- package/dist/cjs/Client.js +3 -3
- package/dist/cjs/api/resources/copilots/client/Client.js +27 -9
- package/dist/cjs/api/resources/documentCatalog/client/Client.js +12 -4
- package/dist/cjs/api/resources/documentCollections/client/Client.js +21 -7
- package/dist/cjs/api/resources/search/client/Client.js +3 -1
- package/dist/cjs/api/resources/users/client/Client.js +3 -1
- package/dist/cjs/core/exports.d.ts +1 -0
- package/dist/cjs/core/exports.js +1 -0
- package/dist/cjs/core/fetcher/Fetcher.d.ts +4 -1
- package/dist/cjs/core/fetcher/Fetcher.js +202 -9
- package/dist/cjs/core/fetcher/getRequestBody.d.ts +1 -1
- package/dist/cjs/core/fetcher/getRequestBody.js +4 -0
- package/dist/cjs/core/fetcher/makeRequest.d.ts +1 -1
- package/dist/cjs/core/fetcher/makeRequest.js +0 -2
- package/dist/cjs/core/fetcher/requestWithRetries.js +0 -9
- package/dist/cjs/core/fetcher/signals.d.ts +0 -6
- package/dist/cjs/core/fetcher/signals.js +0 -12
- package/dist/cjs/core/headers.js +6 -4
- package/dist/cjs/core/index.d.ts +1 -0
- package/dist/cjs/core/index.js +2 -1
- package/dist/cjs/core/logging/exports.d.ts +18 -0
- package/dist/cjs/core/logging/exports.js +45 -0
- package/dist/cjs/core/logging/index.d.ts +1 -0
- package/dist/cjs/core/logging/index.js +17 -0
- package/dist/cjs/core/logging/logger.d.ts +126 -0
- package/dist/cjs/core/logging/logger.js +144 -0
- package/dist/cjs/core/url/join.js +0 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/BaseClient.d.mts +4 -0
- package/dist/esm/Client.mjs +3 -3
- package/dist/esm/api/resources/copilots/client/Client.mjs +27 -9
- package/dist/esm/api/resources/documentCatalog/client/Client.mjs +12 -4
- package/dist/esm/api/resources/documentCollections/client/Client.mjs +21 -7
- package/dist/esm/api/resources/search/client/Client.mjs +3 -1
- package/dist/esm/api/resources/users/client/Client.mjs +3 -1
- package/dist/esm/core/exports.d.mts +1 -0
- package/dist/esm/core/exports.mjs +1 -0
- package/dist/esm/core/fetcher/Fetcher.d.mts +4 -1
- package/dist/esm/core/fetcher/Fetcher.mjs +202 -9
- package/dist/esm/core/fetcher/getRequestBody.d.mts +1 -1
- package/dist/esm/core/fetcher/getRequestBody.mjs +4 -0
- package/dist/esm/core/fetcher/makeRequest.d.mts +1 -1
- package/dist/esm/core/fetcher/makeRequest.mjs +0 -2
- package/dist/esm/core/fetcher/requestWithRetries.mjs +0 -9
- package/dist/esm/core/fetcher/signals.d.mts +0 -6
- package/dist/esm/core/fetcher/signals.mjs +0 -12
- package/dist/esm/core/headers.mjs +6 -4
- package/dist/esm/core/index.d.mts +1 -0
- package/dist/esm/core/index.mjs +1 -0
- package/dist/esm/core/logging/exports.d.mts +18 -0
- package/dist/esm/core/logging/exports.mjs +9 -0
- package/dist/esm/core/logging/index.d.mts +1 -0
- package/dist/esm/core/logging/index.mjs +1 -0
- package/dist/esm/core/logging/logger.d.mts +126 -0
- package/dist/esm/core/logging/logger.mjs +138 -0
- package/dist/esm/core/url/join.mjs +0 -1
- package/dist/esm/version.d.mts +1 -1
- package/dist/esm/version.mjs +1 -1
- package/package.json +3 -2
|
@@ -12,21 +12,153 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.fetcher = void 0;
|
|
13
13
|
exports.fetcherImpl = fetcherImpl;
|
|
14
14
|
const json_js_1 = require("../json.js");
|
|
15
|
+
const logger_js_1 = require("../logging/logger.js");
|
|
15
16
|
const createRequestUrl_js_1 = require("./createRequestUrl.js");
|
|
16
17
|
const EndpointSupplier_js_1 = require("./EndpointSupplier.js");
|
|
17
18
|
const getErrorResponseBody_js_1 = require("./getErrorResponseBody.js");
|
|
18
19
|
const getFetchFn_js_1 = require("./getFetchFn.js");
|
|
19
20
|
const getRequestBody_js_1 = require("./getRequestBody.js");
|
|
20
21
|
const getResponseBody_js_1 = require("./getResponseBody.js");
|
|
22
|
+
const Headers_js_1 = require("./Headers.js");
|
|
21
23
|
const makeRequest_js_1 = require("./makeRequest.js");
|
|
22
24
|
const RawResponse_js_1 = require("./RawResponse.js");
|
|
23
25
|
const requestWithRetries_js_1 = require("./requestWithRetries.js");
|
|
26
|
+
const SENSITIVE_HEADERS = new Set([
|
|
27
|
+
"authorization",
|
|
28
|
+
"www-authenticate",
|
|
29
|
+
"x-api-key",
|
|
30
|
+
"api-key",
|
|
31
|
+
"apikey",
|
|
32
|
+
"x-api-token",
|
|
33
|
+
"x-auth-token",
|
|
34
|
+
"auth-token",
|
|
35
|
+
"cookie",
|
|
36
|
+
"set-cookie",
|
|
37
|
+
"proxy-authorization",
|
|
38
|
+
"proxy-authenticate",
|
|
39
|
+
"x-csrf-token",
|
|
40
|
+
"x-xsrf-token",
|
|
41
|
+
"x-session-token",
|
|
42
|
+
"x-access-token",
|
|
43
|
+
]);
|
|
44
|
+
function redactHeaders(headers) {
|
|
45
|
+
const filtered = {};
|
|
46
|
+
for (const [key, value] of headers instanceof Headers_js_1.Headers ? headers.entries() : Object.entries(headers)) {
|
|
47
|
+
if (SENSITIVE_HEADERS.has(key.toLowerCase())) {
|
|
48
|
+
filtered[key] = "[REDACTED]";
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
filtered[key] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return filtered;
|
|
55
|
+
}
|
|
56
|
+
const SENSITIVE_QUERY_PARAMS = new Set([
|
|
57
|
+
"api_key",
|
|
58
|
+
"api-key",
|
|
59
|
+
"apikey",
|
|
60
|
+
"token",
|
|
61
|
+
"access_token",
|
|
62
|
+
"access-token",
|
|
63
|
+
"auth_token",
|
|
64
|
+
"auth-token",
|
|
65
|
+
"password",
|
|
66
|
+
"passwd",
|
|
67
|
+
"secret",
|
|
68
|
+
"api_secret",
|
|
69
|
+
"api-secret",
|
|
70
|
+
"apisecret",
|
|
71
|
+
"key",
|
|
72
|
+
"session",
|
|
73
|
+
"session_id",
|
|
74
|
+
"session-id",
|
|
75
|
+
]);
|
|
76
|
+
function redactQueryParameters(queryParameters) {
|
|
77
|
+
if (queryParameters == null) {
|
|
78
|
+
return queryParameters;
|
|
79
|
+
}
|
|
80
|
+
const redacted = {};
|
|
81
|
+
for (const [key, value] of Object.entries(queryParameters)) {
|
|
82
|
+
if (SENSITIVE_QUERY_PARAMS.has(key.toLowerCase())) {
|
|
83
|
+
redacted[key] = "[REDACTED]";
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
redacted[key] = value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return redacted;
|
|
90
|
+
}
|
|
91
|
+
function redactUrl(url) {
|
|
92
|
+
const protocolIndex = url.indexOf("://");
|
|
93
|
+
if (protocolIndex === -1)
|
|
94
|
+
return url;
|
|
95
|
+
const afterProtocol = protocolIndex + 3;
|
|
96
|
+
// Find the first delimiter that marks the end of the authority section
|
|
97
|
+
const pathStart = url.indexOf("/", afterProtocol);
|
|
98
|
+
let queryStart = url.indexOf("?", afterProtocol);
|
|
99
|
+
let fragmentStart = url.indexOf("#", afterProtocol);
|
|
100
|
+
const firstDelimiter = Math.min(pathStart === -1 ? url.length : pathStart, queryStart === -1 ? url.length : queryStart, fragmentStart === -1 ? url.length : fragmentStart);
|
|
101
|
+
// Find the LAST @ before the delimiter (handles multiple @ in credentials)
|
|
102
|
+
let atIndex = -1;
|
|
103
|
+
for (let i = afterProtocol; i < firstDelimiter; i++) {
|
|
104
|
+
if (url[i] === "@") {
|
|
105
|
+
atIndex = i;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (atIndex !== -1) {
|
|
109
|
+
url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`;
|
|
110
|
+
}
|
|
111
|
+
// Recalculate queryStart since url might have changed
|
|
112
|
+
queryStart = url.indexOf("?");
|
|
113
|
+
if (queryStart === -1)
|
|
114
|
+
return url;
|
|
115
|
+
fragmentStart = url.indexOf("#", queryStart);
|
|
116
|
+
const queryEnd = fragmentStart !== -1 ? fragmentStart : url.length;
|
|
117
|
+
const queryString = url.slice(queryStart + 1, queryEnd);
|
|
118
|
+
if (queryString.length === 0)
|
|
119
|
+
return url;
|
|
120
|
+
// FAST PATH: Quick check if any sensitive keywords present
|
|
121
|
+
// Using indexOf is faster than regex for simple substring matching
|
|
122
|
+
const lower = queryString.toLowerCase();
|
|
123
|
+
const hasSensitive = lower.includes("token") ||
|
|
124
|
+
lower.includes("key") ||
|
|
125
|
+
lower.includes("password") ||
|
|
126
|
+
lower.includes("passwd") ||
|
|
127
|
+
lower.includes("secret") ||
|
|
128
|
+
lower.includes("session") ||
|
|
129
|
+
lower.includes("auth");
|
|
130
|
+
if (!hasSensitive) {
|
|
131
|
+
return url;
|
|
132
|
+
}
|
|
133
|
+
// SLOW PATH: Parse and redact
|
|
134
|
+
const redactedParams = [];
|
|
135
|
+
const params = queryString.split("&");
|
|
136
|
+
for (const param of params) {
|
|
137
|
+
const equalIndex = param.indexOf("=");
|
|
138
|
+
if (equalIndex === -1) {
|
|
139
|
+
redactedParams.push(param);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const key = param.slice(0, equalIndex);
|
|
143
|
+
let shouldRedact = SENSITIVE_QUERY_PARAMS.has(key.toLowerCase());
|
|
144
|
+
if (!shouldRedact && key.includes("%")) {
|
|
145
|
+
try {
|
|
146
|
+
const decodedKey = decodeURIComponent(key);
|
|
147
|
+
shouldRedact = SENSITIVE_QUERY_PARAMS.has(decodedKey.toLowerCase());
|
|
148
|
+
}
|
|
149
|
+
catch (_a) { }
|
|
150
|
+
}
|
|
151
|
+
redactedParams.push(shouldRedact ? `${key}=[REDACTED]` : param);
|
|
152
|
+
}
|
|
153
|
+
return url.slice(0, queryStart + 1) + redactedParams.join("&") + url.slice(queryEnd);
|
|
154
|
+
}
|
|
24
155
|
function getHeaders(args) {
|
|
25
156
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26
157
|
var _a;
|
|
27
|
-
const newHeaders =
|
|
158
|
+
const newHeaders = new Headers_js_1.Headers();
|
|
159
|
+
newHeaders.set("Accept", args.responseType === "json" ? "application/json" : args.responseType === "text" ? "text/plain" : "*/*");
|
|
28
160
|
if (args.body !== undefined && args.contentType != null) {
|
|
29
|
-
newHeaders
|
|
161
|
+
newHeaders.set("Content-Type", args.contentType);
|
|
30
162
|
}
|
|
31
163
|
if (args.headers == null) {
|
|
32
164
|
return newHeaders;
|
|
@@ -34,31 +166,52 @@ function getHeaders(args) {
|
|
|
34
166
|
for (const [key, value] of Object.entries(args.headers)) {
|
|
35
167
|
const result = yield EndpointSupplier_js_1.EndpointSupplier.get(value, { endpointMetadata: (_a = args.endpointMetadata) !== null && _a !== void 0 ? _a : {} });
|
|
36
168
|
if (typeof result === "string") {
|
|
37
|
-
newHeaders
|
|
169
|
+
newHeaders.set(key, result);
|
|
38
170
|
continue;
|
|
39
171
|
}
|
|
40
172
|
if (result == null) {
|
|
41
173
|
continue;
|
|
42
174
|
}
|
|
43
|
-
newHeaders
|
|
175
|
+
newHeaders.set(key, `${result}`);
|
|
44
176
|
}
|
|
45
177
|
return newHeaders;
|
|
46
178
|
});
|
|
47
179
|
}
|
|
48
180
|
function fetcherImpl(args) {
|
|
49
181
|
return __awaiter(this, void 0, void 0, function* () {
|
|
50
|
-
var _a;
|
|
182
|
+
var _a, _b, _c;
|
|
51
183
|
const url = (0, createRequestUrl_js_1.createRequestUrl)(args.url, args.queryParameters);
|
|
52
184
|
const requestBody = yield (0, getRequestBody_js_1.getRequestBody)({
|
|
53
185
|
body: args.body,
|
|
54
|
-
type: args.requestType
|
|
186
|
+
type: (_a = args.requestType) !== null && _a !== void 0 ? _a : "other",
|
|
55
187
|
});
|
|
56
|
-
const fetchFn = yield (0, getFetchFn_js_1.getFetchFn)();
|
|
188
|
+
const fetchFn = (_b = args.fetchFn) !== null && _b !== void 0 ? _b : (yield (0, getFetchFn_js_1.getFetchFn)());
|
|
189
|
+
const headers = yield getHeaders(args);
|
|
190
|
+
const logger = (0, logger_js_1.createLogger)(args.logging);
|
|
191
|
+
if (logger.isDebug()) {
|
|
192
|
+
const metadata = {
|
|
193
|
+
method: args.method,
|
|
194
|
+
url: redactUrl(url),
|
|
195
|
+
headers: redactHeaders(headers),
|
|
196
|
+
queryParameters: redactQueryParameters(args.queryParameters),
|
|
197
|
+
hasBody: requestBody != null,
|
|
198
|
+
};
|
|
199
|
+
logger.debug("Making HTTP request", metadata);
|
|
200
|
+
}
|
|
57
201
|
try {
|
|
58
202
|
const response = yield (0, requestWithRetries_js_1.requestWithRetries)(() => __awaiter(this, void 0, void 0, function* () {
|
|
59
|
-
return (0, makeRequest_js_1.makeRequest)(fetchFn, url, args.method,
|
|
203
|
+
return (0, makeRequest_js_1.makeRequest)(fetchFn, url, args.method, headers, requestBody, args.timeoutMs, args.abortSignal, args.withCredentials, args.duplex);
|
|
60
204
|
}), args.maxRetries);
|
|
61
205
|
if (response.status >= 200 && response.status < 400) {
|
|
206
|
+
if (logger.isDebug()) {
|
|
207
|
+
const metadata = {
|
|
208
|
+
method: args.method,
|
|
209
|
+
url: redactUrl(url),
|
|
210
|
+
statusCode: response.status,
|
|
211
|
+
responseHeaders: redactHeaders(response.headers),
|
|
212
|
+
};
|
|
213
|
+
logger.debug("HTTP request succeeded", metadata);
|
|
214
|
+
}
|
|
62
215
|
return {
|
|
63
216
|
ok: true,
|
|
64
217
|
body: (yield (0, getResponseBody_js_1.getResponseBody)(response, args.responseType)),
|
|
@@ -67,6 +220,15 @@ function fetcherImpl(args) {
|
|
|
67
220
|
};
|
|
68
221
|
}
|
|
69
222
|
else {
|
|
223
|
+
if (logger.isError()) {
|
|
224
|
+
const metadata = {
|
|
225
|
+
method: args.method,
|
|
226
|
+
url: redactUrl(url),
|
|
227
|
+
statusCode: response.status,
|
|
228
|
+
responseHeaders: redactHeaders(Object.fromEntries(response.headers.entries())),
|
|
229
|
+
};
|
|
230
|
+
logger.error("HTTP request failed with error status", metadata);
|
|
231
|
+
}
|
|
70
232
|
return {
|
|
71
233
|
ok: false,
|
|
72
234
|
error: {
|
|
@@ -79,7 +241,14 @@ function fetcherImpl(args) {
|
|
|
79
241
|
}
|
|
80
242
|
}
|
|
81
243
|
catch (error) {
|
|
82
|
-
if ((
|
|
244
|
+
if ((_c = args.abortSignal) === null || _c === void 0 ? void 0 : _c.aborted) {
|
|
245
|
+
if (logger.isError()) {
|
|
246
|
+
const metadata = {
|
|
247
|
+
method: args.method,
|
|
248
|
+
url: redactUrl(url),
|
|
249
|
+
};
|
|
250
|
+
logger.error("HTTP request was aborted", metadata);
|
|
251
|
+
}
|
|
83
252
|
return {
|
|
84
253
|
ok: false,
|
|
85
254
|
error: {
|
|
@@ -90,6 +259,14 @@ function fetcherImpl(args) {
|
|
|
90
259
|
};
|
|
91
260
|
}
|
|
92
261
|
else if (error instanceof Error && error.name === "AbortError") {
|
|
262
|
+
if (logger.isError()) {
|
|
263
|
+
const metadata = {
|
|
264
|
+
method: args.method,
|
|
265
|
+
url: redactUrl(url),
|
|
266
|
+
timeoutMs: args.timeoutMs,
|
|
267
|
+
};
|
|
268
|
+
logger.error("HTTP request timed out", metadata);
|
|
269
|
+
}
|
|
93
270
|
return {
|
|
94
271
|
ok: false,
|
|
95
272
|
error: {
|
|
@@ -99,6 +276,14 @@ function fetcherImpl(args) {
|
|
|
99
276
|
};
|
|
100
277
|
}
|
|
101
278
|
else if (error instanceof Error) {
|
|
279
|
+
if (logger.isError()) {
|
|
280
|
+
const metadata = {
|
|
281
|
+
method: args.method,
|
|
282
|
+
url: redactUrl(url),
|
|
283
|
+
errorMessage: error.message,
|
|
284
|
+
};
|
|
285
|
+
logger.error("HTTP request failed with error", metadata);
|
|
286
|
+
}
|
|
102
287
|
return {
|
|
103
288
|
ok: false,
|
|
104
289
|
error: {
|
|
@@ -108,6 +293,14 @@ function fetcherImpl(args) {
|
|
|
108
293
|
rawResponse: RawResponse_js_1.unknownRawResponse,
|
|
109
294
|
};
|
|
110
295
|
}
|
|
296
|
+
if (logger.isError()) {
|
|
297
|
+
const metadata = {
|
|
298
|
+
method: args.method,
|
|
299
|
+
url: redactUrl(url),
|
|
300
|
+
error: (0, json_js_1.toJson)(error),
|
|
301
|
+
};
|
|
302
|
+
logger.error("HTTP request failed with unknown error", metadata);
|
|
303
|
+
}
|
|
111
304
|
return {
|
|
112
305
|
ok: false,
|
|
113
306
|
error: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare namespace GetRequestBody {
|
|
2
2
|
interface Args {
|
|
3
3
|
body: unknown;
|
|
4
|
-
type: "json" | "file" | "bytes" | "other";
|
|
4
|
+
type: "json" | "file" | "bytes" | "form" | "other";
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
7
|
export declare function getRequestBody({ body, type }: GetRequestBody.Args): Promise<BodyInit | undefined>;
|
|
@@ -11,8 +11,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.getRequestBody = getRequestBody;
|
|
13
13
|
const json_js_1 = require("../json.js");
|
|
14
|
+
const qs_js_1 = require("../url/qs.js");
|
|
14
15
|
function getRequestBody(_a) {
|
|
15
16
|
return __awaiter(this, arguments, void 0, function* ({ body, type }) {
|
|
17
|
+
if (type === "form") {
|
|
18
|
+
return (0, qs_js_1.toQueryString)(body, { arrayFormat: "repeat", encode: true });
|
|
19
|
+
}
|
|
16
20
|
if (type.includes("json")) {
|
|
17
21
|
return (0, json_js_1.toJson)(body);
|
|
18
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const makeRequest: (fetchFn: (url: string, init: RequestInit) => Promise<Response>, url: string, method: string, headers: Record<string, string>, requestBody: BodyInit | undefined, timeoutMs?: number, abortSignal?: AbortSignal, withCredentials?: boolean, duplex?: "half") => Promise<Response>;
|
|
1
|
+
export declare const makeRequest: (fetchFn: (url: string, init: RequestInit) => Promise<Response>, url: string, method: string, headers: Headers | Record<string, string>, requestBody: BodyInit | undefined, timeoutMs?: number, abortSignal?: AbortSignal, withCredentials?: boolean, duplex?: "half") => Promise<Response>;
|
|
@@ -13,14 +13,12 @@ exports.makeRequest = void 0;
|
|
|
13
13
|
const signals_js_1 = require("./signals.js");
|
|
14
14
|
const makeRequest = (fetchFn, url, method, headers, requestBody, timeoutMs, abortSignal, withCredentials, duplex) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
15
|
const signals = [];
|
|
16
|
-
// Add timeout signal
|
|
17
16
|
let timeoutAbortId;
|
|
18
17
|
if (timeoutMs != null) {
|
|
19
18
|
const { signal, abortId } = (0, signals_js_1.getTimeoutSignal)(timeoutMs);
|
|
20
19
|
timeoutAbortId = abortId;
|
|
21
20
|
signals.push(signal);
|
|
22
21
|
}
|
|
23
|
-
// Add arbitrary signal
|
|
24
22
|
if (abortSignal != null) {
|
|
25
23
|
signals.push(abortSignal);
|
|
26
24
|
}
|
|
@@ -15,25 +15,20 @@ const MAX_RETRY_DELAY = 60000; // in milliseconds
|
|
|
15
15
|
const DEFAULT_MAX_RETRIES = 2;
|
|
16
16
|
const JITTER_FACTOR = 0.2; // 20% random jitter
|
|
17
17
|
function addPositiveJitter(delay) {
|
|
18
|
-
// Generate a random value between 0 and +JITTER_FACTOR
|
|
19
18
|
const jitterMultiplier = 1 + Math.random() * JITTER_FACTOR;
|
|
20
19
|
return delay * jitterMultiplier;
|
|
21
20
|
}
|
|
22
21
|
function addSymmetricJitter(delay) {
|
|
23
|
-
// Generate a random value in a JITTER_FACTOR-sized percentage range around delay
|
|
24
22
|
const jitterMultiplier = 1 + (Math.random() - 0.5) * JITTER_FACTOR;
|
|
25
23
|
return delay * jitterMultiplier;
|
|
26
24
|
}
|
|
27
25
|
function getRetryDelayFromHeaders(response, retryAttempt) {
|
|
28
|
-
// Check for Retry-After header first (RFC 7231), with no jitter
|
|
29
26
|
const retryAfter = response.headers.get("Retry-After");
|
|
30
27
|
if (retryAfter) {
|
|
31
|
-
// Parse as number of seconds...
|
|
32
28
|
const retryAfterSeconds = parseInt(retryAfter, 10);
|
|
33
29
|
if (!Number.isNaN(retryAfterSeconds) && retryAfterSeconds > 0) {
|
|
34
30
|
return Math.min(retryAfterSeconds * 1000, MAX_RETRY_DELAY);
|
|
35
31
|
}
|
|
36
|
-
// ...or as an HTTP date; both are valid
|
|
37
32
|
const retryAfterDate = new Date(retryAfter);
|
|
38
33
|
if (!Number.isNaN(retryAfterDate.getTime())) {
|
|
39
34
|
const delay = retryAfterDate.getTime() - Date.now();
|
|
@@ -42,19 +37,16 @@ function getRetryDelayFromHeaders(response, retryAttempt) {
|
|
|
42
37
|
}
|
|
43
38
|
}
|
|
44
39
|
}
|
|
45
|
-
// Then check for industry-standard X-RateLimit-Reset header, with positive jitter
|
|
46
40
|
const rateLimitReset = response.headers.get("X-RateLimit-Reset");
|
|
47
41
|
if (rateLimitReset) {
|
|
48
42
|
const resetTime = parseInt(rateLimitReset, 10);
|
|
49
43
|
if (!Number.isNaN(resetTime)) {
|
|
50
|
-
// Assume Unix timestamp in epoch seconds
|
|
51
44
|
const delay = resetTime * 1000 - Date.now();
|
|
52
45
|
if (delay > 0) {
|
|
53
46
|
return addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY));
|
|
54
47
|
}
|
|
55
48
|
}
|
|
56
49
|
}
|
|
57
|
-
// Fall back to exponential backoff, with symmetric jitter
|
|
58
50
|
return addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * Math.pow(2, retryAttempt), MAX_RETRY_DELAY));
|
|
59
51
|
}
|
|
60
52
|
function requestWithRetries(requestFn_1) {
|
|
@@ -62,7 +54,6 @@ function requestWithRetries(requestFn_1) {
|
|
|
62
54
|
let response = yield requestFn();
|
|
63
55
|
for (let i = 0; i < maxRetries; ++i) {
|
|
64
56
|
if ([408, 429].includes(response.status) || response.status >= 500) {
|
|
65
|
-
// Get delay with appropriate jitter applied
|
|
66
57
|
const delay = getRetryDelayFromHeaders(response, i);
|
|
67
58
|
yield new Promise((resolve) => setTimeout(resolve, delay));
|
|
68
59
|
response = yield requestFn();
|
|
@@ -2,10 +2,4 @@ export declare function getTimeoutSignal(timeoutMs: number): {
|
|
|
2
2
|
signal: AbortSignal;
|
|
3
3
|
abortId: NodeJS.Timeout;
|
|
4
4
|
};
|
|
5
|
-
/**
|
|
6
|
-
* Returns an abort signal that is getting aborted when
|
|
7
|
-
* at least one of the specified abort signals is aborted.
|
|
8
|
-
*
|
|
9
|
-
* Requires at least node.js 18.
|
|
10
|
-
*/
|
|
11
5
|
export declare function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal;
|
|
@@ -8,26 +8,14 @@ function getTimeoutSignal(timeoutMs) {
|
|
|
8
8
|
const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs);
|
|
9
9
|
return { signal: controller.signal, abortId };
|
|
10
10
|
}
|
|
11
|
-
/**
|
|
12
|
-
* Returns an abort signal that is getting aborted when
|
|
13
|
-
* at least one of the specified abort signals is aborted.
|
|
14
|
-
*
|
|
15
|
-
* Requires at least node.js 18.
|
|
16
|
-
*/
|
|
17
11
|
function anySignal(...args) {
|
|
18
|
-
// Allowing signals to be passed either as array
|
|
19
|
-
// of signals or as multiple arguments.
|
|
20
12
|
const signals = (args.length === 1 && Array.isArray(args[0]) ? args[0] : args);
|
|
21
13
|
const controller = new AbortController();
|
|
22
14
|
for (const signal of signals) {
|
|
23
15
|
if (signal.aborted) {
|
|
24
|
-
// Exiting early if one of the signals
|
|
25
|
-
// is already aborted.
|
|
26
16
|
controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason);
|
|
27
17
|
break;
|
|
28
18
|
}
|
|
29
|
-
// Listening for signals and removing the listeners
|
|
30
|
-
// when at least one symbol is aborted.
|
|
31
19
|
signal.addEventListener("abort", () => controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason), {
|
|
32
20
|
signal: controller.signal,
|
|
33
21
|
});
|
package/dist/cjs/core/headers.js
CHANGED
|
@@ -7,11 +7,12 @@ function mergeHeaders(...headersArray) {
|
|
|
7
7
|
for (const [key, value] of headersArray
|
|
8
8
|
.filter((headers) => headers != null)
|
|
9
9
|
.flatMap((headers) => Object.entries(headers))) {
|
|
10
|
+
const insensitiveKey = key.toLowerCase();
|
|
10
11
|
if (value != null) {
|
|
11
|
-
result[
|
|
12
|
+
result[insensitiveKey] = value;
|
|
12
13
|
}
|
|
13
|
-
else if (
|
|
14
|
-
delete result[
|
|
14
|
+
else if (insensitiveKey in result) {
|
|
15
|
+
delete result[insensitiveKey];
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
return result;
|
|
@@ -21,8 +22,9 @@ function mergeOnlyDefinedHeaders(...headersArray) {
|
|
|
21
22
|
for (const [key, value] of headersArray
|
|
22
23
|
.filter((headers) => headers != null)
|
|
23
24
|
.flatMap((headers) => Object.entries(headers))) {
|
|
25
|
+
const insensitiveKey = key.toLowerCase();
|
|
24
26
|
if (value != null) {
|
|
25
|
-
result[
|
|
27
|
+
result[insensitiveKey] = value;
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
return result;
|
package/dist/cjs/core/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from "./base64.js";
|
|
|
3
3
|
export * from "./fetcher/index.js";
|
|
4
4
|
export * as file from "./file/index.js";
|
|
5
5
|
export * from "./form-data-utils/index.js";
|
|
6
|
+
export * as logging from "./logging/index.js";
|
|
6
7
|
export * from "./runtime/index.js";
|
|
7
8
|
export * from "./stream/index.js";
|
|
8
9
|
export * as url from "./url/index.js";
|
package/dist/cjs/core/index.js
CHANGED
|
@@ -36,12 +36,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.url = exports.file = void 0;
|
|
39
|
+
exports.url = exports.logging = exports.file = void 0;
|
|
40
40
|
__exportStar(require("./auth/index.js"), exports);
|
|
41
41
|
__exportStar(require("./base64.js"), exports);
|
|
42
42
|
__exportStar(require("./fetcher/index.js"), exports);
|
|
43
43
|
exports.file = __importStar(require("./file/index.js"));
|
|
44
44
|
__exportStar(require("./form-data-utils/index.js"), exports);
|
|
45
|
+
exports.logging = __importStar(require("./logging/index.js"));
|
|
45
46
|
__exportStar(require("./runtime/index.js"), exports);
|
|
46
47
|
__exportStar(require("./stream/index.js"), exports);
|
|
47
48
|
exports.url = __importStar(require("./url/index.js"));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as logger from "./logger.js";
|
|
2
|
+
export declare namespace logging {
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for logger instances.
|
|
5
|
+
*/
|
|
6
|
+
type LogConfig = logger.LogConfig;
|
|
7
|
+
type LogLevel = logger.LogLevel;
|
|
8
|
+
const LogLevel: typeof logger.LogLevel;
|
|
9
|
+
type ILogger = logger.ILogger;
|
|
10
|
+
/**
|
|
11
|
+
* Console logger implementation that outputs to the console.
|
|
12
|
+
*/
|
|
13
|
+
type ConsoleLogger = logger.ConsoleLogger;
|
|
14
|
+
/**
|
|
15
|
+
* Console logger implementation that outputs to the console.
|
|
16
|
+
*/
|
|
17
|
+
const ConsoleLogger: typeof logger.ConsoleLogger;
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.logging = void 0;
|
|
37
|
+
const logger = __importStar(require("./logger.js"));
|
|
38
|
+
var logging;
|
|
39
|
+
(function (logging) {
|
|
40
|
+
logging.LogLevel = logger.LogLevel;
|
|
41
|
+
/**
|
|
42
|
+
* Console logger implementation that outputs to the console.
|
|
43
|
+
*/
|
|
44
|
+
logging.ConsoleLogger = logger.ConsoleLogger;
|
|
45
|
+
})(logging || (exports.logging = logging = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./logger.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./logger.js"), exports);
|