@naturalcycles/js-lib 14.159.0 → 14.161.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/{lazy.d.ts → define.d.ts} +26 -0
- package/dist/define.js +118 -0
- package/dist/error/app.error.d.ts +16 -3
- package/dist/error/app.error.js +22 -19
- package/dist/error/assert.d.ts +1 -1
- package/dist/error/assert.js +2 -2
- package/dist/error/error.model.d.ts +7 -0
- package/dist/error/error.util.js +29 -22
- package/dist/error/httpRequestError.d.ts +2 -2
- package/dist/error/httpRequestError.js +7 -2
- package/dist/error/jsonParseError.d.ts +2 -2
- package/dist/error/jsonParseError.js +5 -2
- package/dist/error/try.js +3 -1
- package/dist/http/fetcher.js +6 -3
- package/dist/http/fetcher.model.d.ts +1 -0
- package/dist/http/fetcher.model.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/object/object.util.d.ts +16 -11
- package/dist/object/object.util.js +29 -12
- package/dist/promise/pTimeout.d.ts +3 -3
- package/dist/promise/pTimeout.js +2 -2
- package/dist/types.d.ts +9 -2
- package/dist/types.js +9 -2
- package/dist-esm/{lazy.js → define.js} +38 -0
- package/dist-esm/error/app.error.js +22 -19
- package/dist-esm/error/assert.js +2 -2
- package/dist-esm/error/error.util.js +30 -23
- package/dist-esm/error/httpRequestError.js +7 -2
- package/dist-esm/error/jsonParseError.js +5 -2
- package/dist-esm/error/try.js +3 -1
- package/dist-esm/http/fetcher.js +6 -3
- package/dist-esm/http/fetcher.model.js +1 -0
- package/dist-esm/index.js +1 -1
- package/dist-esm/object/object.util.js +27 -11
- package/dist-esm/promise/pTimeout.js +2 -2
- package/dist-esm/types.js +8 -1
- package/package.json +1 -1
- package/src/{lazy.ts → define.ts} +68 -0
- package/src/error/app.error.ts +39 -22
- package/src/error/assert.ts +2 -2
- package/src/error/error.model.ts +8 -0
- package/src/error/error.util.ts +31 -25
- package/src/error/httpRequestError.ts +9 -3
- package/src/error/jsonParseError.ts +7 -8
- package/src/error/try.ts +7 -1
- package/src/http/fetcher.model.ts +2 -0
- package/src/http/fetcher.ts +6 -3
- package/src/index.ts +1 -1
- package/src/object/object.util.ts +51 -30
- package/src/promise/pTimeout.ts +4 -4
- package/src/types.ts +12 -2
- package/dist/lazy.js +0 -65
package/src/error/error.util.ts
CHANGED
|
@@ -109,41 +109,47 @@ export function _errorObjectToError<DATA_TYPE extends ErrorData, ERROR_TYPE exte
|
|
|
109
109
|
): ERROR_TYPE {
|
|
110
110
|
if (o instanceof errorClass) return o
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
// Here we pass constructor values assuming it's AppError or sub-class of it
|
|
113
|
+
// If not - will be checked at the next step
|
|
114
|
+
// We cannot check `if (errorClass instanceof AppError)`, only `err instanceof AppError`
|
|
115
|
+
const { name, cause } = o
|
|
116
|
+
const err = new errorClass(o.message, o.data, { name, cause })
|
|
113
117
|
// name: err.name, // cannot be assigned to a readonly property like this
|
|
114
118
|
// stack: o.stack, // also readonly e.g in Firefox
|
|
115
119
|
|
|
116
|
-
Object.defineProperty(err, 'name', {
|
|
117
|
-
value: o.name,
|
|
118
|
-
configurable: true,
|
|
119
|
-
writable: true,
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
Object.defineProperty(err.constructor, 'name', {
|
|
123
|
-
value: o.name,
|
|
124
|
-
configurable: true,
|
|
125
|
-
writable: true,
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
Object.defineProperty(err, 'data', {
|
|
129
|
-
value: o.data,
|
|
130
|
-
writable: true,
|
|
131
|
-
configurable: true,
|
|
132
|
-
enumerable: false,
|
|
133
|
-
})
|
|
134
|
-
|
|
135
120
|
if (o.stack) {
|
|
136
121
|
Object.defineProperty(err, 'stack', {
|
|
137
122
|
value: o.stack,
|
|
138
123
|
})
|
|
139
124
|
}
|
|
140
125
|
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
126
|
+
if (!(err instanceof AppError)) {
|
|
127
|
+
// Following actions are only needed for non-AppError-like errors
|
|
128
|
+
|
|
129
|
+
Object.defineProperties(err, {
|
|
130
|
+
name: {
|
|
131
|
+
value: name,
|
|
132
|
+
configurable: true,
|
|
133
|
+
writable: true,
|
|
134
|
+
},
|
|
135
|
+
data: {
|
|
136
|
+
value: o.data,
|
|
137
|
+
writable: true,
|
|
138
|
+
configurable: true,
|
|
139
|
+
enumerable: false,
|
|
140
|
+
},
|
|
141
|
+
cause: {
|
|
142
|
+
value: cause,
|
|
143
|
+
writable: true,
|
|
144
|
+
configurable: true,
|
|
145
|
+
enumerable: true,
|
|
146
|
+
},
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
Object.defineProperty(err.constructor, 'name', {
|
|
150
|
+
value: name,
|
|
145
151
|
configurable: true,
|
|
146
|
-
|
|
152
|
+
writable: true,
|
|
147
153
|
})
|
|
148
154
|
}
|
|
149
155
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppError } from './app.error'
|
|
1
|
+
import { AppError, AppErrorOptions } from './app.error'
|
|
2
2
|
import type { ErrorObject, HttpRequestErrorData } from './error.model'
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -19,8 +19,14 @@ import type { ErrorObject, HttpRequestErrorData } from './error.model'
|
|
|
19
19
|
* (by default).
|
|
20
20
|
*/
|
|
21
21
|
export class HttpRequestError extends AppError<HttpRequestErrorData> {
|
|
22
|
-
constructor(message: string, data: HttpRequestErrorData,
|
|
23
|
-
|
|
22
|
+
constructor(message: string, data: HttpRequestErrorData, opt?: AppErrorOptions) {
|
|
23
|
+
if (data.response) {
|
|
24
|
+
Object.defineProperty(data, 'response', {
|
|
25
|
+
enumerable: false,
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
super(message, data, { ...opt, name: 'HttpRequestError' })
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _truncateMiddle } from '../string/string.util'
|
|
2
2
|
import { AppError } from './app.error'
|
|
3
|
-
import { ErrorData
|
|
3
|
+
import { ErrorData } from './error.model'
|
|
4
4
|
|
|
5
5
|
export interface JsonParseErrorData extends ErrorData {
|
|
6
6
|
/**
|
|
@@ -10,12 +10,11 @@ export interface JsonParseErrorData extends ErrorData {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export class JsonParseError extends AppError<JsonParseErrorData> {
|
|
13
|
-
constructor(data: JsonParseErrorData
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
)
|
|
13
|
+
constructor(data: JsonParseErrorData) {
|
|
14
|
+
const message = ['Failed to parse', data.text && _truncateMiddle(data.text, 200)]
|
|
15
|
+
.filter(Boolean)
|
|
16
|
+
.join(': ')
|
|
17
|
+
|
|
18
|
+
super(message, data, { name: 'JsonParseError' })
|
|
20
19
|
}
|
|
21
20
|
}
|
package/src/error/try.ts
CHANGED
|
@@ -62,7 +62,13 @@ export async function pTry<T, ERR extends Error = Error>(
|
|
|
62
62
|
*/
|
|
63
63
|
export class UnexpectedPassError extends AppError {
|
|
64
64
|
constructor() {
|
|
65
|
-
super(
|
|
65
|
+
super(
|
|
66
|
+
'expected error was not thrown',
|
|
67
|
+
{},
|
|
68
|
+
{
|
|
69
|
+
name: 'UnexpectedPassError',
|
|
70
|
+
},
|
|
71
|
+
)
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
|
package/src/http/fetcher.ts
CHANGED
|
@@ -395,6 +395,7 @@ export class Fetcher {
|
|
|
395
395
|
res.err = new HttpRequestError(
|
|
396
396
|
message,
|
|
397
397
|
_filterNullishValues({
|
|
398
|
+
response: res.fetchResponse,
|
|
398
399
|
responseStatusCode: res.fetchResponse?.status || 0,
|
|
399
400
|
// These properties are provided to be used in e.g custom Sentry error grouping
|
|
400
401
|
// Actually, disabled now, to avoid unnecessary error printing when both msg and data are printed
|
|
@@ -402,12 +403,14 @@ export class Fetcher {
|
|
|
402
403
|
// method: req.method,
|
|
403
404
|
// tryCount: req.tryCount,
|
|
404
405
|
requestUrl: res.req.fullUrl,
|
|
405
|
-
requestBaseUrl: this.cfg.baseUrl ||
|
|
406
|
+
requestBaseUrl: this.cfg.baseUrl || undefined,
|
|
406
407
|
requestMethod: res.req.init.method,
|
|
407
408
|
requestSignature: res.signature,
|
|
408
409
|
requestDuration: Date.now() - res.req.started,
|
|
409
410
|
}),
|
|
410
|
-
|
|
411
|
+
{
|
|
412
|
+
cause,
|
|
413
|
+
},
|
|
411
414
|
)
|
|
412
415
|
|
|
413
416
|
await this.processRetry(res)
|
|
@@ -660,7 +663,7 @@ export class Fetcher {
|
|
|
660
663
|
|
|
661
664
|
if (Object.keys(searchParams).length) {
|
|
662
665
|
const qs = new URLSearchParams(searchParams).toString()
|
|
663
|
-
req.fullUrl += req.fullUrl.includes('?') ? '&' : '?' + qs
|
|
666
|
+
req.fullUrl += (req.fullUrl.includes('?') ? '&' : '?') + qs
|
|
664
667
|
}
|
|
665
668
|
|
|
666
669
|
// setup request body
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _isEmpty, _isObject } from '../is.util'
|
|
2
2
|
import type { PropertyPath } from '../lodash.types'
|
|
3
|
-
import
|
|
3
|
+
import { _objectEntries, KeyValueTuple, SKIP } from '../types'
|
|
4
|
+
import type { AnyObject, ObjectMapper, ObjectPredicate, ValueOf } from '../types'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Returns clone of `obj` with only `props` preserved.
|
|
@@ -111,24 +112,22 @@ export function _filterObject<T extends AnyObject>(
|
|
|
111
112
|
* 'pebbles': { 'user': 'pebbles', 'age': 1 }
|
|
112
113
|
* }
|
|
113
114
|
*
|
|
114
|
-
*
|
|
115
|
+
* _mapValues(users, (_key, value) => value.age)
|
|
115
116
|
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
|
116
117
|
*
|
|
117
|
-
*
|
|
118
|
-
* _.mapValues(users, 'age')
|
|
119
|
-
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
|
118
|
+
* To skip some key-value pairs - use _mapObject instead.
|
|
120
119
|
*/
|
|
121
|
-
export function _mapValues<T extends AnyObject
|
|
120
|
+
export function _mapValues<T extends AnyObject>(
|
|
122
121
|
obj: T,
|
|
123
122
|
mapper: ObjectMapper<T, any>,
|
|
124
123
|
mutate = false,
|
|
125
|
-
):
|
|
126
|
-
return
|
|
124
|
+
): T {
|
|
125
|
+
return _objectEntries(obj).reduce(
|
|
127
126
|
(map, [k, v]) => {
|
|
128
|
-
map[k
|
|
127
|
+
map[k] = mapper(k, v, obj)
|
|
129
128
|
return map
|
|
130
129
|
},
|
|
131
|
-
|
|
130
|
+
mutate ? obj : ({} as T),
|
|
132
131
|
)
|
|
133
132
|
}
|
|
134
133
|
|
|
@@ -137,15 +136,20 @@ export function _mapValues<T extends AnyObject, OUT = T>(
|
|
|
137
136
|
* // => { 'a1': 1, 'b2': 2 }
|
|
138
137
|
*
|
|
139
138
|
* Does not support `mutate` flag.
|
|
139
|
+
*
|
|
140
|
+
* To skip some key-value pairs - use _mapObject instead.
|
|
140
141
|
*/
|
|
141
142
|
export function _mapKeys<T extends AnyObject>(
|
|
142
143
|
obj: T,
|
|
143
144
|
mapper: ObjectMapper<T, string>,
|
|
144
|
-
):
|
|
145
|
-
return
|
|
146
|
-
map[
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
): Record<string, T[keyof T]> {
|
|
146
|
+
return _objectEntries(obj).reduce(
|
|
147
|
+
(map, [k, v]) => {
|
|
148
|
+
map[mapper(k, v, obj)] = v
|
|
149
|
+
return map
|
|
150
|
+
},
|
|
151
|
+
{} as Record<string, T[keyof T]>,
|
|
152
|
+
)
|
|
149
153
|
}
|
|
150
154
|
|
|
151
155
|
/**
|
|
@@ -160,24 +164,21 @@ export function _mapKeys<T extends AnyObject>(
|
|
|
160
164
|
* 0 - key of returned object (string)
|
|
161
165
|
* 1 - value of returned object (any)
|
|
162
166
|
*
|
|
163
|
-
* If predicate returns
|
|
167
|
+
* If predicate returns SKIP symbol - such key/value pair is ignored (filtered out).
|
|
164
168
|
*
|
|
165
169
|
* Non-string keys are passed via String(...)
|
|
166
170
|
*/
|
|
167
|
-
export function _mapObject<
|
|
168
|
-
obj:
|
|
169
|
-
mapper: ObjectMapper<
|
|
170
|
-
):
|
|
171
|
-
return Object.entries(obj).reduce(
|
|
172
|
-
(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
},
|
|
179
|
-
{} as { [P in keyof IN]: OUT },
|
|
180
|
-
)
|
|
171
|
+
export function _mapObject<T extends AnyObject>(
|
|
172
|
+
obj: T,
|
|
173
|
+
mapper: ObjectMapper<T, KeyValueTuple<string, any> | typeof SKIP>,
|
|
174
|
+
): T {
|
|
175
|
+
return Object.entries(obj).reduce((map, [k, v]) => {
|
|
176
|
+
const r = mapper(k, v, obj)
|
|
177
|
+
if (r !== SKIP) {
|
|
178
|
+
map[r[0]] = r[1]
|
|
179
|
+
}
|
|
180
|
+
return map
|
|
181
|
+
}, {} as AnyObject) as T
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
export function _findKeyByValue<T extends AnyObject>(obj: T, v: ValueOf<T>): keyof T | undefined {
|
|
@@ -404,3 +405,23 @@ export function _has<T extends AnyObject>(obj: T, path: string): boolean {
|
|
|
404
405
|
const v = _get(obj, path)
|
|
405
406
|
return v !== undefined && v !== null
|
|
406
407
|
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Does Object.freeze recursively for given object.
|
|
411
|
+
*
|
|
412
|
+
* Based on: https://github.com/substack/deep-freeze/blob/master/index.js
|
|
413
|
+
*/
|
|
414
|
+
export function _deepFreeze(o: any): void {
|
|
415
|
+
Object.freeze(o)
|
|
416
|
+
|
|
417
|
+
Object.getOwnPropertyNames(o).forEach(prop => {
|
|
418
|
+
if (
|
|
419
|
+
o.hasOwnProperty(prop) && // eslint-disable-line no-prototype-builtins
|
|
420
|
+
o[prop] !== null &&
|
|
421
|
+
(typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
|
|
422
|
+
!Object.isFrozen(o[prop])
|
|
423
|
+
) {
|
|
424
|
+
_deepFreeze(o[prop])
|
|
425
|
+
}
|
|
426
|
+
})
|
|
427
|
+
}
|
package/src/promise/pTimeout.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { AppError } from '../error/app.error'
|
|
2
|
-
import type { ErrorData
|
|
1
|
+
import { AppError, AppErrorOptions } from '../error/app.error'
|
|
2
|
+
import type { ErrorData } from '../error/error.model'
|
|
3
3
|
import { _errorDataAppend } from '../error/error.util'
|
|
4
4
|
import type { AnyAsyncFunction, NumberOfMilliseconds } from '../types'
|
|
5
5
|
|
|
6
6
|
export class TimeoutError extends AppError {
|
|
7
|
-
constructor(message: string, data
|
|
8
|
-
super(message, data,
|
|
7
|
+
constructor(message: string, data?: ErrorData, opt?: AppErrorOptions) {
|
|
8
|
+
super(message, data, { ...opt, name: 'TimeoutError' })
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
package/src/types.ts
CHANGED
|
@@ -163,7 +163,7 @@ export type KeyValueTuple<K, V> = [key: K, value: V]
|
|
|
163
163
|
|
|
164
164
|
// Exclude<something, undefined> is used here to support StringMap<OBJ> (because values of StringMap add `undefined`)
|
|
165
165
|
export type ObjectMapper<OBJ, OUT> = (
|
|
166
|
-
key:
|
|
166
|
+
key: keyof OBJ,
|
|
167
167
|
value: Exclude<OBJ[keyof OBJ], undefined>,
|
|
168
168
|
obj: OBJ,
|
|
169
169
|
) => OUT
|
|
@@ -250,11 +250,21 @@ export const _stringMapValues = Object.values as <T>(m: StringMap<T>) => T[]
|
|
|
250
250
|
export const _stringMapEntries = Object.entries as <T>(m: StringMap<T>) => [k: string, v: T][]
|
|
251
251
|
|
|
252
252
|
/**
|
|
253
|
-
*
|
|
253
|
+
* Alias of `Object.keys`, but returns keys typed as `keyof T`, not as just `string`.
|
|
254
254
|
* This is how TypeScript should work, actually.
|
|
255
255
|
*/
|
|
256
256
|
export const _objectKeys = Object.keys as <T extends AnyObject>(obj: T) => (keyof T)[]
|
|
257
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Alias of `Object.entries`, but returns better-typed output.
|
|
260
|
+
*
|
|
261
|
+
* So e.g you can use _objectEntries(obj).map([k, v] => {})
|
|
262
|
+
* and `k` will be `keyof obj` instead of generic `string`.
|
|
263
|
+
*/
|
|
264
|
+
export const _objectEntries = Object.entries as <T extends AnyObject>(
|
|
265
|
+
obj: T,
|
|
266
|
+
) => [k: keyof T, v: T[keyof T]][]
|
|
267
|
+
|
|
258
268
|
export type NullishValue = null | undefined
|
|
259
269
|
export type FalsyValue = false | '' | 0 | null | undefined
|
|
260
270
|
|
package/dist/lazy.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._defineLazyProps = exports._defineLazyProperty = exports._lazyValue = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* const value = lazyValue(() => expensiveComputation())
|
|
6
|
-
*
|
|
7
|
-
* value() // calls expensiveComputation() once
|
|
8
|
-
* value() // returns cached result
|
|
9
|
-
* value() // returns cached result
|
|
10
|
-
*
|
|
11
|
-
* Based on: https://github.com/sindresorhus/lazy-value
|
|
12
|
-
*/
|
|
13
|
-
function _lazyValue(fn) {
|
|
14
|
-
let isCalled = false;
|
|
15
|
-
let result;
|
|
16
|
-
return (() => {
|
|
17
|
-
if (!isCalled) {
|
|
18
|
-
isCalled = true;
|
|
19
|
-
result = fn();
|
|
20
|
-
}
|
|
21
|
-
return result;
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
exports._lazyValue = _lazyValue;
|
|
25
|
-
/**
|
|
26
|
-
* interface Obj {
|
|
27
|
-
* v: number
|
|
28
|
-
* }
|
|
29
|
-
*
|
|
30
|
-
* const obj = {} as Obj
|
|
31
|
-
*
|
|
32
|
-
* _defineLazyProperty(obj, 'v', () => expensiveComputation())
|
|
33
|
-
* obj.v // runs expensiveComputation() once
|
|
34
|
-
* obj.v // cached value
|
|
35
|
-
* obj.v // cached value
|
|
36
|
-
*
|
|
37
|
-
* Based on: https://github.com/sindresorhus/define-lazy-prop
|
|
38
|
-
*/
|
|
39
|
-
function _defineLazyProperty(obj, propertyName, fn) {
|
|
40
|
-
const define = (value) => {
|
|
41
|
-
Object.defineProperty(obj, propertyName, { value, enumerable: true, writable: true });
|
|
42
|
-
};
|
|
43
|
-
Object.defineProperty(obj, propertyName, {
|
|
44
|
-
configurable: true,
|
|
45
|
-
enumerable: true,
|
|
46
|
-
get() {
|
|
47
|
-
const result = fn();
|
|
48
|
-
define(result);
|
|
49
|
-
return result;
|
|
50
|
-
},
|
|
51
|
-
set(value) {
|
|
52
|
-
define(value);
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
return obj;
|
|
56
|
-
}
|
|
57
|
-
exports._defineLazyProperty = _defineLazyProperty;
|
|
58
|
-
/**
|
|
59
|
-
* Like _defineLazyProperty, but allows to define multiple props at once.
|
|
60
|
-
*/
|
|
61
|
-
function _defineLazyProps(obj, props) {
|
|
62
|
-
Object.entries(props).forEach(([k, fn]) => _defineLazyProperty(obj, k, fn));
|
|
63
|
-
return obj;
|
|
64
|
-
}
|
|
65
|
-
exports._defineLazyProps = _defineLazyProps;
|