@naturalcycles/js-lib 15.33.3 → 15.35.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 +1 -1
- package/dist/array/array.util.js +7 -13
- package/dist/decorators/asyncMemo.decorator.d.ts +3 -3
- package/dist/decorators/asyncMemo.decorator.js +3 -3
- package/dist/decorators/logMethod.decorator.js +1 -1
- package/dist/error/error.util.d.ts +1 -1
- package/dist/error/error.util.js +1 -1
- package/dist/json-schema/jsonSchemaBuilder.d.ts +34 -5
- package/dist/json-schema/jsonSchemaBuilder.js +44 -3
- package/dist/object/object.util.d.ts +1 -3
- package/dist/object/object.util.js +3 -5
- package/dist/promise/pMap.js +2 -2
- package/dist/string/safeJsonStringify.js +2 -1
- package/dist/string/string.util.d.ts +1 -1
- package/dist/string/string.util.js +1 -1
- package/dist/typeFest.d.ts +0 -7
- package/dist/types.d.ts +1 -3
- package/dist/types.js +1 -1
- package/package.json +1 -1
- package/src/array/array.util.ts +7 -13
- package/src/browser/analytics.util.ts +2 -0
- package/src/decorators/asyncMemo.decorator.ts +3 -3
- package/src/decorators/logMethod.decorator.ts +1 -1
- package/src/error/error.util.ts +1 -1
- package/src/json-schema/jsonSchemaBuilder.ts +78 -9
- package/src/object/object.util.ts +3 -5
- package/src/promise/pMap.ts +2 -2
- package/src/string/safeJsonStringify.ts +2 -2
- package/src/string/string.util.ts +1 -1
- package/src/typeFest.ts +0 -7
- package/src/types.ts +1 -3
|
@@ -5,7 +5,7 @@ import type { AbortablePredicate, FalsyValue, Mapper, Predicate, SortDirection,
|
|
|
5
5
|
*
|
|
6
6
|
* @param array The array to process.
|
|
7
7
|
* @param size The length of each chunk.
|
|
8
|
-
* @
|
|
8
|
+
* @returns Returns the new array containing chunks.
|
|
9
9
|
*
|
|
10
10
|
* https://lodash.com/docs#chunk
|
|
11
11
|
*
|
package/dist/array/array.util.js
CHANGED
|
@@ -6,7 +6,7 @@ import { END } from '../types.js';
|
|
|
6
6
|
*
|
|
7
7
|
* @param array The array to process.
|
|
8
8
|
* @param size The length of each chunk.
|
|
9
|
-
* @
|
|
9
|
+
* @returns Returns the new array containing chunks.
|
|
10
10
|
*
|
|
11
11
|
* https://lodash.com/docs#chunk
|
|
12
12
|
*
|
|
@@ -79,8 +79,7 @@ export function _pushUniqBy(a, mapper, ...items) {
|
|
|
79
79
|
*/
|
|
80
80
|
export function _uniqBy(arr, mapper) {
|
|
81
81
|
const map = new Map();
|
|
82
|
-
for (
|
|
83
|
-
const item = arr[i];
|
|
82
|
+
for (const item of arr) {
|
|
84
83
|
const key = item === undefined || item === null ? item : mapper(item);
|
|
85
84
|
if (!map.has(key))
|
|
86
85
|
map.set(key, item);
|
|
@@ -109,8 +108,7 @@ export function _uniqBy(arr, mapper) {
|
|
|
109
108
|
*/
|
|
110
109
|
export function _by(items, mapper) {
|
|
111
110
|
const map = {};
|
|
112
|
-
for (
|
|
113
|
-
const v = items[i];
|
|
111
|
+
for (const v of items) {
|
|
114
112
|
const k = mapper(v);
|
|
115
113
|
if (k !== undefined) {
|
|
116
114
|
map[k] = v;
|
|
@@ -123,8 +121,7 @@ export function _by(items, mapper) {
|
|
|
123
121
|
*/
|
|
124
122
|
export function _mapBy(items, mapper) {
|
|
125
123
|
const map = new Map();
|
|
126
|
-
for (
|
|
127
|
-
const item = items[i];
|
|
124
|
+
for (const item of items) {
|
|
128
125
|
const key = mapper(item);
|
|
129
126
|
if (key !== undefined) {
|
|
130
127
|
map.set(key, item);
|
|
@@ -145,8 +142,7 @@ export function _mapBy(items, mapper) {
|
|
|
145
142
|
*/
|
|
146
143
|
export function _groupBy(items, mapper) {
|
|
147
144
|
const map = {};
|
|
148
|
-
for (
|
|
149
|
-
const item = items[i];
|
|
145
|
+
for (const item of items) {
|
|
150
146
|
const key = mapper(item);
|
|
151
147
|
if (key !== undefined) {
|
|
152
148
|
;
|
|
@@ -444,8 +440,7 @@ export function _maxByOrUndefined(array, mapper) {
|
|
|
444
440
|
return;
|
|
445
441
|
let maxItem;
|
|
446
442
|
let max;
|
|
447
|
-
for (
|
|
448
|
-
const item = array[i];
|
|
443
|
+
for (const item of array) {
|
|
449
444
|
const v = mapper(item);
|
|
450
445
|
if (v !== undefined && (max === undefined || v > max)) {
|
|
451
446
|
maxItem = item;
|
|
@@ -459,8 +454,7 @@ export function _minByOrUndefined(array, mapper) {
|
|
|
459
454
|
return;
|
|
460
455
|
let minItem;
|
|
461
456
|
let min;
|
|
462
|
-
for (
|
|
463
|
-
const item = array[i];
|
|
457
|
+
for (const item of array) {
|
|
464
458
|
const v = mapper(item);
|
|
465
459
|
if (v !== undefined && (min === undefined || v < min)) {
|
|
466
460
|
minItem = item;
|
|
@@ -25,12 +25,12 @@ export interface AsyncMemoInstance {
|
|
|
25
25
|
getCache: (instance: AnyAsyncFunction) => AsyncMemoCache | undefined;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* Like
|
|
28
|
+
* Like `@_Memo`, but allowing async MemoCache implementation.
|
|
29
29
|
*
|
|
30
|
-
* Implementation is more complex than
|
|
30
|
+
* Implementation is more complex than `@_Memo`, because it needs to handle "in-flight" Promises
|
|
31
31
|
* while waiting for cache to resolve, to prevent "async swarm" issue.
|
|
32
32
|
*
|
|
33
|
-
* @experimental consider normal
|
|
33
|
+
* @experimental consider normal `@_Memo` for most of the cases, it's stable and predictable
|
|
34
34
|
*/
|
|
35
35
|
export declare const _AsyncMemo: <FN>(opt: AsyncMemoOptions<FN>) => MethodDecorator<FN>;
|
|
36
36
|
/**
|
|
@@ -3,12 +3,12 @@ import { _objectAssign, MISS } from '../types.js';
|
|
|
3
3
|
import { _getTargetMethodSignature } from './decorator.util.js';
|
|
4
4
|
import { jsonMemoSerializer } from './memo.util.js';
|
|
5
5
|
/**
|
|
6
|
-
* Like
|
|
6
|
+
* Like `@_Memo`, but allowing async MemoCache implementation.
|
|
7
7
|
*
|
|
8
|
-
* Implementation is more complex than
|
|
8
|
+
* Implementation is more complex than `@_Memo`, because it needs to handle "in-flight" Promises
|
|
9
9
|
* while waiting for cache to resolve, to prevent "async swarm" issue.
|
|
10
10
|
*
|
|
11
|
-
* @experimental consider normal
|
|
11
|
+
* @experimental consider normal `@_Memo` for most of the cases, it's stable and predictable
|
|
12
12
|
*/
|
|
13
13
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
14
14
|
export const _AsyncMemo = (opt) => (target, key, descriptor) => {
|
|
@@ -70,7 +70,7 @@ export function _LogMethod(opt = {}) {
|
|
|
70
70
|
return descriptor;
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
-
//
|
|
73
|
+
// oxlint-disable-next-line max-params
|
|
74
74
|
function logFinished(logger, callSignature, started, sma, logResultFn, res, err) {
|
|
75
75
|
const millis = Date.now() - started;
|
|
76
76
|
const t = ['<<', callSignature, 'took', _ms(millis)];
|
|
@@ -83,7 +83,7 @@ export interface AppErrorOptions {
|
|
|
83
83
|
* data - optional "any" payload.
|
|
84
84
|
* data.userFriendly - if present, will be displayed to the User as is.
|
|
85
85
|
*
|
|
86
|
-
* Based on: https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801
|
|
86
|
+
* Based on: `https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801`
|
|
87
87
|
*/
|
|
88
88
|
export declare class AppError<DATA_TYPE extends ErrorData = ErrorData> extends Error {
|
|
89
89
|
data: DATA_TYPE;
|
package/dist/error/error.util.js
CHANGED
|
@@ -221,7 +221,7 @@ export function _errorDataAppend(err, data) {
|
|
|
221
221
|
* data - optional "any" payload.
|
|
222
222
|
* data.userFriendly - if present, will be displayed to the User as is.
|
|
223
223
|
*
|
|
224
|
-
* Based on: https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801
|
|
224
|
+
* Based on: `https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801`
|
|
225
225
|
*/
|
|
226
226
|
export class AppError extends Error {
|
|
227
227
|
data;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnyObject, BaseDBEntity, IsoDate, UnixTimestamp } from '../types.js';
|
|
1
|
+
import type { AnyObject, BaseDBEntity, IsoDate, IsoDateTime, UnixTimestamp } from '../types.js';
|
|
2
2
|
import type { JsonSchema, JsonSchemaAllOf, JsonSchemaAny, JsonSchemaArray, JsonSchemaBoolean, JsonSchemaConst, JsonSchemaEnum, JsonSchemaNull, JsonSchemaNumber, JsonSchemaObject, JsonSchemaOneOf, JsonSchemaRef, JsonSchemaString, JsonSchemaTuple } from './jsonSchema.model.js';
|
|
3
3
|
export interface JsonSchemaBuilder<T = unknown> {
|
|
4
4
|
build: () => JsonSchema<T>;
|
|
@@ -20,10 +20,19 @@ export declare const j: {
|
|
|
20
20
|
unixTimestamp(): JsonSchemaNumberBuilder<UnixTimestamp>;
|
|
21
21
|
unixTimestamp2000(): JsonSchemaNumberBuilder<UnixTimestamp>;
|
|
22
22
|
string<T extends string = string>(): JsonSchemaStringBuilder<T>;
|
|
23
|
+
/**
|
|
24
|
+
* Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
|
|
25
|
+
*/
|
|
23
26
|
isoDate(): JsonSchemaStringBuilder<IsoDate>;
|
|
24
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
|
|
29
|
+
* and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
|
|
30
|
+
*/
|
|
31
|
+
isoDateTime(): JsonSchemaStringBuilder<IsoDateTime>;
|
|
32
|
+
object: typeof object;
|
|
33
|
+
dbEntity<T extends AnyObject>(props: T): JsonSchemaObjectBuilder<BaseDBEntity & { [K in keyof T]: T[K] extends JsonSchemaAnyBuilder<infer U, any> ? U : never; }>;
|
|
25
34
|
rootObject<T extends AnyObject>(props: { [K in keyof T]: JsonSchemaAnyBuilder<T[K]>; }): JsonSchemaObjectBuilder<T>;
|
|
26
|
-
array<
|
|
35
|
+
array<T extends JsonSchemaAnyBuilder<any>>(itemSchema: T): JsonSchemaArrayBuilder<T["infer"]>;
|
|
27
36
|
tuple<T extends any[] = unknown[]>(items: JsonSchemaAnyBuilder[]): JsonSchemaTupleBuilder<T>;
|
|
28
37
|
oneOf<T = unknown>(items: JsonSchemaAnyBuilder[]): JsonSchemaAnyBuilder<T, JsonSchemaOneOf<T>>;
|
|
29
38
|
allOf<T = unknown>(items: JsonSchemaAnyBuilder[]): JsonSchemaAnyBuilder<T, JsonSchemaAllOf<T>>;
|
|
@@ -46,7 +55,9 @@ export declare class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonS
|
|
|
46
55
|
oneOf(schemas: JsonSchema[]): this;
|
|
47
56
|
allOf(schemas: JsonSchema[]): this;
|
|
48
57
|
instanceof(of: string): this;
|
|
49
|
-
optional(
|
|
58
|
+
optional(): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>>;
|
|
59
|
+
optional(optional: true): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>>;
|
|
60
|
+
optional(optional: false): JsonSchemaAnyBuilder<Exclude<T, undefined>, JsonSchema<Exclude<T, undefined>>>;
|
|
50
61
|
/**
|
|
51
62
|
* Produces a "clean schema object" without methods.
|
|
52
63
|
* Same as if it would be JSON.stringified.
|
|
@@ -81,16 +92,17 @@ export declare class JsonSchemaNumberBuilder<T extends number = number> extends
|
|
|
81
92
|
unixTimestampMillis2000: () => this;
|
|
82
93
|
utcOffset: () => this;
|
|
83
94
|
utcOffsetHours: () => this;
|
|
95
|
+
branded<B extends number>(): JsonSchemaNumberBuilder<B>;
|
|
84
96
|
}
|
|
85
97
|
export declare class JsonSchemaStringBuilder<T extends string = string> extends JsonSchemaAnyBuilder<T, JsonSchemaString<T>> {
|
|
86
98
|
constructor();
|
|
99
|
+
regex(pattern: RegExp): this;
|
|
87
100
|
pattern(pattern: string): this;
|
|
88
101
|
min(minLength: number): this;
|
|
89
102
|
max(maxLength: number): this;
|
|
90
103
|
length(minLength: number, maxLength: number): this;
|
|
91
104
|
format(format: string): this;
|
|
92
105
|
email: () => this;
|
|
93
|
-
isoDate: () => this;
|
|
94
106
|
url: () => this;
|
|
95
107
|
ipv4: () => this;
|
|
96
108
|
ipv6: () => this;
|
|
@@ -104,6 +116,16 @@ export declare class JsonSchemaStringBuilder<T extends string = string> extends
|
|
|
104
116
|
trim: (trim?: boolean) => this;
|
|
105
117
|
toLowerCase: (toLowerCase?: boolean) => this;
|
|
106
118
|
toUpperCase: (toUpperCase?: boolean) => this;
|
|
119
|
+
branded<B extends string>(): JsonSchemaStringBuilder<B>;
|
|
120
|
+
/**
|
|
121
|
+
* Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
|
|
122
|
+
*/
|
|
123
|
+
isoDate(): JsonSchemaStringBuilder<IsoDate>;
|
|
124
|
+
/**
|
|
125
|
+
* Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
|
|
126
|
+
* and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
|
|
127
|
+
*/
|
|
128
|
+
isoDateTime(): JsonSchemaStringBuilder<IsoDateTime>;
|
|
107
129
|
private transformModify;
|
|
108
130
|
}
|
|
109
131
|
export declare class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyBuilder<T, JsonSchemaObject<T>> {
|
|
@@ -131,3 +153,10 @@ export declare class JsonSchemaArrayBuilder<ITEM> extends JsonSchemaAnyBuilder<I
|
|
|
131
153
|
export declare class JsonSchemaTupleBuilder<T extends any[]> extends JsonSchemaAnyBuilder<T, JsonSchemaTuple<T>> {
|
|
132
154
|
constructor(items: JsonSchemaBuilder[]);
|
|
133
155
|
}
|
|
156
|
+
declare function object<P extends Record<string, JsonSchemaAnyBuilder<any, any>>>(props: P): JsonSchemaObjectBuilder<{
|
|
157
|
+
[K in keyof P]: P[K] extends JsonSchemaAnyBuilder<infer U, any> ? U : never;
|
|
158
|
+
}>;
|
|
159
|
+
declare function object<T extends AnyObject>(props: {
|
|
160
|
+
[K in keyof T]: JsonSchemaAnyBuilder<T[K]>;
|
|
161
|
+
}): JsonSchemaObjectBuilder<T>;
|
|
162
|
+
export {};
|
|
@@ -56,13 +56,30 @@ export const j = {
|
|
|
56
56
|
string() {
|
|
57
57
|
return new JsonSchemaStringBuilder();
|
|
58
58
|
},
|
|
59
|
+
/**
|
|
60
|
+
* Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
|
|
61
|
+
*/
|
|
59
62
|
isoDate() {
|
|
60
63
|
return new JsonSchemaStringBuilder().isoDate();
|
|
61
64
|
},
|
|
65
|
+
/**
|
|
66
|
+
* Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
|
|
67
|
+
* and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
|
|
68
|
+
*/
|
|
69
|
+
isoDateTime() {
|
|
70
|
+
return new JsonSchemaStringBuilder().isoDateTime();
|
|
71
|
+
},
|
|
62
72
|
// email: () => new JsonSchemaStringBuilder().email(),
|
|
63
73
|
// complex types
|
|
64
|
-
object
|
|
65
|
-
|
|
74
|
+
object,
|
|
75
|
+
dbEntity(props) {
|
|
76
|
+
return j
|
|
77
|
+
.object({
|
|
78
|
+
id: j.string(),
|
|
79
|
+
created: j.unixTimestamp2000(),
|
|
80
|
+
updated: j.unixTimestamp2000(),
|
|
81
|
+
})
|
|
82
|
+
.extend(j.object(props));
|
|
66
83
|
},
|
|
67
84
|
rootObject(props) {
|
|
68
85
|
return new JsonSchemaObjectBuilder().addProperties(props).$schemaDraft7();
|
|
@@ -214,6 +231,9 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder {
|
|
|
214
231
|
unixTimestampMillis2000 = () => this.format('unixTimestampMillis2000').description('UnixTimestampMillis2000');
|
|
215
232
|
utcOffset = () => this.format('utcOffset');
|
|
216
233
|
utcOffsetHours = () => this.format('utcOffsetHours');
|
|
234
|
+
branded() {
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
217
237
|
}
|
|
218
238
|
export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
|
|
219
239
|
constructor() {
|
|
@@ -221,6 +241,9 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
|
|
|
221
241
|
type: 'string',
|
|
222
242
|
});
|
|
223
243
|
}
|
|
244
|
+
regex(pattern) {
|
|
245
|
+
return this.pattern(pattern.source);
|
|
246
|
+
}
|
|
224
247
|
pattern(pattern) {
|
|
225
248
|
Object.assign(this.schema, { pattern });
|
|
226
249
|
return this;
|
|
@@ -242,7 +265,6 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
|
|
|
242
265
|
return this;
|
|
243
266
|
}
|
|
244
267
|
email = () => this.format('email');
|
|
245
|
-
isoDate = () => this.format('date').description('IsoDate'); // todo: make it custom isoDate instead
|
|
246
268
|
url = () => this.format('url');
|
|
247
269
|
ipv4 = () => this.format('ipv4');
|
|
248
270
|
ipv6 = () => this.format('ipv6');
|
|
@@ -256,6 +278,22 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
|
|
|
256
278
|
trim = (trim = true) => this.transformModify('trim', trim);
|
|
257
279
|
toLowerCase = (toLowerCase = true) => this.transformModify('toLowerCase', toLowerCase);
|
|
258
280
|
toUpperCase = (toUpperCase = true) => this.transformModify('toUpperCase', toUpperCase);
|
|
281
|
+
branded() {
|
|
282
|
+
return this;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
|
|
286
|
+
*/
|
|
287
|
+
isoDate() {
|
|
288
|
+
return this.format('IsoDate').branded().description('IsoDate');
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
|
|
292
|
+
* and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
|
|
293
|
+
*/
|
|
294
|
+
isoDateTime() {
|
|
295
|
+
return this.format('IsoDateTime').branded().description('IsoDateTime');
|
|
296
|
+
}
|
|
259
297
|
transformModify(t, add) {
|
|
260
298
|
if (add) {
|
|
261
299
|
this.schema.transform = _uniq([...(this.schema.transform || []), t]);
|
|
@@ -357,3 +395,6 @@ export class JsonSchemaTupleBuilder extends JsonSchemaAnyBuilder {
|
|
|
357
395
|
});
|
|
358
396
|
}
|
|
359
397
|
}
|
|
398
|
+
function object(props) {
|
|
399
|
+
return new JsonSchemaObjectBuilder().addProperties(props);
|
|
400
|
+
}
|
|
@@ -126,7 +126,6 @@ export declare function _filterEmptyValues<T extends AnyObject>(obj: T, opt?: Mu
|
|
|
126
126
|
*
|
|
127
127
|
* **Note:** This method mutates `object`.
|
|
128
128
|
*
|
|
129
|
-
* @category Object
|
|
130
129
|
* @param target The destination object.
|
|
131
130
|
* @param sources The source objects.
|
|
132
131
|
* @returns Returns `object`.
|
|
@@ -177,7 +176,7 @@ type PropertyPath = Many<PropertyKey>;
|
|
|
177
176
|
* @param obj The object to modify.
|
|
178
177
|
* @param path The path of the property to set.
|
|
179
178
|
* @param value The value to set.
|
|
180
|
-
* @
|
|
179
|
+
* @returns Returns object.
|
|
181
180
|
*
|
|
182
181
|
* Based on: https://stackoverflow.com/a/54733755/4919972
|
|
183
182
|
*/
|
|
@@ -185,7 +184,6 @@ export declare function _set<T extends AnyObject>(obj: T, path: PropertyPath, va
|
|
|
185
184
|
/**
|
|
186
185
|
* Checks if `path` is a direct property of `object` (not null, not undefined).
|
|
187
186
|
*
|
|
188
|
-
* @category Object
|
|
189
187
|
* @param obj The object to query.
|
|
190
188
|
* @param path The path to check.
|
|
191
189
|
* @returns Returns `true` if `path` exists, else `false`.
|
|
@@ -236,7 +236,6 @@ export function _filterEmptyValues(obj, opt = {}) {
|
|
|
236
236
|
*
|
|
237
237
|
* **Note:** This method mutates `object`.
|
|
238
238
|
*
|
|
239
|
-
* @category Object
|
|
240
239
|
* @param target The destination object.
|
|
241
240
|
* @param sources The source objects.
|
|
242
241
|
* @returns Returns `object`.
|
|
@@ -340,7 +339,7 @@ export function _get(obj = {}, path = '') {
|
|
|
340
339
|
return (path
|
|
341
340
|
.replaceAll(/\[([^\]]+)]/g, '.$1')
|
|
342
341
|
.split('.')
|
|
343
|
-
//
|
|
342
|
+
// oxlint-disable-next-line unicorn/no-array-reduce
|
|
344
343
|
.reduce((o, p) => o?.[p], obj));
|
|
345
344
|
}
|
|
346
345
|
/**
|
|
@@ -350,7 +349,7 @@ export function _get(obj = {}, path = '') {
|
|
|
350
349
|
* @param obj The object to modify.
|
|
351
350
|
* @param path The path of the property to set.
|
|
352
351
|
* @param value The value to set.
|
|
353
|
-
* @
|
|
352
|
+
* @returns Returns object.
|
|
354
353
|
*
|
|
355
354
|
* Based on: https://stackoverflow.com/a/54733755/4919972
|
|
356
355
|
*/
|
|
@@ -365,7 +364,7 @@ export function _set(obj, path, value) {
|
|
|
365
364
|
else if (!path.length) {
|
|
366
365
|
return obj;
|
|
367
366
|
}
|
|
368
|
-
//
|
|
367
|
+
// oxlint-disable-next-line unicorn/no-array-reduce
|
|
369
368
|
;
|
|
370
369
|
path.slice(0, -1).reduce((a, c, i) =>
|
|
371
370
|
// biome-ignore lint/style/useConsistentBuiltinInstantiation: ok
|
|
@@ -384,7 +383,6 @@ export function _set(obj, path, value) {
|
|
|
384
383
|
/**
|
|
385
384
|
* Checks if `path` is a direct property of `object` (not null, not undefined).
|
|
386
385
|
*
|
|
387
|
-
* @category Object
|
|
388
386
|
* @param obj The object to query.
|
|
389
387
|
* @param path The path to check.
|
|
390
388
|
* @returns Returns `true` if `path` exists, else `false`.
|
package/dist/promise/pMap.js
CHANGED
|
@@ -85,7 +85,7 @@ export async function pMap(iterable, mapper, opt = {}) {
|
|
|
85
85
|
}
|
|
86
86
|
ret[i] = value;
|
|
87
87
|
resolvingCount--;
|
|
88
|
-
next();
|
|
88
|
+
next(); // oxlint-disable-line no-callback-in-promise
|
|
89
89
|
}, (err) => {
|
|
90
90
|
if (errorMode === ErrorMode.THROW_IMMEDIATELY) {
|
|
91
91
|
isSettled = true;
|
|
@@ -100,7 +100,7 @@ export async function pMap(iterable, mapper, opt = {}) {
|
|
|
100
100
|
logger?.error(err);
|
|
101
101
|
}
|
|
102
102
|
resolvingCount--;
|
|
103
|
-
next();
|
|
103
|
+
next(); // oxlint-disable-line no-callback-in-promise
|
|
104
104
|
}
|
|
105
105
|
});
|
|
106
106
|
};
|
|
@@ -13,7 +13,8 @@ export function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
|
|
|
13
13
|
return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
/* eslint-disable
|
|
16
|
+
/* eslint-disable no-bitwise, no-implicit-coercion */
|
|
17
|
+
// oxlint-disable no-unused-expressions
|
|
17
18
|
function serializer(replacer, cycleReplacer) {
|
|
18
19
|
const stack = [];
|
|
19
20
|
const keys = [];
|
|
@@ -16,7 +16,7 @@ export declare function _lowerFirst(s: string): Uncapitalize<string>;
|
|
|
16
16
|
/**
|
|
17
17
|
* Like String.split(), but with limit, returning the tail together with last element.
|
|
18
18
|
*
|
|
19
|
-
* @
|
|
19
|
+
* @returns Returns the new array of string segments.
|
|
20
20
|
*/
|
|
21
21
|
export declare function _split(str: string, separator: string, limit: number): string[];
|
|
22
22
|
export declare function _removeWhitespace(s: string): string;
|
|
@@ -26,7 +26,7 @@ export function _lowerFirst(s) {
|
|
|
26
26
|
/**
|
|
27
27
|
* Like String.split(), but with limit, returning the tail together with last element.
|
|
28
28
|
*
|
|
29
|
-
* @
|
|
29
|
+
* @returns Returns the new array of string segments.
|
|
30
30
|
*/
|
|
31
31
|
export function _split(str, separator, limit) {
|
|
32
32
|
const parts = str.split(separator);
|
package/dist/typeFest.d.ts
CHANGED
|
@@ -37,8 +37,6 @@ type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ?
|
|
|
37
37
|
type FooWithoutA = Except<Foo, 'a' | 'c'>;
|
|
38
38
|
//=> {b: string};
|
|
39
39
|
```
|
|
40
|
-
|
|
41
|
-
@category Utilities
|
|
42
40
|
*/
|
|
43
41
|
export type Except<ObjectType, KeysType extends keyof ObjectType> = {
|
|
44
42
|
[KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];
|
|
@@ -82,8 +80,6 @@ export type OmitIndexSignature<ObjectType> = {
|
|
|
82
80
|
|
|
83
81
|
const ab: Merge<Foo, Bar> = {a: 1, b: 2};
|
|
84
82
|
```
|
|
85
|
-
|
|
86
|
-
@category Utilities
|
|
87
83
|
*/
|
|
88
84
|
export type Merge<Destination, Source> = {
|
|
89
85
|
[Key in keyof OmitIndexSignature<Destination & Source>]: Key extends keyof Source ? Source[Key] : Key extends keyof Destination ? Destination[Key] : never;
|
|
@@ -109,7 +105,6 @@ export type Merge<Destination, Source> = {
|
|
|
109
105
|
type StringKeysAndUndefined = ConditionalKeys<Example, string | undefined>;
|
|
110
106
|
//=> 'a' | 'c'
|
|
111
107
|
```
|
|
112
|
-
@category Utilities
|
|
113
108
|
*/
|
|
114
109
|
export type ConditionalKeys<Base, Condition> = NonNullable<{
|
|
115
110
|
[Key in keyof Base]: Base[Key] extends Condition ? Key : never;
|
|
@@ -141,7 +136,6 @@ export type ConditionalKeys<Base, Condition> = NonNullable<{
|
|
|
141
136
|
type NonStringKeysOnly = ConditionalExcept<Example, string>;
|
|
142
137
|
//=> {b: string | number; c: () => void; d: {}}
|
|
143
138
|
```
|
|
144
|
-
@category Utilities
|
|
145
139
|
*/
|
|
146
140
|
export type ConditionalExcept<Base, Condition> = Except<Base, ConditionalKeys<Base, Condition>>;
|
|
147
141
|
/**
|
|
@@ -171,7 +165,6 @@ export type ConditionalExcept<Base, Condition> = Except<Base, ConditionalKeys<Ba
|
|
|
171
165
|
type StringKeysOnly = ConditionalPick<Example, string>;
|
|
172
166
|
//=> {a: string}
|
|
173
167
|
```
|
|
174
|
-
@category Utilities
|
|
175
168
|
*/
|
|
176
169
|
export type ConditionalPick<Base, Condition> = Pick<Base, ConditionalKeys<Base, Condition>>;
|
|
177
170
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -310,7 +310,7 @@ export type FalsyValue = false | '' | 0 | null | undefined;
|
|
|
310
310
|
* err.data = {} // can be done, because it was casted
|
|
311
311
|
* }
|
|
312
312
|
*/
|
|
313
|
-
export declare function _typeCast<T>(
|
|
313
|
+
export declare function _typeCast<T>(_v: any): asserts _v is T;
|
|
314
314
|
/**
|
|
315
315
|
* Type-safe Object.assign that checks that part is indeed a Partial<T>
|
|
316
316
|
*/
|
|
@@ -371,8 +371,6 @@ export type Class<T = any> = new (...args: any[]) => T;
|
|
|
371
371
|
data.foo.push('bar');
|
|
372
372
|
//=> error TS2339: Property 'push' does not exist on type 'readonly string[]'
|
|
373
373
|
```
|
|
374
|
-
|
|
375
|
-
@category Utilities
|
|
376
374
|
*/
|
|
377
375
|
export type ReadonlyDeep<T> = T extends Primitive | ((...args: any[]) => unknown) ? T : T extends ReadonlyMap<infer KeyType, infer ValueType> ? ReadonlyMapDeep<KeyType, ValueType> : T extends ReadonlySet<infer ItemType> ? ReadonlySetDeep<ItemType> : T extends object ? ReadonlyObjectDeep<T> : unknown;
|
|
378
376
|
/**
|
package/dist/types.js
CHANGED
|
@@ -59,7 +59,7 @@ export const _objectEntries = Object.entries;
|
|
|
59
59
|
* err.data = {} // can be done, because it was casted
|
|
60
60
|
* }
|
|
61
61
|
*/
|
|
62
|
-
export function _typeCast(
|
|
62
|
+
export function _typeCast(_v) { }
|
|
63
63
|
/**
|
|
64
64
|
* Type-safe Object.assign that checks that part is indeed a Partial<T>
|
|
65
65
|
*/
|
package/package.json
CHANGED
package/src/array/array.util.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { END } from '../types.js'
|
|
|
15
15
|
*
|
|
16
16
|
* @param array The array to process.
|
|
17
17
|
* @param size The length of each chunk.
|
|
18
|
-
* @
|
|
18
|
+
* @returns Returns the new array containing chunks.
|
|
19
19
|
*
|
|
20
20
|
* https://lodash.com/docs#chunk
|
|
21
21
|
*
|
|
@@ -91,8 +91,7 @@ export function _pushUniqBy<T>(a: T[], mapper: Mapper<T, any>, ...items: T[]): T
|
|
|
91
91
|
*/
|
|
92
92
|
export function _uniqBy<T>(arr: readonly T[], mapper: Mapper<T, any>): T[] {
|
|
93
93
|
const map = new Map<any, T>()
|
|
94
|
-
for (
|
|
95
|
-
const item = arr[i]!
|
|
94
|
+
for (const item of arr) {
|
|
96
95
|
const key = item === undefined || item === null ? item : mapper(item)
|
|
97
96
|
if (!map.has(key)) map.set(key, item)
|
|
98
97
|
}
|
|
@@ -121,8 +120,7 @@ export function _uniqBy<T>(arr: readonly T[], mapper: Mapper<T, any>): T[] {
|
|
|
121
120
|
*/
|
|
122
121
|
export function _by<T>(items: readonly T[], mapper: Mapper<T, any>): StringMap<T> {
|
|
123
122
|
const map: StringMap<T> = {}
|
|
124
|
-
for (
|
|
125
|
-
const v = items[i]!
|
|
123
|
+
for (const v of items) {
|
|
126
124
|
const k = mapper(v)
|
|
127
125
|
if (k !== undefined) {
|
|
128
126
|
map[k] = v
|
|
@@ -140,8 +138,7 @@ export function _mapBy<ITEM, KEY>(
|
|
|
140
138
|
mapper: Mapper<ITEM, KEY>,
|
|
141
139
|
): Map<KEY, ITEM> {
|
|
142
140
|
const map = new Map<KEY, ITEM>()
|
|
143
|
-
for (
|
|
144
|
-
const item = items[i]!
|
|
141
|
+
for (const item of items) {
|
|
145
142
|
const key = mapper(item)
|
|
146
143
|
if (key !== undefined) {
|
|
147
144
|
map.set(key, item)
|
|
@@ -164,8 +161,7 @@ export function _mapBy<ITEM, KEY>(
|
|
|
164
161
|
export function _groupBy<T>(items: readonly T[], mapper: Mapper<T, any>): StringMap<T[]> {
|
|
165
162
|
const map: StringMap<T[]> = {}
|
|
166
163
|
|
|
167
|
-
for (
|
|
168
|
-
const item = items[i]!
|
|
164
|
+
for (const item of items) {
|
|
169
165
|
const key = mapper(item)
|
|
170
166
|
if (key !== undefined) {
|
|
171
167
|
;(map[key] ||= []).push(item)
|
|
@@ -531,8 +527,7 @@ export function _maxByOrUndefined<T>(
|
|
|
531
527
|
let maxItem: T | undefined
|
|
532
528
|
let max: number | string | undefined
|
|
533
529
|
|
|
534
|
-
for (
|
|
535
|
-
const item = array[i]!
|
|
530
|
+
for (const item of array) {
|
|
536
531
|
const v = mapper(item)
|
|
537
532
|
if (v !== undefined && (max === undefined || v > max)) {
|
|
538
533
|
maxItem = item
|
|
@@ -551,8 +546,7 @@ export function _minByOrUndefined<T>(
|
|
|
551
546
|
let minItem: T | undefined
|
|
552
547
|
let min: number | string | undefined
|
|
553
548
|
|
|
554
|
-
for (
|
|
555
|
-
const item = array[i]!
|
|
549
|
+
for (const item of array) {
|
|
556
550
|
const v = mapper(item)
|
|
557
551
|
if (v !== undefined && (min === undefined || v < min)) {
|
|
558
552
|
minItem = item
|
|
@@ -36,12 +36,12 @@ export interface AsyncMemoInstance {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* Like
|
|
39
|
+
* Like `@_Memo`, but allowing async MemoCache implementation.
|
|
40
40
|
*
|
|
41
|
-
* Implementation is more complex than
|
|
41
|
+
* Implementation is more complex than `@_Memo`, because it needs to handle "in-flight" Promises
|
|
42
42
|
* while waiting for cache to resolve, to prevent "async swarm" issue.
|
|
43
43
|
*
|
|
44
|
-
* @experimental consider normal
|
|
44
|
+
* @experimental consider normal `@_Memo` for most of the cases, it's stable and predictable
|
|
45
45
|
*/
|
|
46
46
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
47
47
|
export const _AsyncMemo =
|
|
@@ -138,7 +138,7 @@ export function _LogMethod(opt: LogMethodOptions = {}): MethodDecorator {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
//
|
|
141
|
+
// oxlint-disable-next-line max-params
|
|
142
142
|
function logFinished(
|
|
143
143
|
logger: CommonLogger,
|
|
144
144
|
callSignature: string,
|
package/src/error/error.util.ts
CHANGED
|
@@ -304,7 +304,7 @@ export interface AppErrorOptions {
|
|
|
304
304
|
* data - optional "any" payload.
|
|
305
305
|
* data.userFriendly - if present, will be displayed to the User as is.
|
|
306
306
|
*
|
|
307
|
-
* Based on: https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801
|
|
307
|
+
* Based on: `https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801`
|
|
308
308
|
*/
|
|
309
309
|
export class AppError<DATA_TYPE extends ErrorData = ErrorData> extends Error {
|
|
310
310
|
data!: DATA_TYPE
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _uniq } from '../array/array.util.js'
|
|
2
2
|
import { _deepCopy } from '../object/object.util.js'
|
|
3
3
|
import { _sortObject } from '../object/sortObject.js'
|
|
4
|
-
import type { AnyObject, BaseDBEntity, IsoDate, UnixTimestamp } from '../types.js'
|
|
4
|
+
import type { AnyObject, BaseDBEntity, IsoDate, IsoDateTime, UnixTimestamp } from '../types.js'
|
|
5
5
|
import { JSON_SCHEMA_ORDER } from './jsonSchema.cnst.js'
|
|
6
6
|
import type {
|
|
7
7
|
JsonSchema,
|
|
@@ -77,27 +77,47 @@ export const j = {
|
|
|
77
77
|
unixTimestamp2000() {
|
|
78
78
|
return new JsonSchemaNumberBuilder<UnixTimestamp>().unixTimestamp2000()
|
|
79
79
|
},
|
|
80
|
+
|
|
80
81
|
// string types
|
|
81
82
|
string<T extends string = string>() {
|
|
82
83
|
return new JsonSchemaStringBuilder<T>()
|
|
83
84
|
},
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
|
|
88
|
+
*/
|
|
84
89
|
isoDate() {
|
|
85
90
|
return new JsonSchemaStringBuilder<IsoDate>().isoDate()
|
|
86
91
|
},
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
|
|
95
|
+
* and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
|
|
96
|
+
*/
|
|
97
|
+
isoDateTime() {
|
|
98
|
+
return new JsonSchemaStringBuilder<IsoDateTime>().isoDateTime()
|
|
99
|
+
},
|
|
100
|
+
|
|
87
101
|
// email: () => new JsonSchemaStringBuilder().email(),
|
|
88
102
|
// complex types
|
|
89
|
-
object
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
103
|
+
object,
|
|
104
|
+
dbEntity<T extends AnyObject>(props: T) {
|
|
105
|
+
return j
|
|
106
|
+
.object<BaseDBEntity>({
|
|
107
|
+
id: j.string(),
|
|
108
|
+
created: j.unixTimestamp2000(),
|
|
109
|
+
updated: j.unixTimestamp2000(),
|
|
110
|
+
})
|
|
111
|
+
.extend(j.object(props))
|
|
93
112
|
},
|
|
113
|
+
|
|
94
114
|
rootObject<T extends AnyObject>(props: {
|
|
95
115
|
[K in keyof T]: JsonSchemaAnyBuilder<T[K]>
|
|
96
116
|
}) {
|
|
97
117
|
return new JsonSchemaObjectBuilder<T>().addProperties(props).$schemaDraft7()
|
|
98
118
|
},
|
|
99
|
-
array<
|
|
100
|
-
return new JsonSchemaArrayBuilder<
|
|
119
|
+
array<T extends JsonSchemaAnyBuilder<any>>(itemSchema: T) {
|
|
120
|
+
return new JsonSchemaArrayBuilder<T['infer']>(itemSchema)
|
|
101
121
|
},
|
|
102
122
|
tuple<T extends any[] = unknown[]>(items: JsonSchemaAnyBuilder[]) {
|
|
103
123
|
return new JsonSchemaTupleBuilder<T>(items)
|
|
@@ -181,7 +201,12 @@ export class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T>
|
|
|
181
201
|
return this
|
|
182
202
|
}
|
|
183
203
|
|
|
184
|
-
optional(
|
|
204
|
+
optional(): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>>
|
|
205
|
+
optional(optional: true): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>>
|
|
206
|
+
optional(
|
|
207
|
+
optional: false,
|
|
208
|
+
): JsonSchemaAnyBuilder<Exclude<T, undefined>, JsonSchema<Exclude<T, undefined>>>
|
|
209
|
+
optional(optional = true): JsonSchemaAnyBuilder<any, JsonSchema<any>> {
|
|
185
210
|
if (optional) {
|
|
186
211
|
this.schema.optionalField = true
|
|
187
212
|
} else {
|
|
@@ -275,6 +300,10 @@ export class JsonSchemaNumberBuilder<T extends number = number> extends JsonSche
|
|
|
275
300
|
|
|
276
301
|
utcOffset = (): this => this.format('utcOffset')
|
|
277
302
|
utcOffsetHours = (): this => this.format('utcOffsetHours')
|
|
303
|
+
|
|
304
|
+
branded<B extends number>(): JsonSchemaNumberBuilder<B> {
|
|
305
|
+
return this as unknown as JsonSchemaNumberBuilder<B>
|
|
306
|
+
}
|
|
278
307
|
}
|
|
279
308
|
|
|
280
309
|
export class JsonSchemaStringBuilder<T extends string = string> extends JsonSchemaAnyBuilder<
|
|
@@ -287,6 +316,10 @@ export class JsonSchemaStringBuilder<T extends string = string> extends JsonSche
|
|
|
287
316
|
})
|
|
288
317
|
}
|
|
289
318
|
|
|
319
|
+
regex(pattern: RegExp): this {
|
|
320
|
+
return this.pattern(pattern.source)
|
|
321
|
+
}
|
|
322
|
+
|
|
290
323
|
pattern(pattern: string): this {
|
|
291
324
|
Object.assign(this.schema, { pattern })
|
|
292
325
|
return this
|
|
@@ -313,7 +346,6 @@ export class JsonSchemaStringBuilder<T extends string = string> extends JsonSche
|
|
|
313
346
|
}
|
|
314
347
|
|
|
315
348
|
email = (): this => this.format('email')
|
|
316
|
-
isoDate = (): this => this.format('date').description('IsoDate') // todo: make it custom isoDate instead
|
|
317
349
|
url = (): this => this.format('url')
|
|
318
350
|
ipv4 = (): this => this.format('ipv4')
|
|
319
351
|
ipv6 = (): this => this.format('ipv6')
|
|
@@ -329,6 +361,25 @@ export class JsonSchemaStringBuilder<T extends string = string> extends JsonSche
|
|
|
329
361
|
toLowerCase = (toLowerCase = true): this => this.transformModify('toLowerCase', toLowerCase)
|
|
330
362
|
toUpperCase = (toUpperCase = true): this => this.transformModify('toUpperCase', toUpperCase)
|
|
331
363
|
|
|
364
|
+
branded<B extends string>(): JsonSchemaStringBuilder<B> {
|
|
365
|
+
return this as unknown as JsonSchemaStringBuilder<B>
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
|
|
370
|
+
*/
|
|
371
|
+
isoDate(): JsonSchemaStringBuilder<IsoDate> {
|
|
372
|
+
return this.format('IsoDate').branded<IsoDate>().description('IsoDate')
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
|
|
377
|
+
* and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
|
|
378
|
+
*/
|
|
379
|
+
isoDateTime(): JsonSchemaStringBuilder<IsoDateTime> {
|
|
380
|
+
return this.format('IsoDateTime').branded<IsoDateTime>().description('IsoDateTime')
|
|
381
|
+
}
|
|
382
|
+
|
|
332
383
|
private transformModify(t: 'trim' | 'toLowerCase' | 'toUpperCase', add: boolean): this {
|
|
333
384
|
if (add) {
|
|
334
385
|
this.schema.transform = _uniq([...(this.schema.transform || []), t])
|
|
@@ -457,3 +508,21 @@ export class JsonSchemaTupleBuilder<T extends any[]> extends JsonSchemaAnyBuilde
|
|
|
457
508
|
})
|
|
458
509
|
}
|
|
459
510
|
}
|
|
511
|
+
|
|
512
|
+
// TODO and Notes
|
|
513
|
+
// The issue is that in `j` we mix two approaches:
|
|
514
|
+
// 1) the builder driven approach
|
|
515
|
+
// 2) the type driven approach.
|
|
516
|
+
|
|
517
|
+
function object<P extends Record<string, JsonSchemaAnyBuilder<any, any>>>(
|
|
518
|
+
props: P,
|
|
519
|
+
): JsonSchemaObjectBuilder<{
|
|
520
|
+
[K in keyof P]: P[K] extends JsonSchemaAnyBuilder<infer U, any> ? U : never
|
|
521
|
+
}>
|
|
522
|
+
function object<T extends AnyObject>(props: {
|
|
523
|
+
[K in keyof T]: JsonSchemaAnyBuilder<T[K]>
|
|
524
|
+
}): JsonSchemaObjectBuilder<T>
|
|
525
|
+
|
|
526
|
+
function object(props: any): any {
|
|
527
|
+
return new JsonSchemaObjectBuilder<any>().addProperties(props)
|
|
528
|
+
}
|
|
@@ -292,7 +292,6 @@ export function _filterEmptyValues<T extends AnyObject>(obj: T, opt: MutateOptio
|
|
|
292
292
|
*
|
|
293
293
|
* **Note:** This method mutates `object`.
|
|
294
294
|
*
|
|
295
|
-
* @category Object
|
|
296
295
|
* @param target The destination object.
|
|
297
296
|
* @param sources The source objects.
|
|
298
297
|
* @returns Returns `object`.
|
|
@@ -402,7 +401,7 @@ export function _get<T extends AnyObject>(obj = {} as T, path = ''): unknown {
|
|
|
402
401
|
path
|
|
403
402
|
.replaceAll(/\[([^\]]+)]/g, '.$1')
|
|
404
403
|
.split('.')
|
|
405
|
-
//
|
|
404
|
+
// oxlint-disable-next-line unicorn/no-array-reduce
|
|
406
405
|
.reduce((o, p) => o?.[p], obj)
|
|
407
406
|
)
|
|
408
407
|
}
|
|
@@ -417,7 +416,7 @@ type PropertyPath = Many<PropertyKey>
|
|
|
417
416
|
* @param obj The object to modify.
|
|
418
417
|
* @param path The path of the property to set.
|
|
419
418
|
* @param value The value to set.
|
|
420
|
-
* @
|
|
419
|
+
* @returns Returns object.
|
|
421
420
|
*
|
|
422
421
|
* Based on: https://stackoverflow.com/a/54733755/4919972
|
|
423
422
|
*/
|
|
@@ -432,7 +431,7 @@ export function _set<T extends AnyObject>(obj: T, path: PropertyPath, value: any
|
|
|
432
431
|
return obj as any
|
|
433
432
|
}
|
|
434
433
|
|
|
435
|
-
//
|
|
434
|
+
// oxlint-disable-next-line unicorn/no-array-reduce
|
|
436
435
|
;(path as any[]).slice(0, -1).reduce(
|
|
437
436
|
(
|
|
438
437
|
a,
|
|
@@ -458,7 +457,6 @@ export function _set<T extends AnyObject>(obj: T, path: PropertyPath, value: any
|
|
|
458
457
|
/**
|
|
459
458
|
* Checks if `path` is a direct property of `object` (not null, not undefined).
|
|
460
459
|
*
|
|
461
|
-
* @category Object
|
|
462
460
|
* @param obj The object to query.
|
|
463
461
|
* @param path The path to check.
|
|
464
462
|
* @returns Returns `true` if `path` exists, else `false`.
|
package/src/promise/pMap.ts
CHANGED
|
@@ -126,7 +126,7 @@ export async function pMap<IN, OUT>(
|
|
|
126
126
|
|
|
127
127
|
ret[i] = value
|
|
128
128
|
resolvingCount--
|
|
129
|
-
next()
|
|
129
|
+
next() // oxlint-disable-line no-callback-in-promise
|
|
130
130
|
},
|
|
131
131
|
(err: Error) => {
|
|
132
132
|
if (errorMode === ErrorMode.THROW_IMMEDIATELY) {
|
|
@@ -140,7 +140,7 @@ export async function pMap<IN, OUT>(
|
|
|
140
140
|
logger?.error(err)
|
|
141
141
|
}
|
|
142
142
|
resolvingCount--
|
|
143
|
-
next()
|
|
143
|
+
next() // oxlint-disable-line no-callback-in-promise
|
|
144
144
|
}
|
|
145
145
|
},
|
|
146
146
|
)
|
|
@@ -20,8 +20,8 @@ export function _safeJsonStringify(
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
/* eslint-disable
|
|
24
|
-
|
|
23
|
+
/* eslint-disable no-bitwise, no-implicit-coercion */
|
|
24
|
+
// oxlint-disable no-unused-expressions
|
|
25
25
|
function serializer(replacer?: Reviver, cycleReplacer?: Reviver): Reviver {
|
|
26
26
|
const stack: any[] = []
|
|
27
27
|
const keys: string[] = []
|
|
@@ -31,7 +31,7 @@ export function _lowerFirst(s: string): Uncapitalize<string> {
|
|
|
31
31
|
/**
|
|
32
32
|
* Like String.split(), but with limit, returning the tail together with last element.
|
|
33
33
|
*
|
|
34
|
-
* @
|
|
34
|
+
* @returns Returns the new array of string segments.
|
|
35
35
|
*/
|
|
36
36
|
export function _split(str: string, separator: string, limit: number): string[] {
|
|
37
37
|
const parts = str.split(separator)
|
package/src/typeFest.ts
CHANGED
|
@@ -42,8 +42,6 @@ type Filter<KeyType, ExcludeType> =
|
|
|
42
42
|
type FooWithoutA = Except<Foo, 'a' | 'c'>;
|
|
43
43
|
//=> {b: string};
|
|
44
44
|
```
|
|
45
|
-
|
|
46
|
-
@category Utilities
|
|
47
45
|
*/
|
|
48
46
|
export type Except<ObjectType, KeysType extends keyof ObjectType> = {
|
|
49
47
|
[KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType]
|
|
@@ -94,8 +92,6 @@ export type OmitIndexSignature<ObjectType> = {
|
|
|
94
92
|
|
|
95
93
|
const ab: Merge<Foo, Bar> = {a: 1, b: 2};
|
|
96
94
|
```
|
|
97
|
-
|
|
98
|
-
@category Utilities
|
|
99
95
|
*/
|
|
100
96
|
export type Merge<Destination, Source> = {
|
|
101
97
|
[Key in keyof OmitIndexSignature<Destination & Source>]: Key extends keyof Source
|
|
@@ -126,7 +122,6 @@ export type Merge<Destination, Source> = {
|
|
|
126
122
|
type StringKeysAndUndefined = ConditionalKeys<Example, string | undefined>;
|
|
127
123
|
//=> 'a' | 'c'
|
|
128
124
|
```
|
|
129
|
-
@category Utilities
|
|
130
125
|
*/
|
|
131
126
|
export type ConditionalKeys<Base, Condition> = NonNullable<
|
|
132
127
|
// Wrap in `NonNullable` to strip away the `undefined` type from the produced union.
|
|
@@ -169,7 +164,6 @@ export type ConditionalKeys<Base, Condition> = NonNullable<
|
|
|
169
164
|
type NonStringKeysOnly = ConditionalExcept<Example, string>;
|
|
170
165
|
//=> {b: string | number; c: () => void; d: {}}
|
|
171
166
|
```
|
|
172
|
-
@category Utilities
|
|
173
167
|
*/
|
|
174
168
|
export type ConditionalExcept<Base, Condition> = Except<Base, ConditionalKeys<Base, Condition>>
|
|
175
169
|
|
|
@@ -200,7 +194,6 @@ export type ConditionalExcept<Base, Condition> = Except<Base, ConditionalKeys<Ba
|
|
|
200
194
|
type StringKeysOnly = ConditionalPick<Example, string>;
|
|
201
195
|
//=> {a: string}
|
|
202
196
|
```
|
|
203
|
-
@category Utilities
|
|
204
197
|
*/
|
|
205
198
|
export type ConditionalPick<Base, Condition> = Pick<Base, ConditionalKeys<Base, Condition>>
|
|
206
199
|
|
package/src/types.ts
CHANGED
|
@@ -396,7 +396,7 @@ export type FalsyValue = false | '' | 0 | null | undefined
|
|
|
396
396
|
* err.data = {} // can be done, because it was casted
|
|
397
397
|
* }
|
|
398
398
|
*/
|
|
399
|
-
export function _typeCast<T>(
|
|
399
|
+
export function _typeCast<T>(_v: any): asserts _v is T {}
|
|
400
400
|
|
|
401
401
|
/**
|
|
402
402
|
* Type-safe Object.assign that checks that part is indeed a Partial<T>
|
|
@@ -469,8 +469,6 @@ export type Class<T = any> = new (...args: any[]) => T
|
|
|
469
469
|
data.foo.push('bar');
|
|
470
470
|
//=> error TS2339: Property 'push' does not exist on type 'readonly string[]'
|
|
471
471
|
```
|
|
472
|
-
|
|
473
|
-
@category Utilities
|
|
474
472
|
*/
|
|
475
473
|
/* eslint-disable @typescript-eslint/no-restricted-types */
|
|
476
474
|
export type ReadonlyDeep<T> = T extends Primitive | ((...args: any[]) => unknown)
|