@naturalcycles/js-lib 14.175.0 → 14.177.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/dist/http/fetcher.js
CHANGED
|
@@ -204,7 +204,8 @@ class Fetcher {
|
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
try {
|
|
207
|
-
|
|
207
|
+
// Calls cfg.fetchFn if set, otherwise Fetcher.callNativeFetch
|
|
208
|
+
res.fetchResponse = await (this.cfg.fetchFn || Fetcher.callNativeFetch)(req.fullUrl, req.init);
|
|
208
209
|
res.ok = res.fetchResponse.ok;
|
|
209
210
|
// important to set it to undefined, otherwise it can keep the previous value (from previous try)
|
|
210
211
|
res.err = undefined;
|
|
@@ -223,7 +224,7 @@ class Fetcher {
|
|
|
223
224
|
}
|
|
224
225
|
res.statusFamily = this.getStatusFamily(res);
|
|
225
226
|
res.statusCode = res.fetchResponse?.status;
|
|
226
|
-
if (res.fetchResponse?.ok) {
|
|
227
|
+
if (res.fetchResponse?.ok || !req.throwHttpErrors) {
|
|
227
228
|
try {
|
|
228
229
|
// We are applying a separate Timeout (as long as original Timeout for now) to "download and parse the body"
|
|
229
230
|
await (0, pTimeout_1.pTimeout)(async () => await this.onOkResponse(res), {
|
|
@@ -292,7 +293,7 @@ class Fetcher {
|
|
|
292
293
|
}
|
|
293
294
|
res.retryStatus.retryStopped = true;
|
|
294
295
|
// res.err can happen on `failed to fetch` type of error, e.g JSON.parse, CORS, unexpected redirect
|
|
295
|
-
if (!res.err && this.cfg.logResponse) {
|
|
296
|
+
if ((!res.err || !req.throwHttpErrors) && this.cfg.logResponse) {
|
|
296
297
|
const { retryAttempt } = res.retryStatus;
|
|
297
298
|
const { logger } = this.cfg;
|
|
298
299
|
logger.log([
|
|
@@ -530,6 +531,7 @@ class Fetcher {
|
|
|
530
531
|
redirect: cfg.redirect,
|
|
531
532
|
},
|
|
532
533
|
hooks: {},
|
|
534
|
+
throwHttpErrors: true,
|
|
533
535
|
}, (0, object_util_1._omit)(cfg, ['method', 'credentials', 'headers', 'redirect', 'logger']));
|
|
534
536
|
norm.init.headers = (0, object_util_1._mapKeys)(norm.init.headers, k => k.toLowerCase());
|
|
535
537
|
return norm;
|
|
@@ -548,6 +550,7 @@ class Fetcher {
|
|
|
548
550
|
'logResponse',
|
|
549
551
|
'logResponseBody',
|
|
550
552
|
'debug',
|
|
553
|
+
'throwHttpErrors',
|
|
551
554
|
]),
|
|
552
555
|
started: Date.now(),
|
|
553
556
|
...(0, object_util_1._omit)(opt, ['method', 'headers', 'credentials']),
|
|
@@ -4,7 +4,7 @@ import type { CommonLogger } from '../log/commonLogger';
|
|
|
4
4
|
import type { Promisable } from '../typeFest';
|
|
5
5
|
import type { AnyObject, NumberOfMilliseconds, Reviver, UnixTimestampMillisNumber } from '../types';
|
|
6
6
|
import type { HttpMethod, HttpStatusFamily } from './http.model';
|
|
7
|
-
export interface FetcherNormalizedCfg extends Required<FetcherCfg>, Omit<FetcherRequest, 'started' | 'fullUrl' | 'logRequest' | 'logRequestBody' | 'logResponse' | 'logResponseBody' | 'debug' | 'redirect' | 'credentials'> {
|
|
7
|
+
export interface FetcherNormalizedCfg extends Required<FetcherCfg>, Omit<FetcherRequest, 'started' | 'fullUrl' | 'logRequest' | 'logRequestBody' | 'logResponse' | 'logResponseBody' | 'debug' | 'redirect' | 'credentials' | 'throwHttpErrors'> {
|
|
8
8
|
logger: CommonLogger;
|
|
9
9
|
searchParams: Record<string, any>;
|
|
10
10
|
}
|
|
@@ -67,6 +67,7 @@ export interface FetcherCfg {
|
|
|
67
67
|
* Defaults to `console`.
|
|
68
68
|
*/
|
|
69
69
|
logger?: CommonLogger;
|
|
70
|
+
throwHttpErrors?: boolean;
|
|
70
71
|
}
|
|
71
72
|
export interface FetcherRetryStatus {
|
|
72
73
|
retryAttempt: number;
|
|
@@ -178,6 +179,15 @@ export interface FetcherOptions {
|
|
|
178
179
|
* If true - enables all possible logging.
|
|
179
180
|
*/
|
|
180
181
|
debug?: boolean;
|
|
182
|
+
/**
|
|
183
|
+
* If provided - will be used instead of static `Fetcher.callNativeFetch`.
|
|
184
|
+
*/
|
|
185
|
+
fetchFn?: FetchFunction;
|
|
186
|
+
/**
|
|
187
|
+
* Default to true.
|
|
188
|
+
* Set to false to not throw on `!Response.ok`, but simply return `Response.body` as-is (json parsed, etc).
|
|
189
|
+
*/
|
|
190
|
+
throwHttpErrors?: boolean;
|
|
181
191
|
}
|
|
182
192
|
export type RequestInitNormalized = Omit<RequestInit, 'method' | 'headers'> & {
|
|
183
193
|
method: HttpMethod;
|
|
@@ -207,3 +217,9 @@ export interface FetcherErrorResponse<BODY = unknown> {
|
|
|
207
217
|
}
|
|
208
218
|
export type FetcherResponse<BODY = unknown> = FetcherSuccessResponse<BODY> | FetcherErrorResponse<BODY>;
|
|
209
219
|
export type FetcherResponseType = 'json' | 'text' | 'void' | 'arrayBuffer' | 'blob' | 'readableStream';
|
|
220
|
+
/**
|
|
221
|
+
* Signature for the `fetch` function.
|
|
222
|
+
* Used to be able to override and provide a different implementation,
|
|
223
|
+
* e.g when mocking.
|
|
224
|
+
*/
|
|
225
|
+
export type FetchFunction = (url: string, init: RequestInitNormalized) => Promise<Response>;
|
package/dist-esm/http/fetcher.js
CHANGED
|
@@ -182,7 +182,8 @@ export class Fetcher {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
try {
|
|
185
|
-
|
|
185
|
+
// Calls cfg.fetchFn if set, otherwise Fetcher.callNativeFetch
|
|
186
|
+
res.fetchResponse = await (this.cfg.fetchFn || Fetcher.callNativeFetch)(req.fullUrl, req.init);
|
|
186
187
|
res.ok = res.fetchResponse.ok;
|
|
187
188
|
// important to set it to undefined, otherwise it can keep the previous value (from previous try)
|
|
188
189
|
res.err = undefined;
|
|
@@ -201,7 +202,7 @@ export class Fetcher {
|
|
|
201
202
|
}
|
|
202
203
|
res.statusFamily = this.getStatusFamily(res);
|
|
203
204
|
res.statusCode = (_b = res.fetchResponse) === null || _b === void 0 ? void 0 : _b.status;
|
|
204
|
-
if ((_c = res.fetchResponse) === null || _c === void 0 ? void 0 : _c.ok) {
|
|
205
|
+
if (((_c = res.fetchResponse) === null || _c === void 0 ? void 0 : _c.ok) || !req.throwHttpErrors) {
|
|
205
206
|
try {
|
|
206
207
|
// We are applying a separate Timeout (as long as original Timeout for now) to "download and parse the body"
|
|
207
208
|
await pTimeout(async () => await this.onOkResponse(res), {
|
|
@@ -270,7 +271,7 @@ export class Fetcher {
|
|
|
270
271
|
}
|
|
271
272
|
res.retryStatus.retryStopped = true;
|
|
272
273
|
// res.err can happen on `failed to fetch` type of error, e.g JSON.parse, CORS, unexpected redirect
|
|
273
|
-
if (!res.err && this.cfg.logResponse) {
|
|
274
|
+
if ((!res.err || !req.throwHttpErrors) && this.cfg.logResponse) {
|
|
274
275
|
const { retryAttempt } = res.retryStatus;
|
|
275
276
|
const { logger } = this.cfg;
|
|
276
277
|
logger.log([
|
|
@@ -510,6 +511,7 @@ export class Fetcher {
|
|
|
510
511
|
redirect: cfg.redirect,
|
|
511
512
|
},
|
|
512
513
|
hooks: {},
|
|
514
|
+
throwHttpErrors: true,
|
|
513
515
|
}, _omit(cfg, ['method', 'credentials', 'headers', 'redirect', 'logger']));
|
|
514
516
|
norm.init.headers = _mapKeys(norm.init.headers, k => k.toLowerCase());
|
|
515
517
|
return norm;
|
|
@@ -528,6 +530,7 @@ export class Fetcher {
|
|
|
528
530
|
'logResponse',
|
|
529
531
|
'logResponseBody',
|
|
530
532
|
'debug',
|
|
533
|
+
'throwHttpErrors',
|
|
531
534
|
])), { started: Date.now() }), _omit(opt, ['method', 'headers', 'credentials'])), { inputUrl: opt.url || '', fullUrl: opt.url || '', retry: Object.assign(Object.assign({}, this.cfg.retry), _filterUndefinedValues(opt.retry || {})), init: _merge(Object.assign(Object.assign({}, this.cfg.init), { headers: Object.assign({}, this.cfg.init.headers), method: opt.method || this.cfg.init.method, credentials: opt.credentials || this.cfg.init.credentials, redirect: opt.redirect || this.cfg.init.redirect || 'follow' }), {
|
|
532
535
|
headers: _mapKeys(opt.headers || {}, k => k.toLowerCase()),
|
|
533
536
|
}) });
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ export interface FetcherNormalizedCfg
|
|
|
19
19
|
| 'debug'
|
|
20
20
|
| 'redirect'
|
|
21
21
|
| 'credentials'
|
|
22
|
+
| 'throwHttpErrors'
|
|
22
23
|
> {
|
|
23
24
|
logger: CommonLogger
|
|
24
25
|
searchParams: Record<string, any>
|
|
@@ -93,6 +94,8 @@ export interface FetcherCfg {
|
|
|
93
94
|
* Defaults to `console`.
|
|
94
95
|
*/
|
|
95
96
|
logger?: CommonLogger
|
|
97
|
+
|
|
98
|
+
throwHttpErrors?: boolean
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
export interface FetcherRetryStatus {
|
|
@@ -227,6 +230,17 @@ export interface FetcherOptions {
|
|
|
227
230
|
* If true - enables all possible logging.
|
|
228
231
|
*/
|
|
229
232
|
debug?: boolean
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* If provided - will be used instead of static `Fetcher.callNativeFetch`.
|
|
236
|
+
*/
|
|
237
|
+
fetchFn?: FetchFunction
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Default to true.
|
|
241
|
+
* Set to false to not throw on `!Response.ok`, but simply return `Response.body` as-is (json parsed, etc).
|
|
242
|
+
*/
|
|
243
|
+
throwHttpErrors?: boolean
|
|
230
244
|
}
|
|
231
245
|
|
|
232
246
|
export type RequestInitNormalized = Omit<RequestInit, 'method' | 'headers'> & {
|
|
@@ -269,3 +283,10 @@ export type FetcherResponseType =
|
|
|
269
283
|
| 'arrayBuffer'
|
|
270
284
|
| 'blob'
|
|
271
285
|
| 'readableStream'
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Signature for the `fetch` function.
|
|
289
|
+
* Used to be able to override and provide a different implementation,
|
|
290
|
+
* e.g when mocking.
|
|
291
|
+
*/
|
|
292
|
+
export type FetchFunction = (url: string, init: RequestInitNormalized) => Promise<Response>
|
package/src/http/fetcher.ts
CHANGED
|
@@ -286,7 +286,11 @@ export class Fetcher {
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
try {
|
|
289
|
-
|
|
289
|
+
// Calls cfg.fetchFn if set, otherwise Fetcher.callNativeFetch
|
|
290
|
+
res.fetchResponse = await (this.cfg.fetchFn || Fetcher.callNativeFetch)(
|
|
291
|
+
req.fullUrl,
|
|
292
|
+
req.init,
|
|
293
|
+
)
|
|
290
294
|
res.ok = res.fetchResponse.ok
|
|
291
295
|
// important to set it to undefined, otherwise it can keep the previous value (from previous try)
|
|
292
296
|
res.err = undefined
|
|
@@ -304,7 +308,7 @@ export class Fetcher {
|
|
|
304
308
|
res.statusFamily = this.getStatusFamily(res)
|
|
305
309
|
res.statusCode = res.fetchResponse?.status
|
|
306
310
|
|
|
307
|
-
if (res.fetchResponse?.ok) {
|
|
311
|
+
if (res.fetchResponse?.ok || !req.throwHttpErrors) {
|
|
308
312
|
try {
|
|
309
313
|
// We are applying a separate Timeout (as long as original Timeout for now) to "download and parse the body"
|
|
310
314
|
await pTimeout(
|
|
@@ -380,7 +384,7 @@ export class Fetcher {
|
|
|
380
384
|
res.retryStatus.retryStopped = true
|
|
381
385
|
|
|
382
386
|
// res.err can happen on `failed to fetch` type of error, e.g JSON.parse, CORS, unexpected redirect
|
|
383
|
-
if (!res.err && this.cfg.logResponse) {
|
|
387
|
+
if ((!res.err || !req.throwHttpErrors) && this.cfg.logResponse) {
|
|
384
388
|
const { retryAttempt } = res.retryStatus
|
|
385
389
|
const { logger } = this.cfg
|
|
386
390
|
logger.log(
|
|
@@ -650,6 +654,7 @@ export class Fetcher {
|
|
|
650
654
|
redirect: cfg.redirect,
|
|
651
655
|
},
|
|
652
656
|
hooks: {},
|
|
657
|
+
throwHttpErrors: true,
|
|
653
658
|
},
|
|
654
659
|
_omit(cfg, ['method', 'credentials', 'headers', 'redirect', 'logger']),
|
|
655
660
|
)
|
|
@@ -673,6 +678,7 @@ export class Fetcher {
|
|
|
673
678
|
'logResponse',
|
|
674
679
|
'logResponseBody',
|
|
675
680
|
'debug',
|
|
681
|
+
'throwHttpErrors',
|
|
676
682
|
]),
|
|
677
683
|
started: Date.now(),
|
|
678
684
|
..._omit(opt, ['method', 'headers', 'credentials']),
|