@naturalcycles/js-lib 14.140.0 → 14.142.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/array/array.util.d.ts +4 -0
- package/dist/array/array.util.js +46 -1
- package/dist/http/fetcher.d.ts +6 -1
- package/dist/http/fetcher.js +10 -3
- package/dist/string/stringifyAny.js +10 -14
- package/dist/types.d.ts +8 -0
- package/dist-esm/array/array.util.js +41 -0
- package/dist-esm/http/fetcher.js +10 -3
- package/dist-esm/string/stringifyAny.js +10 -14
- package/package.json +1 -1
- package/src/array/array.util.ts +50 -0
- package/src/http/fetcher.ts +11 -3
- package/src/string/stringifyAny.ts +12 -14
- package/src/types.ts +11 -0
|
@@ -159,3 +159,7 @@ export declare function _maxOrUndefined<T>(array: T[]): NonNullable<T> | undefin
|
|
|
159
159
|
* Filters out nullish values (undefined and null).
|
|
160
160
|
*/
|
|
161
161
|
export declare function _max<T>(array: T[]): NonNullable<T>;
|
|
162
|
+
export declare function _maxBy<T>(array: T[], mapper: Mapper<T, number | undefined>): T;
|
|
163
|
+
export declare function _minBy<T>(array: T[], mapper: Mapper<T, number | undefined>): T;
|
|
164
|
+
export declare function _maxByOrUndefined<T>(array: T[], mapper: Mapper<T, number | undefined>): T | undefined;
|
|
165
|
+
export declare function _minByOrUndefined<T>(array: T[], mapper: Mapper<T, number | undefined>): T | undefined;
|
package/dist/array/array.util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._max = exports._maxOrUndefined = exports._min = exports._minOrUndefined = exports._lastOrUndefined = exports._last = exports._shuffle = exports._mapToObject = exports._sumBy = exports._sum = exports._difference = exports._intersection = exports._countBy = exports._dropRightWhile = exports._dropWhile = exports._takeRightWhile = exports._takeWhile = exports._findLast = exports._sortBy = exports._groupBy = exports._by = exports._uniqBy = exports._uniq = exports._flattenDeep = exports._flatten = exports._chunk = void 0;
|
|
3
|
+
exports._minByOrUndefined = exports._maxByOrUndefined = exports._minBy = exports._maxBy = exports._max = exports._maxOrUndefined = exports._min = exports._minOrUndefined = exports._lastOrUndefined = exports._last = exports._shuffle = exports._mapToObject = exports._sumBy = exports._sum = exports._difference = exports._intersection = exports._countBy = exports._dropRightWhile = exports._dropWhile = exports._takeRightWhile = exports._takeWhile = exports._findLast = exports._sortBy = exports._groupBy = exports._by = exports._uniqBy = exports._uniq = exports._flattenDeep = exports._flatten = exports._chunk = void 0;
|
|
4
4
|
const is_util_1 = require("../is.util");
|
|
5
5
|
/**
|
|
6
6
|
* Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the
|
|
@@ -314,3 +314,48 @@ function _max(array) {
|
|
|
314
314
|
return a.reduce((max, item) => (max >= item ? max : item));
|
|
315
315
|
}
|
|
316
316
|
exports._max = _max;
|
|
317
|
+
function _maxBy(array, mapper) {
|
|
318
|
+
const max = _maxByOrUndefined(array, mapper);
|
|
319
|
+
if (max === undefined)
|
|
320
|
+
throw new Error(`_maxBy returned undefined`);
|
|
321
|
+
return max;
|
|
322
|
+
}
|
|
323
|
+
exports._maxBy = _maxBy;
|
|
324
|
+
function _minBy(array, mapper) {
|
|
325
|
+
const min = _minByOrUndefined(array, mapper);
|
|
326
|
+
if (min === undefined)
|
|
327
|
+
throw new Error(`_minBy returned undefined`);
|
|
328
|
+
return min;
|
|
329
|
+
}
|
|
330
|
+
exports._minBy = _minBy;
|
|
331
|
+
// todo: looks like it _maxByOrUndefined/_minByOrUndefined can be DRYer
|
|
332
|
+
function _maxByOrUndefined(array, mapper) {
|
|
333
|
+
if (!array.length)
|
|
334
|
+
return;
|
|
335
|
+
let maxItem;
|
|
336
|
+
let max;
|
|
337
|
+
array.forEach((item, i) => {
|
|
338
|
+
const v = mapper(item, i);
|
|
339
|
+
if (v !== undefined && (max === undefined || v > max)) {
|
|
340
|
+
maxItem = item;
|
|
341
|
+
max = v;
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
return maxItem;
|
|
345
|
+
}
|
|
346
|
+
exports._maxByOrUndefined = _maxByOrUndefined;
|
|
347
|
+
function _minByOrUndefined(array, mapper) {
|
|
348
|
+
if (!array.length)
|
|
349
|
+
return;
|
|
350
|
+
let minItem;
|
|
351
|
+
let min;
|
|
352
|
+
array.forEach((item, i) => {
|
|
353
|
+
const v = mapper(item, i);
|
|
354
|
+
if (v !== undefined && (min === undefined || v < min)) {
|
|
355
|
+
minItem = item;
|
|
356
|
+
min = v;
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
return minItem;
|
|
360
|
+
}
|
|
361
|
+
exports._minByOrUndefined = _minByOrUndefined;
|
package/dist/http/fetcher.d.ts
CHANGED
|
@@ -34,9 +34,14 @@ export declare class Fetcher {
|
|
|
34
34
|
/**
|
|
35
35
|
* Returns FetcherResponse.
|
|
36
36
|
* Never throws, returns `err` property in the response instead.
|
|
37
|
+
* Use this method instead of `throwHttpErrors: false` or try-catching.
|
|
37
38
|
*/
|
|
38
|
-
|
|
39
|
+
doFetch<T = unknown>(url: string, rawOpt?: FetcherOptions): Promise<FetcherResponse<T>>;
|
|
39
40
|
private onOkResponse;
|
|
41
|
+
/**
|
|
42
|
+
* This method exists to be able to easily mock it.
|
|
43
|
+
*/
|
|
44
|
+
callNativeFetch(url: string, init: RequestInit): Promise<Response>;
|
|
40
45
|
private onNotOkResponse;
|
|
41
46
|
private processRetry;
|
|
42
47
|
/**
|
package/dist/http/fetcher.js
CHANGED
|
@@ -78,7 +78,7 @@ class Fetcher {
|
|
|
78
78
|
return new Fetcher(cfg);
|
|
79
79
|
}
|
|
80
80
|
async fetch(url, opt) {
|
|
81
|
-
const res = await this.
|
|
81
|
+
const res = await this.doFetch(url, opt);
|
|
82
82
|
if (res.err) {
|
|
83
83
|
if (res.req.throwHttpErrors)
|
|
84
84
|
throw res.err;
|
|
@@ -89,8 +89,9 @@ class Fetcher {
|
|
|
89
89
|
/**
|
|
90
90
|
* Returns FetcherResponse.
|
|
91
91
|
* Never throws, returns `err` property in the response instead.
|
|
92
|
+
* Use this method instead of `throwHttpErrors: false` or try-catching.
|
|
92
93
|
*/
|
|
93
|
-
async
|
|
94
|
+
async doFetch(url, rawOpt = {}) {
|
|
94
95
|
const { logger } = this.cfg;
|
|
95
96
|
const req = this.normalizeOptions(url, rawOpt);
|
|
96
97
|
const { timeoutSeconds, init: { method }, } = req;
|
|
@@ -131,7 +132,7 @@ class Fetcher {
|
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
134
|
try {
|
|
134
|
-
res.fetchResponse = await
|
|
135
|
+
res.fetchResponse = await this.callNativeFetch(req.url, req.init);
|
|
135
136
|
res.ok = res.fetchResponse.ok;
|
|
136
137
|
}
|
|
137
138
|
catch (err) {
|
|
@@ -215,6 +216,12 @@ class Fetcher {
|
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* This method exists to be able to easily mock it.
|
|
221
|
+
*/
|
|
222
|
+
async callNativeFetch(url, init) {
|
|
223
|
+
return await globalThis.fetch(url, init);
|
|
224
|
+
}
|
|
218
225
|
async onNotOkResponse(res, timeout) {
|
|
219
226
|
clearTimeout(timeout);
|
|
220
227
|
let errObj;
|
|
@@ -69,7 +69,15 @@ function _stringifyAny(obj, opt = {}) {
|
|
|
69
69
|
// if (obj?.name === 'Error') {
|
|
70
70
|
// s = obj.message
|
|
71
71
|
// }
|
|
72
|
-
|
|
72
|
+
if ((0, error_util_1._isErrorObject)(obj) && (0, error_util_1._isHttpErrorObject)(obj)) {
|
|
73
|
+
// Printing (0) to avoid ambiguity
|
|
74
|
+
s = `${obj.name}(${obj.data.httpStatusCode}): ${obj.message}`;
|
|
75
|
+
}
|
|
76
|
+
s ||= [obj.name, obj.message].filter(Boolean).join(': ');
|
|
77
|
+
if (typeof obj.code === 'string') {
|
|
78
|
+
// Error that has no `data`, but has `code` property
|
|
79
|
+
s += `\ncode: ${obj.code}`;
|
|
80
|
+
}
|
|
73
81
|
if (opt.includeErrorStack && obj.stack) {
|
|
74
82
|
// Here we're using the previously-generated "title line" (e.g "Error: some_message"),
|
|
75
83
|
// concatenating it with the Stack (but without the title line of the Stack)
|
|
@@ -79,18 +87,6 @@ function _stringifyAny(obj, opt = {}) {
|
|
|
79
87
|
const sLines = s.split('\n').length;
|
|
80
88
|
s = [s, ...obj.stack.split('\n').slice(sLines)].join('\n');
|
|
81
89
|
}
|
|
82
|
-
if ((0, error_util_1._isErrorObject)(obj)) {
|
|
83
|
-
if ((0, error_util_1._isHttpErrorObject)(obj)) {
|
|
84
|
-
// Only include (statusCode) if it's non-zero
|
|
85
|
-
// No: print (0), as it removes ambiguity
|
|
86
|
-
// `replace` here works ONCE, exactly as we need it
|
|
87
|
-
s = s.replace('HttpError', `HttpError(${obj.data.httpStatusCode})`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
else if (typeof obj.code === 'string') {
|
|
91
|
-
// Error that has no `data`, but has `code` property
|
|
92
|
-
s = [s, `code: ${obj.code}`].join('\n');
|
|
93
|
-
}
|
|
94
90
|
if (supportsAggregateError && obj instanceof AggregateError && obj.errors.length) {
|
|
95
91
|
s = [
|
|
96
92
|
s,
|
|
@@ -99,7 +95,7 @@ function _stringifyAny(obj, opt = {}) {
|
|
|
99
95
|
].join('\n');
|
|
100
96
|
}
|
|
101
97
|
if (obj.cause && includeErrorCause) {
|
|
102
|
-
s = s + '\
|
|
98
|
+
s = s + '\nCaused by: ' + _stringifyAny(obj.cause, opt);
|
|
103
99
|
}
|
|
104
100
|
}
|
|
105
101
|
else if (typeof obj === 'string') {
|
package/dist/types.d.ts
CHANGED
|
@@ -163,13 +163,21 @@ export type UnixTimestampMillisNumber = number;
|
|
|
163
163
|
* @deprecated use UnixTimestampNumber
|
|
164
164
|
*/
|
|
165
165
|
export type UnixTimestamp = number;
|
|
166
|
+
export type NumberOfSeconds = number;
|
|
167
|
+
export type NumberOfMilliseconds = number;
|
|
166
168
|
/**
|
|
167
169
|
* Same as `number`, but with semantic meaning that it's an Integer.
|
|
168
170
|
*/
|
|
169
171
|
export type Integer = number;
|
|
172
|
+
/**
|
|
173
|
+
* Used as a compact representation of truthy value.
|
|
174
|
+
* undefined ('' or other short falsy value) should be used as falsy value.
|
|
175
|
+
*/
|
|
176
|
+
export type ShortBoolean = '1';
|
|
170
177
|
export type Base64String = string;
|
|
171
178
|
export type Base64UrlString = string;
|
|
172
179
|
export type JWTString = string;
|
|
180
|
+
export type SemVerString = string;
|
|
173
181
|
/**
|
|
174
182
|
* Named type for JSON.parse / JSON.stringify second argument
|
|
175
183
|
*/
|
|
@@ -285,3 +285,44 @@ export function _max(array) {
|
|
|
285
285
|
throw new Error('_max called on empty array');
|
|
286
286
|
return a.reduce((max, item) => (max >= item ? max : item));
|
|
287
287
|
}
|
|
288
|
+
export function _maxBy(array, mapper) {
|
|
289
|
+
const max = _maxByOrUndefined(array, mapper);
|
|
290
|
+
if (max === undefined)
|
|
291
|
+
throw new Error(`_maxBy returned undefined`);
|
|
292
|
+
return max;
|
|
293
|
+
}
|
|
294
|
+
export function _minBy(array, mapper) {
|
|
295
|
+
const min = _minByOrUndefined(array, mapper);
|
|
296
|
+
if (min === undefined)
|
|
297
|
+
throw new Error(`_minBy returned undefined`);
|
|
298
|
+
return min;
|
|
299
|
+
}
|
|
300
|
+
// todo: looks like it _maxByOrUndefined/_minByOrUndefined can be DRYer
|
|
301
|
+
export function _maxByOrUndefined(array, mapper) {
|
|
302
|
+
if (!array.length)
|
|
303
|
+
return;
|
|
304
|
+
let maxItem;
|
|
305
|
+
let max;
|
|
306
|
+
array.forEach((item, i) => {
|
|
307
|
+
const v = mapper(item, i);
|
|
308
|
+
if (v !== undefined && (max === undefined || v > max)) {
|
|
309
|
+
maxItem = item;
|
|
310
|
+
max = v;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
return maxItem;
|
|
314
|
+
}
|
|
315
|
+
export function _minByOrUndefined(array, mapper) {
|
|
316
|
+
if (!array.length)
|
|
317
|
+
return;
|
|
318
|
+
let minItem;
|
|
319
|
+
let min;
|
|
320
|
+
array.forEach((item, i) => {
|
|
321
|
+
const v = mapper(item, i);
|
|
322
|
+
if (v !== undefined && (min === undefined || v < min)) {
|
|
323
|
+
minItem = item;
|
|
324
|
+
min = v;
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
return minItem;
|
|
328
|
+
}
|
package/dist-esm/http/fetcher.js
CHANGED
|
@@ -67,7 +67,7 @@ export class Fetcher {
|
|
|
67
67
|
return new Fetcher(cfg);
|
|
68
68
|
}
|
|
69
69
|
async fetch(url, opt) {
|
|
70
|
-
const res = await this.
|
|
70
|
+
const res = await this.doFetch(url, opt);
|
|
71
71
|
if (res.err) {
|
|
72
72
|
if (res.req.throwHttpErrors)
|
|
73
73
|
throw res.err;
|
|
@@ -78,8 +78,9 @@ export class Fetcher {
|
|
|
78
78
|
/**
|
|
79
79
|
* Returns FetcherResponse.
|
|
80
80
|
* Never throws, returns `err` property in the response instead.
|
|
81
|
+
* Use this method instead of `throwHttpErrors: false` or try-catching.
|
|
81
82
|
*/
|
|
82
|
-
async
|
|
83
|
+
async doFetch(url, rawOpt = {}) {
|
|
83
84
|
var _a, e_1, _b, _c, _d, e_2, _e, _f;
|
|
84
85
|
var _g;
|
|
85
86
|
const { logger } = this.cfg;
|
|
@@ -139,7 +140,7 @@ export class Fetcher {
|
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
142
|
try {
|
|
142
|
-
res.fetchResponse = await
|
|
143
|
+
res.fetchResponse = await this.callNativeFetch(req.url, req.init);
|
|
143
144
|
res.ok = res.fetchResponse.ok;
|
|
144
145
|
}
|
|
145
146
|
catch (err) {
|
|
@@ -240,6 +241,12 @@ export class Fetcher {
|
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* This method exists to be able to easily mock it.
|
|
246
|
+
*/
|
|
247
|
+
async callNativeFetch(url, init) {
|
|
248
|
+
return await globalThis.fetch(url, init);
|
|
249
|
+
}
|
|
243
250
|
async onNotOkResponse(res, timeout) {
|
|
244
251
|
var _a, _b;
|
|
245
252
|
clearTimeout(timeout);
|
|
@@ -65,7 +65,15 @@ export function _stringifyAny(obj, opt = {}) {
|
|
|
65
65
|
// if (obj?.name === 'Error') {
|
|
66
66
|
// s = obj.message
|
|
67
67
|
// }
|
|
68
|
-
|
|
68
|
+
if (_isErrorObject(obj) && _isHttpErrorObject(obj)) {
|
|
69
|
+
// Printing (0) to avoid ambiguity
|
|
70
|
+
s = `${obj.name}(${obj.data.httpStatusCode}): ${obj.message}`;
|
|
71
|
+
}
|
|
72
|
+
s || (s = [obj.name, obj.message].filter(Boolean).join(': '));
|
|
73
|
+
if (typeof obj.code === 'string') {
|
|
74
|
+
// Error that has no `data`, but has `code` property
|
|
75
|
+
s += `\ncode: ${obj.code}`;
|
|
76
|
+
}
|
|
69
77
|
if (opt.includeErrorStack && obj.stack) {
|
|
70
78
|
// Here we're using the previously-generated "title line" (e.g "Error: some_message"),
|
|
71
79
|
// concatenating it with the Stack (but without the title line of the Stack)
|
|
@@ -75,18 +83,6 @@ export function _stringifyAny(obj, opt = {}) {
|
|
|
75
83
|
const sLines = s.split('\n').length;
|
|
76
84
|
s = [s, ...obj.stack.split('\n').slice(sLines)].join('\n');
|
|
77
85
|
}
|
|
78
|
-
if (_isErrorObject(obj)) {
|
|
79
|
-
if (_isHttpErrorObject(obj)) {
|
|
80
|
-
// Only include (statusCode) if it's non-zero
|
|
81
|
-
// No: print (0), as it removes ambiguity
|
|
82
|
-
// `replace` here works ONCE, exactly as we need it
|
|
83
|
-
s = s.replace('HttpError', `HttpError(${obj.data.httpStatusCode})`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
else if (typeof obj.code === 'string') {
|
|
87
|
-
// Error that has no `data`, but has `code` property
|
|
88
|
-
s = [s, `code: ${obj.code}`].join('\n');
|
|
89
|
-
}
|
|
90
86
|
if (supportsAggregateError && obj instanceof AggregateError && obj.errors.length) {
|
|
91
87
|
s = [
|
|
92
88
|
s,
|
|
@@ -95,7 +91,7 @@ export function _stringifyAny(obj, opt = {}) {
|
|
|
95
91
|
].join('\n');
|
|
96
92
|
}
|
|
97
93
|
if (obj.cause && includeErrorCause) {
|
|
98
|
-
s = s + '\
|
|
94
|
+
s = s + '\nCaused by: ' + _stringifyAny(obj.cause, opt);
|
|
99
95
|
}
|
|
100
96
|
}
|
|
101
97
|
else if (typeof obj === 'string') {
|
package/package.json
CHANGED
package/src/array/array.util.ts
CHANGED
|
@@ -321,3 +321,53 @@ export function _max<T>(array: T[]): NonNullable<T> {
|
|
|
321
321
|
if (!a.length) throw new Error('_max called on empty array')
|
|
322
322
|
return a.reduce((max, item) => (max >= item ? max : item))
|
|
323
323
|
}
|
|
324
|
+
|
|
325
|
+
export function _maxBy<T>(array: T[], mapper: Mapper<T, number | undefined>): T {
|
|
326
|
+
const max = _maxByOrUndefined(array, mapper)
|
|
327
|
+
if (max === undefined) throw new Error(`_maxBy returned undefined`)
|
|
328
|
+
return max
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export function _minBy<T>(array: T[], mapper: Mapper<T, number | undefined>): T {
|
|
332
|
+
const min = _minByOrUndefined(array, mapper)
|
|
333
|
+
if (min === undefined) throw new Error(`_minBy returned undefined`)
|
|
334
|
+
return min
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// todo: looks like it _maxByOrUndefined/_minByOrUndefined can be DRYer
|
|
338
|
+
|
|
339
|
+
export function _maxByOrUndefined<T>(
|
|
340
|
+
array: T[],
|
|
341
|
+
mapper: Mapper<T, number | undefined>,
|
|
342
|
+
): T | undefined {
|
|
343
|
+
if (!array.length) return
|
|
344
|
+
let maxItem: T | undefined
|
|
345
|
+
let max: number | undefined
|
|
346
|
+
array.forEach((item, i) => {
|
|
347
|
+
const v = mapper(item, i)
|
|
348
|
+
if (v !== undefined && (max === undefined || v > max)) {
|
|
349
|
+
maxItem = item
|
|
350
|
+
max = v
|
|
351
|
+
}
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
return maxItem
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export function _minByOrUndefined<T>(
|
|
358
|
+
array: T[],
|
|
359
|
+
mapper: Mapper<T, number | undefined>,
|
|
360
|
+
): T | undefined {
|
|
361
|
+
if (!array.length) return
|
|
362
|
+
let minItem: T | undefined
|
|
363
|
+
let min: number | undefined
|
|
364
|
+
array.forEach((item, i) => {
|
|
365
|
+
const v = mapper(item, i)
|
|
366
|
+
if (v !== undefined && (min === undefined || v < min)) {
|
|
367
|
+
minItem = item
|
|
368
|
+
min = v
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
return minItem
|
|
373
|
+
}
|
package/src/http/fetcher.ts
CHANGED
|
@@ -129,7 +129,7 @@ export class Fetcher {
|
|
|
129
129
|
headVoid!: (url: string, opt?: FetcherOptions) => Promise<void>
|
|
130
130
|
|
|
131
131
|
async fetch<T = unknown>(url: string, opt?: FetcherOptions): Promise<T> {
|
|
132
|
-
const res = await this.
|
|
132
|
+
const res = await this.doFetch<T>(url, opt)
|
|
133
133
|
if (res.err) {
|
|
134
134
|
if (res.req.throwHttpErrors) throw res.err
|
|
135
135
|
return res as any
|
|
@@ -140,8 +140,9 @@ export class Fetcher {
|
|
|
140
140
|
/**
|
|
141
141
|
* Returns FetcherResponse.
|
|
142
142
|
* Never throws, returns `err` property in the response instead.
|
|
143
|
+
* Use this method instead of `throwHttpErrors: false` or try-catching.
|
|
143
144
|
*/
|
|
144
|
-
async
|
|
145
|
+
async doFetch<T = unknown>(
|
|
145
146
|
url: string,
|
|
146
147
|
rawOpt: FetcherOptions = {},
|
|
147
148
|
): Promise<FetcherResponse<T>> {
|
|
@@ -198,7 +199,7 @@ export class Fetcher {
|
|
|
198
199
|
}
|
|
199
200
|
|
|
200
201
|
try {
|
|
201
|
-
res.fetchResponse = await
|
|
202
|
+
res.fetchResponse = await this.callNativeFetch(req.url, req.init)
|
|
202
203
|
res.ok = res.fetchResponse.ok
|
|
203
204
|
} catch (err) {
|
|
204
205
|
// For example, CORS error would result in "TypeError: failed to fetch" here
|
|
@@ -294,6 +295,13 @@ export class Fetcher {
|
|
|
294
295
|
}
|
|
295
296
|
}
|
|
296
297
|
|
|
298
|
+
/**
|
|
299
|
+
* This method exists to be able to easily mock it.
|
|
300
|
+
*/
|
|
301
|
+
async callNativeFetch(url: string, init: RequestInit): Promise<Response> {
|
|
302
|
+
return await globalThis.fetch(url, init)
|
|
303
|
+
}
|
|
304
|
+
|
|
297
305
|
private async onNotOkResponse(res: FetcherResponse, timeout?: number): Promise<void> {
|
|
298
306
|
clearTimeout(timeout)
|
|
299
307
|
|
|
@@ -103,7 +103,17 @@ export function _stringifyAny(obj: any, opt: StringifyAnyOptions = {}): string {
|
|
|
103
103
|
// if (obj?.name === 'Error') {
|
|
104
104
|
// s = obj.message
|
|
105
105
|
// }
|
|
106
|
-
|
|
106
|
+
if (_isErrorObject(obj) && _isHttpErrorObject(obj)) {
|
|
107
|
+
// Printing (0) to avoid ambiguity
|
|
108
|
+
s = `${obj.name}(${obj.data.httpStatusCode}): ${obj.message}`
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
s ||= [obj.name, obj.message].filter(Boolean).join(': ')
|
|
112
|
+
|
|
113
|
+
if (typeof (obj as any).code === 'string') {
|
|
114
|
+
// Error that has no `data`, but has `code` property
|
|
115
|
+
s += `\ncode: ${(obj as any).code}`
|
|
116
|
+
}
|
|
107
117
|
|
|
108
118
|
if (opt.includeErrorStack && obj.stack) {
|
|
109
119
|
// Here we're using the previously-generated "title line" (e.g "Error: some_message"),
|
|
@@ -116,18 +126,6 @@ export function _stringifyAny(obj: any, opt: StringifyAnyOptions = {}): string {
|
|
|
116
126
|
s = [s, ...obj.stack.split('\n').slice(sLines)].join('\n')
|
|
117
127
|
}
|
|
118
128
|
|
|
119
|
-
if (_isErrorObject(obj)) {
|
|
120
|
-
if (_isHttpErrorObject(obj)) {
|
|
121
|
-
// Only include (statusCode) if it's non-zero
|
|
122
|
-
// No: print (0), as it removes ambiguity
|
|
123
|
-
// `replace` here works ONCE, exactly as we need it
|
|
124
|
-
s = s.replace('HttpError', `HttpError(${obj.data.httpStatusCode})`)
|
|
125
|
-
}
|
|
126
|
-
} else if (typeof (obj as any).code === 'string') {
|
|
127
|
-
// Error that has no `data`, but has `code` property
|
|
128
|
-
s = [s, `code: ${(obj as any).code}`].join('\n')
|
|
129
|
-
}
|
|
130
|
-
|
|
131
129
|
if (supportsAggregateError && obj instanceof AggregateError && obj.errors.length) {
|
|
132
130
|
s = [
|
|
133
131
|
s,
|
|
@@ -137,7 +135,7 @@ export function _stringifyAny(obj: any, opt: StringifyAnyOptions = {}): string {
|
|
|
137
135
|
}
|
|
138
136
|
|
|
139
137
|
if (obj.cause && includeErrorCause) {
|
|
140
|
-
s = s + '\
|
|
138
|
+
s = s + '\nCaused by: ' + _stringifyAny(obj.cause, opt)
|
|
141
139
|
}
|
|
142
140
|
} else if (typeof obj === 'string') {
|
|
143
141
|
//
|
package/src/types.ts
CHANGED
|
@@ -222,15 +222,26 @@ export type UnixTimestampMillisNumber = number
|
|
|
222
222
|
*/
|
|
223
223
|
export type UnixTimestamp = number
|
|
224
224
|
|
|
225
|
+
export type NumberOfSeconds = number
|
|
226
|
+
export type NumberOfMilliseconds = number
|
|
227
|
+
|
|
225
228
|
/**
|
|
226
229
|
* Same as `number`, but with semantic meaning that it's an Integer.
|
|
227
230
|
*/
|
|
228
231
|
export type Integer = number
|
|
229
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Used as a compact representation of truthy value.
|
|
235
|
+
* undefined ('' or other short falsy value) should be used as falsy value.
|
|
236
|
+
*/
|
|
237
|
+
export type ShortBoolean = '1'
|
|
238
|
+
|
|
230
239
|
export type Base64String = string
|
|
231
240
|
export type Base64UrlString = string
|
|
232
241
|
export type JWTString = string
|
|
233
242
|
|
|
243
|
+
export type SemVerString = string
|
|
244
|
+
|
|
234
245
|
/**
|
|
235
246
|
* Named type for JSON.parse / JSON.stringify second argument
|
|
236
247
|
*/
|