@naturalcycles/js-lib 14.251.0 → 14.252.1
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/datetime/localDate.js +1 -0
- package/dist/decorators/debounce.decorator.js +2 -2
- package/dist/decorators/retry.decorator.js +1 -1
- package/dist/define.js +1 -1
- package/dist/error/assert.d.ts +2 -2
- package/dist/error/assert.js +6 -0
- package/dist/error/tryCatch.js +1 -1
- package/dist/http/fetcher.js +19 -10
- package/dist/object/object.util.js +1 -2
- package/dist/promise/pFilter.js +1 -1
- package/dist/promise/pTimeout.js +1 -1
- package/dist/string/safeJsonStringify.js +1 -1
- package/dist-esm/datetime/localDate.js +1 -0
- package/dist-esm/decorators/debounce.decorator.js +2 -2
- package/dist-esm/decorators/retry.decorator.js +1 -1
- package/dist-esm/define.js +1 -1
- package/dist-esm/error/assert.js +6 -1
- package/dist-esm/error/tryCatch.js +1 -1
- package/dist-esm/http/fetcher.js +19 -10
- package/dist-esm/object/object.util.js +1 -2
- package/dist-esm/promise/pFilter.js +1 -1
- package/dist-esm/promise/pTimeout.js +1 -1
- package/dist-esm/string/safeJsonStringify.js +1 -1
- package/package.json +2 -2
- package/src/array/range.ts +1 -1
- package/src/datetime/localDate.ts +1 -0
- package/src/decorators/debounce.decorator.ts +2 -2
- package/src/decorators/retry.decorator.ts +1 -1
- package/src/define.ts +1 -1
- package/src/error/assert.ts +21 -2
- package/src/error/tryCatch.ts +1 -1
- package/src/http/fetcher.ts +17 -10
- package/src/object/object.util.ts +2 -2
- package/src/promise/pFilter.ts +1 -1
- package/src/promise/pTimeout.ts +1 -1
- package/src/string/safeJsonStringify.ts +1 -1
|
@@ -246,6 +246,7 @@ class LocalDate {
|
|
|
246
246
|
return this.plus(-num, 'year');
|
|
247
247
|
}
|
|
248
248
|
plus(num, unit, mutate = false) {
|
|
249
|
+
num = Math.floor(num); // if a fractional number like 0.5 is passed - it will be floored, as LocalDate only deals with "whole days" as minimal unit
|
|
249
250
|
let { day, month, year } = this;
|
|
250
251
|
if (unit === 'week') {
|
|
251
252
|
num *= 7;
|
|
@@ -5,7 +5,7 @@ exports._Throttle = _Throttle;
|
|
|
5
5
|
const debounce_1 = require("./debounce");
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
7
7
|
function _Debounce(wait, opt = {}) {
|
|
8
|
-
return (
|
|
8
|
+
return (_target, _key, descriptor) => {
|
|
9
9
|
const originalFn = descriptor.value;
|
|
10
10
|
descriptor.value = (0, debounce_1._debounce)(originalFn, wait, opt);
|
|
11
11
|
return descriptor;
|
|
@@ -13,7 +13,7 @@ function _Debounce(wait, opt = {}) {
|
|
|
13
13
|
}
|
|
14
14
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
15
15
|
function _Throttle(wait, opt = {}) {
|
|
16
|
-
return (
|
|
16
|
+
return (_target, _key, descriptor) => {
|
|
17
17
|
const originalFn = descriptor.value;
|
|
18
18
|
descriptor.value = (0, debounce_1._throttle)(originalFn, wait, opt);
|
|
19
19
|
return descriptor;
|
|
@@ -4,7 +4,7 @@ exports._Retry = _Retry;
|
|
|
4
4
|
const __1 = require("..");
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
6
6
|
function _Retry(opt = {}) {
|
|
7
|
-
return (
|
|
7
|
+
return (_target, _key, descriptor) => {
|
|
8
8
|
const originalFn = descriptor.value;
|
|
9
9
|
descriptor.value = (0, __1.pRetryFn)(originalFn, opt);
|
|
10
10
|
return descriptor;
|
package/dist/define.js
CHANGED
|
@@ -97,7 +97,7 @@ function _defineProperty(obj, prop, pd) {
|
|
|
97
97
|
* See _defineProperty for exact defaults definition.
|
|
98
98
|
*/
|
|
99
99
|
function _defineProps(obj, props) {
|
|
100
|
-
return Object.defineProperties(obj, (0, object_util_1._mapValues)(props, (
|
|
100
|
+
return Object.defineProperties(obj, (0, object_util_1._mapValues)(props, (_k, pd) => ({
|
|
101
101
|
writable: true,
|
|
102
102
|
configurable: true,
|
|
103
103
|
enumerable: true,
|
package/dist/error/assert.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Class } from '..';
|
|
1
|
+
import { BackendErrorResponseObject, Class, ErrorData, ErrorObject } from '..';
|
|
3
2
|
/**
|
|
4
3
|
* Evaluates the `condition` (casts it to Boolean).
|
|
5
4
|
* Expects it to be truthy, otherwise throws AppError.
|
|
@@ -40,6 +39,7 @@ export declare function _assertIsError<ERR extends Error = Error>(err: any, erro
|
|
|
40
39
|
*/
|
|
41
40
|
export declare function _assertErrorClassOrRethrow<ERR extends Error>(err: any, errorClass: Class<ERR>): asserts err is ERR;
|
|
42
41
|
export declare function _assertIsErrorObject<DATA_TYPE extends ErrorData = ErrorData>(obj: any): asserts obj is ErrorObject<DATA_TYPE>;
|
|
42
|
+
export declare function _assertIsBackendErrorResponseObject<DATA_TYPE extends ErrorData = ErrorData>(obj: any): asserts obj is BackendErrorResponseObject<DATA_TYPE>;
|
|
43
43
|
export declare function _assertIsString(v: any, message?: string): asserts v is string;
|
|
44
44
|
export declare function _assertIsNumber(v: any, message?: string): asserts v is number;
|
|
45
45
|
export declare function _assertTypeOf<T>(v: any, expectedType: string, message?: string): asserts v is T;
|
package/dist/error/assert.js
CHANGED
|
@@ -6,6 +6,7 @@ exports._assertDeepEquals = _assertDeepEquals;
|
|
|
6
6
|
exports._assertIsError = _assertIsError;
|
|
7
7
|
exports._assertErrorClassOrRethrow = _assertErrorClassOrRethrow;
|
|
8
8
|
exports._assertIsErrorObject = _assertIsErrorObject;
|
|
9
|
+
exports._assertIsBackendErrorResponseObject = _assertIsBackendErrorResponseObject;
|
|
9
10
|
exports._assertIsString = _assertIsString;
|
|
10
11
|
exports._assertIsNumber = _assertIsNumber;
|
|
11
12
|
exports._assertTypeOf = _assertTypeOf;
|
|
@@ -89,6 +90,11 @@ function _assertIsErrorObject(obj) {
|
|
|
89
90
|
throw new __1.AssertionError(`Expected to be ErrorObject, actual typeof: ${typeof obj}`);
|
|
90
91
|
}
|
|
91
92
|
}
|
|
93
|
+
function _assertIsBackendErrorResponseObject(obj) {
|
|
94
|
+
if (!(0, __1._isBackendErrorResponseObject)(obj)) {
|
|
95
|
+
throw new __1.AssertionError(`Expected to be BackendErrorResponseObject, actual typeof: ${typeof obj}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
92
98
|
function _assertIsString(v, message) {
|
|
93
99
|
_assertTypeOf(v, 'string', message);
|
|
94
100
|
}
|
package/dist/error/tryCatch.js
CHANGED
|
@@ -38,7 +38,7 @@ function _tryCatch(fn, opt = {}) {
|
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
41
|
-
const _TryCatch = (opt = {}) => (
|
|
41
|
+
const _TryCatch = (opt = {}) => (_target, _key, descriptor) => {
|
|
42
42
|
const originalFn = descriptor.value;
|
|
43
43
|
descriptor.value = _tryCatch(originalFn, opt);
|
|
44
44
|
return descriptor;
|
package/dist/http/fetcher.js
CHANGED
|
@@ -320,23 +320,32 @@ class Fetcher {
|
|
|
320
320
|
}
|
|
321
321
|
async onNotOkResponse(res) {
|
|
322
322
|
let cause;
|
|
323
|
+
// Try to fetch body and attach to res.body
|
|
324
|
+
// (but don't fail if it doesn't work)
|
|
325
|
+
if (!res.body && res.fetchResponse) {
|
|
326
|
+
try {
|
|
327
|
+
res.body = (0, json_util_1._jsonParseIfPossible)(await res.fetchResponse.text());
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
// ignore body fetching/parsing errors at this point
|
|
331
|
+
}
|
|
332
|
+
}
|
|
323
333
|
if (res.err) {
|
|
324
334
|
// This is only possible on JSON.parse error, or CORS error,
|
|
325
335
|
// or `unexpected redirect`
|
|
326
336
|
// This check should go first, to avoid calling .text() twice (which will fail)
|
|
327
337
|
cause = (0, error_util_1._errorLikeToErrorObject)(res.err);
|
|
328
338
|
}
|
|
329
|
-
else if (res.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
339
|
+
else if (res.body) {
|
|
340
|
+
cause = (0, error_util_1._anyToErrorObject)(res.body);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
cause = {
|
|
344
|
+
name: 'Error',
|
|
345
|
+
message: 'Fetch failed',
|
|
346
|
+
data: {},
|
|
347
|
+
};
|
|
334
348
|
}
|
|
335
|
-
cause ||= {
|
|
336
|
-
name: 'Error',
|
|
337
|
-
message: 'Fetch failed',
|
|
338
|
-
data: {},
|
|
339
|
-
};
|
|
340
349
|
let responseStatusCode = res.fetchResponse?.status || 0;
|
|
341
350
|
if (res.statusFamily === 2) {
|
|
342
351
|
// important to reset responseStatusCode to 0 in this case, as status 2xx can be misleading
|
|
@@ -308,7 +308,6 @@ function _unset(obj, prop) {
|
|
|
308
308
|
if (!(0, is_util_1._isObject)(obj)) {
|
|
309
309
|
return;
|
|
310
310
|
}
|
|
311
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
312
311
|
if (obj.hasOwnProperty(prop)) {
|
|
313
312
|
delete obj[prop];
|
|
314
313
|
return;
|
|
@@ -426,7 +425,7 @@ function _has(obj, path) {
|
|
|
426
425
|
function _deepFreeze(o) {
|
|
427
426
|
Object.freeze(o);
|
|
428
427
|
Object.getOwnPropertyNames(o).forEach(prop => {
|
|
429
|
-
if (o.hasOwnProperty(prop) &&
|
|
428
|
+
if (o.hasOwnProperty(prop) &&
|
|
430
429
|
o[prop] !== null &&
|
|
431
430
|
(typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
|
|
432
431
|
!Object.isFrozen(o[prop])) {
|
package/dist/promise/pFilter.js
CHANGED
|
@@ -4,5 +4,5 @@ exports.pFilter = pFilter;
|
|
|
4
4
|
async function pFilter(iterable, filterFn) {
|
|
5
5
|
const items = [...iterable];
|
|
6
6
|
const predicates = await Promise.all(items.map((item, i) => filterFn(item, i)));
|
|
7
|
-
return items.filter((
|
|
7
|
+
return items.filter((_item, i) => predicates[i]);
|
|
8
8
|
}
|
package/dist/promise/pTimeout.js
CHANGED
|
@@ -33,7 +33,7 @@ async function pTimeout(fn, opt) {
|
|
|
33
33
|
}
|
|
34
34
|
const { timeout, name = fn.name || 'pTimeout function', onTimeout } = opt;
|
|
35
35
|
const fakeError = opt.fakeError || new Error('TimeoutError');
|
|
36
|
-
//
|
|
36
|
+
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: ok
|
|
37
37
|
return await new Promise(async (resolve, reject) => {
|
|
38
38
|
// Prepare the timeout timer
|
|
39
39
|
const timer = setTimeout(() => {
|
|
@@ -20,7 +20,7 @@ function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
|
|
|
20
20
|
function serializer(replacer, cycleReplacer) {
|
|
21
21
|
const stack = [];
|
|
22
22
|
const keys = [];
|
|
23
|
-
cycleReplacer ??= (
|
|
23
|
+
cycleReplacer ??= (_key, value) => {
|
|
24
24
|
if (stack[0] === value)
|
|
25
25
|
return '[Circular ~]';
|
|
26
26
|
return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
|
|
@@ -243,6 +243,7 @@ export class LocalDate {
|
|
|
243
243
|
return this.plus(-num, 'year');
|
|
244
244
|
}
|
|
245
245
|
plus(num, unit, mutate = false) {
|
|
246
|
+
num = Math.floor(num); // if a fractional number like 0.5 is passed - it will be floored, as LocalDate only deals with "whole days" as minimal unit
|
|
246
247
|
let { day, month, year } = this;
|
|
247
248
|
if (unit === 'week') {
|
|
248
249
|
num *= 7;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _debounce, _throttle } from './debounce';
|
|
2
2
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3
3
|
export function _Debounce(wait, opt = {}) {
|
|
4
|
-
return (
|
|
4
|
+
return (_target, _key, descriptor) => {
|
|
5
5
|
const originalFn = descriptor.value;
|
|
6
6
|
descriptor.value = _debounce(originalFn, wait, opt);
|
|
7
7
|
return descriptor;
|
|
@@ -9,7 +9,7 @@ export function _Debounce(wait, opt = {}) {
|
|
|
9
9
|
}
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
11
11
|
export function _Throttle(wait, opt = {}) {
|
|
12
|
-
return (
|
|
12
|
+
return (_target, _key, descriptor) => {
|
|
13
13
|
const originalFn = descriptor.value;
|
|
14
14
|
descriptor.value = _throttle(originalFn, wait, opt);
|
|
15
15
|
return descriptor;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { pRetryFn } from '..';
|
|
2
2
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3
3
|
export function _Retry(opt = {}) {
|
|
4
|
-
return (
|
|
4
|
+
return (_target, _key, descriptor) => {
|
|
5
5
|
const originalFn = descriptor.value;
|
|
6
6
|
descriptor.value = pRetryFn(originalFn, opt);
|
|
7
7
|
return descriptor;
|
package/dist-esm/define.js
CHANGED
|
@@ -89,7 +89,7 @@ export function _defineProperty(obj, prop, pd) {
|
|
|
89
89
|
* See _defineProperty for exact defaults definition.
|
|
90
90
|
*/
|
|
91
91
|
export function _defineProps(obj, props) {
|
|
92
|
-
return Object.defineProperties(obj, _mapValues(props, (
|
|
92
|
+
return Object.defineProperties(obj, _mapValues(props, (_k, pd) => ({
|
|
93
93
|
writable: true,
|
|
94
94
|
configurable: true,
|
|
95
95
|
enumerable: true,
|
package/dist-esm/error/assert.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _deepEquals, _isErrorObject, _stringify, AssertionError } from '..';
|
|
1
|
+
import { _deepEquals, _isBackendErrorResponseObject, _isErrorObject, _stringify, AssertionError, } from '..';
|
|
2
2
|
/**
|
|
3
3
|
* Evaluates the `condition` (casts it to Boolean).
|
|
4
4
|
* Expects it to be truthy, otherwise throws AppError.
|
|
@@ -78,6 +78,11 @@ export function _assertIsErrorObject(obj) {
|
|
|
78
78
|
throw new AssertionError(`Expected to be ErrorObject, actual typeof: ${typeof obj}`);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
+
export function _assertIsBackendErrorResponseObject(obj) {
|
|
82
|
+
if (!_isBackendErrorResponseObject(obj)) {
|
|
83
|
+
throw new AssertionError(`Expected to be BackendErrorResponseObject, actual typeof: ${typeof obj}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
81
86
|
export function _assertIsString(v, message) {
|
|
82
87
|
_assertTypeOf(v, 'string', message);
|
|
83
88
|
}
|
|
@@ -34,7 +34,7 @@ export function _tryCatch(fn, opt = {}) {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
37
|
-
export const _TryCatch = (opt = {}) => (
|
|
37
|
+
export const _TryCatch = (opt = {}) => (_target, _key, descriptor) => {
|
|
38
38
|
const originalFn = descriptor.value;
|
|
39
39
|
descriptor.value = _tryCatch(originalFn, opt);
|
|
40
40
|
return descriptor;
|
package/dist-esm/http/fetcher.js
CHANGED
|
@@ -312,23 +312,32 @@ export class Fetcher {
|
|
|
312
312
|
}
|
|
313
313
|
async onNotOkResponse(res) {
|
|
314
314
|
let cause;
|
|
315
|
+
// Try to fetch body and attach to res.body
|
|
316
|
+
// (but don't fail if it doesn't work)
|
|
317
|
+
if (!res.body && res.fetchResponse) {
|
|
318
|
+
try {
|
|
319
|
+
res.body = _jsonParseIfPossible(await res.fetchResponse.text());
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
// ignore body fetching/parsing errors at this point
|
|
323
|
+
}
|
|
324
|
+
}
|
|
315
325
|
if (res.err) {
|
|
316
326
|
// This is only possible on JSON.parse error, or CORS error,
|
|
317
327
|
// or `unexpected redirect`
|
|
318
328
|
// This check should go first, to avoid calling .text() twice (which will fail)
|
|
319
329
|
cause = _errorLikeToErrorObject(res.err);
|
|
320
330
|
}
|
|
321
|
-
else if (res.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
331
|
+
else if (res.body) {
|
|
332
|
+
cause = _anyToErrorObject(res.body);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
cause = {
|
|
336
|
+
name: 'Error',
|
|
337
|
+
message: 'Fetch failed',
|
|
338
|
+
data: {},
|
|
339
|
+
};
|
|
326
340
|
}
|
|
327
|
-
cause || (cause = {
|
|
328
|
-
name: 'Error',
|
|
329
|
-
message: 'Fetch failed',
|
|
330
|
-
data: {},
|
|
331
|
-
});
|
|
332
341
|
let responseStatusCode = res.fetchResponse?.status || 0;
|
|
333
342
|
if (res.statusFamily === 2) {
|
|
334
343
|
// important to reset responseStatusCode to 0 in this case, as status 2xx can be misleading
|
|
@@ -279,7 +279,6 @@ export function _unset(obj, prop) {
|
|
|
279
279
|
if (!_isObject(obj)) {
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
283
282
|
if (obj.hasOwnProperty(prop)) {
|
|
284
283
|
delete obj[prop];
|
|
285
284
|
return;
|
|
@@ -397,7 +396,7 @@ export function _has(obj, path) {
|
|
|
397
396
|
export function _deepFreeze(o) {
|
|
398
397
|
Object.freeze(o);
|
|
399
398
|
Object.getOwnPropertyNames(o).forEach(prop => {
|
|
400
|
-
if (o.hasOwnProperty(prop) &&
|
|
399
|
+
if (o.hasOwnProperty(prop) &&
|
|
401
400
|
o[prop] !== null &&
|
|
402
401
|
(typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
|
|
403
402
|
!Object.isFrozen(o[prop])) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function pFilter(iterable, filterFn) {
|
|
2
2
|
const items = [...iterable];
|
|
3
3
|
const predicates = await Promise.all(items.map((item, i) => filterFn(item, i)));
|
|
4
|
-
return items.filter((
|
|
4
|
+
return items.filter((_item, i) => predicates[i]);
|
|
5
5
|
}
|
|
@@ -29,7 +29,7 @@ export async function pTimeout(fn, opt) {
|
|
|
29
29
|
}
|
|
30
30
|
const { timeout, name = fn.name || 'pTimeout function', onTimeout } = opt;
|
|
31
31
|
const fakeError = opt.fakeError || new Error('TimeoutError');
|
|
32
|
-
//
|
|
32
|
+
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: ok
|
|
33
33
|
return await new Promise(async (resolve, reject) => {
|
|
34
34
|
// Prepare the timeout timer
|
|
35
35
|
const timer = setTimeout(() => {
|
|
@@ -17,7 +17,7 @@ export function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
|
|
|
17
17
|
function serializer(replacer, cycleReplacer) {
|
|
18
18
|
const stack = [];
|
|
19
19
|
const keys = [];
|
|
20
|
-
cycleReplacer ?? (cycleReplacer = (
|
|
20
|
+
cycleReplacer ?? (cycleReplacer = (_key, value) => {
|
|
21
21
|
if (stack[0] === value)
|
|
22
22
|
return '[Circular ~]';
|
|
23
23
|
return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/js-lib",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.252.1",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky",
|
|
6
6
|
"build": "dev-lib build-esm-cjs",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"types": "dist/index.d.ts",
|
|
47
47
|
"sideEffects": false,
|
|
48
48
|
"engines": {
|
|
49
|
-
"node": ">=
|
|
49
|
+
"node": ">=20.13.0"
|
|
50
50
|
},
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"provenance": true,
|
package/src/array/range.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AsyncIterable2 } from '../iter/asyncIterable2'
|
|
2
2
|
import { Iterable2 } from '../iter/iterable2'
|
|
3
3
|
|
|
4
|
-
/* eslint-disable
|
|
4
|
+
/* eslint-disable unicorn/no-new-array */
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Returns an array with ranges from `from` up to (but not including) `to`.
|
|
@@ -287,6 +287,7 @@ export class LocalDate {
|
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
plus(num: number, unit: LocalDateUnit, mutate = false): LocalDate {
|
|
290
|
+
num = Math.floor(num) // if a fractional number like 0.5 is passed - it will be floored, as LocalDate only deals with "whole days" as minimal unit
|
|
290
291
|
let { day, month, year } = this
|
|
291
292
|
|
|
292
293
|
if (unit === 'week') {
|
|
@@ -3,7 +3,7 @@ import { _debounce, _throttle } from './debounce'
|
|
|
3
3
|
|
|
4
4
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
5
5
|
export function _Debounce(wait: number, opt: DebounceOptions = {}): MethodDecorator {
|
|
6
|
-
return (
|
|
6
|
+
return (_target, _key, descriptor) => {
|
|
7
7
|
const originalFn = descriptor.value
|
|
8
8
|
descriptor.value = _debounce(originalFn as any, wait, opt)
|
|
9
9
|
return descriptor
|
|
@@ -12,7 +12,7 @@ export function _Debounce(wait: number, opt: DebounceOptions = {}): MethodDecora
|
|
|
12
12
|
|
|
13
13
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
14
14
|
export function _Throttle(wait: number, opt: ThrottleOptions = {}): MethodDecorator {
|
|
15
|
-
return (
|
|
15
|
+
return (_target, _key, descriptor) => {
|
|
16
16
|
const originalFn = descriptor.value
|
|
17
17
|
descriptor.value = _throttle(originalFn as any, wait, opt)
|
|
18
18
|
return descriptor
|
|
@@ -3,7 +3,7 @@ import { pRetryFn } from '..'
|
|
|
3
3
|
|
|
4
4
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
5
5
|
export function _Retry(opt: PRetryOptions = {}): MethodDecorator {
|
|
6
|
-
return (
|
|
6
|
+
return (_target, _key, descriptor) => {
|
|
7
7
|
const originalFn = descriptor.value
|
|
8
8
|
descriptor.value = pRetryFn(originalFn as any, opt)
|
|
9
9
|
return descriptor
|
package/src/define.ts
CHANGED
package/src/error/assert.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
_deepEquals,
|
|
3
|
+
_isBackendErrorResponseObject,
|
|
4
|
+
_isErrorObject,
|
|
5
|
+
_stringify,
|
|
6
|
+
AssertionError,
|
|
7
|
+
BackendErrorResponseObject,
|
|
8
|
+
Class,
|
|
9
|
+
ErrorData,
|
|
10
|
+
ErrorObject,
|
|
11
|
+
} from '..'
|
|
3
12
|
|
|
4
13
|
/**
|
|
5
14
|
* Evaluates the `condition` (casts it to Boolean).
|
|
@@ -113,6 +122,16 @@ export function _assertIsErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
|
|
|
113
122
|
}
|
|
114
123
|
}
|
|
115
124
|
|
|
125
|
+
export function _assertIsBackendErrorResponseObject<DATA_TYPE extends ErrorData = ErrorData>(
|
|
126
|
+
obj: any,
|
|
127
|
+
): asserts obj is BackendErrorResponseObject<DATA_TYPE> {
|
|
128
|
+
if (!_isBackendErrorResponseObject(obj)) {
|
|
129
|
+
throw new AssertionError(
|
|
130
|
+
`Expected to be BackendErrorResponseObject, actual typeof: ${typeof obj}`,
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
116
135
|
export function _assertIsString(v: any, message?: string): asserts v is string {
|
|
117
136
|
_assertTypeOf<string>(v, 'string', message)
|
|
118
137
|
}
|
package/src/error/tryCatch.ts
CHANGED
|
@@ -67,7 +67,7 @@ export function _tryCatch<T extends AnyFunction>(fn: T, opt: TryCatchOptions = {
|
|
|
67
67
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
68
68
|
export const _TryCatch =
|
|
69
69
|
(opt: TryCatchOptions = {}): MethodDecorator =>
|
|
70
|
-
(
|
|
70
|
+
(_target, _key, descriptor) => {
|
|
71
71
|
const originalFn = descriptor.value
|
|
72
72
|
descriptor.value = _tryCatch(originalFn as any, opt)
|
|
73
73
|
return descriptor
|
package/src/http/fetcher.ts
CHANGED
|
@@ -416,24 +416,31 @@ export class Fetcher {
|
|
|
416
416
|
private async onNotOkResponse(res: FetcherResponse): Promise<void> {
|
|
417
417
|
let cause: ErrorObject
|
|
418
418
|
|
|
419
|
+
// Try to fetch body and attach to res.body
|
|
420
|
+
// (but don't fail if it doesn't work)
|
|
421
|
+
if (!res.body && res.fetchResponse) {
|
|
422
|
+
try {
|
|
423
|
+
res.body = _jsonParseIfPossible(await res.fetchResponse.text())
|
|
424
|
+
} catch {
|
|
425
|
+
// ignore body fetching/parsing errors at this point
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
419
429
|
if (res.err) {
|
|
420
430
|
// This is only possible on JSON.parse error, or CORS error,
|
|
421
431
|
// or `unexpected redirect`
|
|
422
432
|
// This check should go first, to avoid calling .text() twice (which will fail)
|
|
423
433
|
cause = _errorLikeToErrorObject(res.err)
|
|
424
|
-
} else if (res.
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
434
|
+
} else if (res.body) {
|
|
435
|
+
cause = _anyToErrorObject(res.body)
|
|
436
|
+
} else {
|
|
437
|
+
cause = {
|
|
438
|
+
name: 'Error',
|
|
439
|
+
message: 'Fetch failed',
|
|
440
|
+
data: {},
|
|
428
441
|
}
|
|
429
442
|
}
|
|
430
443
|
|
|
431
|
-
cause ||= {
|
|
432
|
-
name: 'Error',
|
|
433
|
-
message: 'Fetch failed',
|
|
434
|
-
data: {},
|
|
435
|
-
}
|
|
436
|
-
|
|
437
444
|
let responseStatusCode = res.fetchResponse?.status || 0
|
|
438
445
|
if (res.statusFamily === 2) {
|
|
439
446
|
// important to reset responseStatusCode to 0 in this case, as status 2xx can be misleading
|
|
@@ -332,7 +332,7 @@ export function _unset<T extends AnyObject>(obj: T, prop: string): void {
|
|
|
332
332
|
if (!_isObject(obj)) {
|
|
333
333
|
return
|
|
334
334
|
}
|
|
335
|
-
|
|
335
|
+
|
|
336
336
|
if (obj.hasOwnProperty(prop)) {
|
|
337
337
|
delete obj[prop]
|
|
338
338
|
return
|
|
@@ -470,7 +470,7 @@ export function _deepFreeze(o: any): void {
|
|
|
470
470
|
|
|
471
471
|
Object.getOwnPropertyNames(o).forEach(prop => {
|
|
472
472
|
if (
|
|
473
|
-
o.hasOwnProperty(prop) &&
|
|
473
|
+
o.hasOwnProperty(prop) &&
|
|
474
474
|
o[prop] !== null &&
|
|
475
475
|
(typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
|
|
476
476
|
!Object.isFrozen(o[prop])
|
package/src/promise/pFilter.ts
CHANGED
|
@@ -3,5 +3,5 @@ import type { AsyncPredicate } from '../types'
|
|
|
3
3
|
export async function pFilter<T>(iterable: Iterable<T>, filterFn: AsyncPredicate<T>): Promise<T[]> {
|
|
4
4
|
const items = [...iterable]
|
|
5
5
|
const predicates = await Promise.all(items.map((item, i) => filterFn(item, i)))
|
|
6
|
-
return items.filter((
|
|
6
|
+
return items.filter((_item, i) => predicates[i])
|
|
7
7
|
}
|
package/src/promise/pTimeout.ts
CHANGED
|
@@ -72,7 +72,7 @@ export async function pTimeout<T>(fn: AnyAsyncFunction<T>, opt: PTimeoutOptions)
|
|
|
72
72
|
const { timeout, name = fn.name || 'pTimeout function', onTimeout } = opt
|
|
73
73
|
const fakeError = opt.fakeError || new Error('TimeoutError')
|
|
74
74
|
|
|
75
|
-
//
|
|
75
|
+
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: ok
|
|
76
76
|
return await new Promise(async (resolve, reject) => {
|
|
77
77
|
// Prepare the timeout timer
|
|
78
78
|
const timer = setTimeout(() => {
|
|
@@ -26,7 +26,7 @@ function serializer(replacer?: Reviver, cycleReplacer?: Reviver): Reviver {
|
|
|
26
26
|
const stack: any[] = []
|
|
27
27
|
const keys: string[] = []
|
|
28
28
|
|
|
29
|
-
cycleReplacer ??= (
|
|
29
|
+
cycleReplacer ??= (_key, value) => {
|
|
30
30
|
if (stack[0] === value) return '[Circular ~]'
|
|
31
31
|
return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'
|
|
32
32
|
}
|