@etsoo/shared 1.2.52 → 1.2.54
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/.github/workflows/main.yml +6 -5
- package/lib/cjs/ActionResult.d.ts +1 -1
- package/lib/cjs/ActionResult.js +3 -3
- package/lib/cjs/ArrayUtils.d.ts +1 -1
- package/lib/cjs/ArrayUtils.js +4 -4
- package/lib/cjs/ColorUtils.d.ts +1 -1
- package/lib/cjs/ColorUtils.js +2 -2
- package/lib/cjs/DataTypes.d.ts +6 -6
- package/lib/cjs/DataTypes.js +50 -51
- package/lib/cjs/DateUtils.d.ts +1 -1
- package/lib/cjs/DateUtils.js +27 -28
- package/lib/cjs/DomUtils.d.ts +3 -3
- package/lib/cjs/DomUtils.js +64 -73
- package/lib/cjs/ExtendUtils.d.ts +1 -1
- package/lib/cjs/ExtendUtils.js +6 -6
- package/lib/cjs/IActionResult.d.ts +1 -1
- package/lib/cjs/NumberUtils.d.ts +1 -1
- package/lib/cjs/NumberUtils.js +9 -9
- package/lib/cjs/StorageUtils.js +2 -2
- package/lib/cjs/Utils.d.ts +4 -4
- package/lib/cjs/Utils.js +58 -62
- package/lib/cjs/index.d.ts +22 -22
- package/lib/cjs/storage/WindowStorage.d.ts +1 -1
- package/lib/cjs/types/ContentDisposition.d.ts +2 -2
- package/lib/cjs/types/ContentDisposition.js +11 -13
- package/lib/cjs/types/EColor.js +5 -7
- package/lib/cjs/types/EHistory.d.ts +3 -3
- package/lib/cjs/types/EHistory.js +4 -4
- package/lib/cjs/types/ErrorData.d.ts +1 -1
- package/lib/cjs/types/EventClass.js +1 -1
- package/lib/mjs/ActionResult.d.ts +1 -1
- package/lib/mjs/ActionResult.js +3 -3
- package/lib/mjs/ArrayUtils.d.ts +1 -1
- package/lib/mjs/ArrayUtils.js +5 -5
- package/lib/mjs/ColorUtils.d.ts +1 -1
- package/lib/mjs/ColorUtils.js +3 -3
- package/lib/mjs/DataTypes.d.ts +6 -6
- package/lib/mjs/DataTypes.js +50 -51
- package/lib/mjs/DateUtils.d.ts +1 -1
- package/lib/mjs/DateUtils.js +27 -28
- package/lib/mjs/DomUtils.d.ts +3 -3
- package/lib/mjs/DomUtils.js +67 -76
- package/lib/mjs/ExtendUtils.d.ts +1 -1
- package/lib/mjs/ExtendUtils.js +6 -6
- package/lib/mjs/IActionResult.d.ts +1 -1
- package/lib/mjs/NumberUtils.d.ts +1 -1
- package/lib/mjs/NumberUtils.js +9 -9
- package/lib/mjs/StorageUtils.js +4 -4
- package/lib/mjs/Utils.d.ts +4 -4
- package/lib/mjs/Utils.js +61 -65
- package/lib/mjs/index.d.ts +22 -22
- package/lib/mjs/index.js +22 -22
- package/lib/mjs/storage/WindowStorage.d.ts +1 -1
- package/lib/mjs/storage/WindowStorage.js +2 -2
- package/lib/mjs/types/ContentDisposition.d.ts +2 -2
- package/lib/mjs/types/ContentDisposition.js +12 -14
- package/lib/mjs/types/EColor.js +5 -7
- package/lib/mjs/types/EHistory.d.ts +3 -3
- package/lib/mjs/types/EHistory.js +5 -5
- package/lib/mjs/types/ErrorData.d.ts +1 -1
- package/lib/mjs/types/EventClass.js +1 -1
- package/package.json +61 -63
- package/src/ActionResult.ts +23 -23
- package/src/ArrayUtils.ts +164 -172
- package/src/ColorUtils.ts +80 -82
- package/src/DataTypes.ts +745 -754
- package/src/DateUtils.ts +266 -268
- package/src/DomUtils.ts +806 -831
- package/src/ExtendUtils.ts +191 -191
- package/src/IActionResult.ts +42 -42
- package/src/Keyboard.ts +258 -258
- package/src/NumberUtils.ts +135 -135
- package/src/StorageUtils.ts +117 -117
- package/src/Utils.ts +908 -930
- package/src/index.ts +22 -22
- package/src/node/Storage.ts +53 -53
- package/src/storage/IStorage.ts +62 -62
- package/src/storage/WindowStorage.ts +140 -140
- package/src/types/ContentDisposition.ts +59 -63
- package/src/types/DataError.ts +15 -15
- package/src/types/DelayedExecutorType.ts +15 -15
- package/src/types/EColor.ts +241 -248
- package/src/types/EHistory.ts +151 -151
- package/src/types/ErrorData.ts +11 -11
- package/src/types/EventClass.ts +220 -220
- package/src/types/FormData.ts +25 -25
- package/src/types/ParsedPath.ts +5 -5
- package/tsconfig.cjs.json +16 -16
- package/tsconfig.json +16 -16
- package/.eslintignore +0 -3
- package/.eslintrc.json +0 -29
- package/.prettierignore +0 -5
- package/.prettierrc +0 -6
package/src/DataTypes.ts
CHANGED
|
@@ -5,801 +5,792 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
declare global {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
interface BigInt {
|
|
9
|
+
toJSON(): String;
|
|
10
|
+
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
BigInt.prototype.toJSON = function () {
|
|
14
|
-
|
|
14
|
+
return this.toString() + "n";
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Interface data types
|
|
19
19
|
*/
|
|
20
20
|
export namespace DataTypes {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Basic types, includes number, bigint, Date, boolean, string
|
|
23
|
+
*/
|
|
24
|
+
export type Basic = number | bigint | Date | boolean | string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Basic type and basic type array names array
|
|
28
|
+
*/
|
|
29
|
+
export const BasicArray = [
|
|
30
|
+
"number",
|
|
31
|
+
"number[]",
|
|
32
|
+
"bigint",
|
|
33
|
+
"bigint[]",
|
|
34
|
+
"date",
|
|
35
|
+
"date[]",
|
|
36
|
+
"boolean",
|
|
37
|
+
"boolean[]",
|
|
38
|
+
"string",
|
|
39
|
+
"string[]",
|
|
40
|
+
"unknown[]"
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Basic type names
|
|
45
|
+
*/
|
|
46
|
+
export type BasicNames = (typeof BasicArray)[number];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Basic type template
|
|
50
|
+
*/
|
|
51
|
+
export type BasicTemplate = { [key: string]: BasicNames };
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Basic template type
|
|
55
|
+
*/
|
|
56
|
+
export type BasicTemplateType<T extends BasicTemplate> = {
|
|
57
|
+
[P in keyof T]?: BasicConditional<T[P]>;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Basic conditinal type
|
|
62
|
+
*/
|
|
63
|
+
export type BasicConditional<T extends BasicNames> = T extends "string"
|
|
64
|
+
? string
|
|
65
|
+
: T extends "string[]"
|
|
66
|
+
? string[]
|
|
67
|
+
: T extends "date"
|
|
68
|
+
? Date
|
|
69
|
+
: T extends "date[]"
|
|
70
|
+
? Date[]
|
|
71
|
+
: T extends "boolean"
|
|
72
|
+
? boolean
|
|
73
|
+
: T extends "boolean[]"
|
|
74
|
+
? boolean[]
|
|
75
|
+
: T extends "number"
|
|
76
|
+
? number
|
|
77
|
+
: T extends "number[]"
|
|
78
|
+
? number[]
|
|
79
|
+
: T extends "bigint"
|
|
80
|
+
? bigint
|
|
81
|
+
: T extends "bigint[]"
|
|
82
|
+
? bigint[]
|
|
83
|
+
: unknown[];
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Basic or basic array type
|
|
87
|
+
*/
|
|
88
|
+
export type Simple = Basic | Array<Basic>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Simple type enum
|
|
92
|
+
*/
|
|
93
|
+
export enum SimpleEnum {
|
|
94
|
+
Number = 1,
|
|
95
|
+
Bigint = 2,
|
|
96
|
+
Date = 3,
|
|
97
|
+
Boolean = 4,
|
|
98
|
+
String = 5,
|
|
99
|
+
Array = 9
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Simple type names
|
|
104
|
+
*/
|
|
105
|
+
export type SimpleNames = Lowercase<keyof typeof SimpleEnum>;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Extended type enum
|
|
109
|
+
*/
|
|
110
|
+
export enum ExtendedEnum {
|
|
111
|
+
Unkwown = 0,
|
|
112
|
+
|
|
113
|
+
Int = 10,
|
|
114
|
+
Money = 11,
|
|
115
|
+
IntMoney = 12,
|
|
116
|
+
DateTime = 13,
|
|
117
|
+
|
|
118
|
+
Email = 21,
|
|
119
|
+
Phone = 22,
|
|
120
|
+
URL = 23,
|
|
121
|
+
Logo = 24
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Combined type enum
|
|
126
|
+
*/
|
|
127
|
+
export const CombinedEnum = {
|
|
128
|
+
...SimpleEnum,
|
|
129
|
+
...ExtendedEnum
|
|
130
|
+
};
|
|
131
|
+
export type CombinedEnum = SimpleEnum | ExtendedEnum;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Horizontal align enum
|
|
135
|
+
*/
|
|
136
|
+
export enum HAlignEnum {
|
|
137
|
+
Left = 1,
|
|
138
|
+
Center = 2,
|
|
139
|
+
Right = 3
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Horizontal align
|
|
144
|
+
*/
|
|
145
|
+
export type HAlign = Lowercase<keyof typeof HAlignEnum>;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Vertical align enum
|
|
149
|
+
*/
|
|
150
|
+
export enum VAlignEnum {
|
|
151
|
+
Top = 1,
|
|
152
|
+
Center = 2,
|
|
153
|
+
Bottom = 3
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Vertical align
|
|
158
|
+
*/
|
|
159
|
+
export type VAlign = Lowercase<keyof typeof VAlignEnum>;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Placement enum
|
|
163
|
+
*/
|
|
164
|
+
export enum PlacementEnum {
|
|
165
|
+
TopLeft,
|
|
166
|
+
TopCenter,
|
|
167
|
+
TopRight,
|
|
168
|
+
|
|
169
|
+
MiddleLeft,
|
|
170
|
+
Center,
|
|
171
|
+
MiddleRight,
|
|
172
|
+
|
|
173
|
+
BottomLeft,
|
|
174
|
+
BottomCenter,
|
|
175
|
+
BottomRight,
|
|
176
|
+
|
|
177
|
+
Unknown // Reserved for modal, only one instance held at the same time
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Placement type
|
|
182
|
+
*/
|
|
183
|
+
export type Placement = keyof typeof PlacementEnum;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Add and edit data type
|
|
187
|
+
* ChangedFields for editing case
|
|
188
|
+
*/
|
|
189
|
+
export type AddAndEditType<
|
|
190
|
+
T extends { [key in D]: IdType },
|
|
191
|
+
D extends string = "id"
|
|
192
|
+
> =
|
|
193
|
+
| (Omit<T, D> & { [key in D]?: undefined | never })
|
|
194
|
+
| (Partial<T> & Readonly<Pick<T, D>> & { changedFields?: string[] });
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Add or edit conditional type
|
|
198
|
+
* ChangedFields for editing case
|
|
199
|
+
*/
|
|
200
|
+
export type AddOrEditType<
|
|
201
|
+
T extends { [key in D]: IdType }, // Entity modal
|
|
202
|
+
E extends boolean, // Editing or not
|
|
203
|
+
D extends string = "id" // Default is 'id' field
|
|
204
|
+
> = E extends false
|
|
205
|
+
? Optional<T, D>
|
|
206
|
+
: Partial<T> & Readonly<Pick<T, D>> & { changedFields?: string[] };
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Key collection, like { key1: {}, key2: {} }
|
|
210
|
+
*/
|
|
211
|
+
export type KeyCollection<K extends readonly string[], I extends object> = {
|
|
212
|
+
[P in K[number]]: I;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Enum value type
|
|
217
|
+
*/
|
|
218
|
+
export type EnumValue = number | string;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Enum base type
|
|
222
|
+
*/
|
|
223
|
+
export type EnumBase = Record<string, EnumValue>;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Function type
|
|
227
|
+
*/
|
|
228
|
+
export type Func<R> = (...args: any[]) => R;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Mixins constructor
|
|
232
|
+
*/
|
|
233
|
+
export type MConstructor<T = {}> = new (...args: any[]) => T;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Make properties optional
|
|
237
|
+
*/
|
|
238
|
+
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* String key, unknown value Record
|
|
242
|
+
*/
|
|
243
|
+
export type StringRecord = Record<string, unknown>;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* String key, string value Record
|
|
247
|
+
*/
|
|
248
|
+
export type StringDictionary = Record<string, string>;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Simple object, string key, simple type and null value Record
|
|
252
|
+
*/
|
|
253
|
+
export type SimpleObject = Record<string, Simple | null | undefined>;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Item with id property
|
|
257
|
+
*/
|
|
258
|
+
export type IdItem<T extends IdType = number> = {
|
|
259
|
+
/**
|
|
260
|
+
* Id field
|
|
261
|
+
*/
|
|
262
|
+
id: T;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Item with id and label property
|
|
267
|
+
*/
|
|
268
|
+
export type IdLabelItem<T extends IdType = number> = IdItem<T> & {
|
|
269
|
+
/**
|
|
270
|
+
* label field
|
|
271
|
+
*/
|
|
272
|
+
label: string;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Item with id and name property
|
|
277
|
+
*/
|
|
278
|
+
export type IdNameItem<T extends IdType = number> = IdItem<T> & {
|
|
279
|
+
/**
|
|
280
|
+
* name field
|
|
281
|
+
*/
|
|
282
|
+
name: string;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Item with id and title property
|
|
287
|
+
*/
|
|
288
|
+
export type IdTitleItem<T extends IdType = number> = IdItem<T> & {
|
|
289
|
+
/**
|
|
290
|
+
* title field
|
|
291
|
+
*/
|
|
292
|
+
title: string;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Item with id and label dynamic type
|
|
297
|
+
*/
|
|
298
|
+
export type IdLabelType<
|
|
299
|
+
I extends string,
|
|
300
|
+
L extends string,
|
|
301
|
+
D extends IdType = number
|
|
302
|
+
> = DIS<I, D> & DIS<L, string>;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Get specific type keys
|
|
306
|
+
*/
|
|
307
|
+
export type Keys<T extends object, R = IdType> = {
|
|
308
|
+
[k in keyof T]: T[k] extends R ? k : never;
|
|
309
|
+
}[keyof T];
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Require at least one property of the keys
|
|
313
|
+
*/
|
|
314
|
+
export type RequireAtLeastOne<T, Keys extends keyof T> = Pick<
|
|
315
|
+
T,
|
|
316
|
+
Exclude<keyof T, Keys>
|
|
317
|
+
> &
|
|
318
|
+
{
|
|
319
|
+
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
|
|
320
|
+
}[Keys];
|
|
25
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Culture definiton
|
|
324
|
+
*/
|
|
325
|
+
export type CultureDefinition<T extends StringRecord = StringRecord> = {
|
|
26
326
|
/**
|
|
27
|
-
*
|
|
327
|
+
* Name, like zh-CN
|
|
28
328
|
*/
|
|
29
|
-
|
|
30
|
-
'number',
|
|
31
|
-
'number[]',
|
|
32
|
-
'bigint',
|
|
33
|
-
'bigint[]',
|
|
34
|
-
'date',
|
|
35
|
-
'date[]',
|
|
36
|
-
'boolean',
|
|
37
|
-
'boolean[]',
|
|
38
|
-
'string',
|
|
39
|
-
'string[]',
|
|
40
|
-
'unknown[]'
|
|
41
|
-
] as const;
|
|
329
|
+
readonly name: string;
|
|
42
330
|
|
|
43
331
|
/**
|
|
44
|
-
*
|
|
332
|
+
* Label for description, like Simplifined Chinese
|
|
45
333
|
*/
|
|
46
|
-
|
|
334
|
+
label: string;
|
|
47
335
|
|
|
48
336
|
/**
|
|
49
|
-
*
|
|
337
|
+
* Resources
|
|
50
338
|
*/
|
|
51
|
-
|
|
339
|
+
resources: T | (() => Promise<T>);
|
|
52
340
|
|
|
53
341
|
/**
|
|
54
|
-
*
|
|
342
|
+
* Compatible names
|
|
55
343
|
*/
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
};
|
|
344
|
+
readonly compatibleNames?: string[];
|
|
345
|
+
};
|
|
59
346
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
? string
|
|
65
|
-
: T extends 'string[]'
|
|
66
|
-
? string[]
|
|
67
|
-
: T extends 'date'
|
|
68
|
-
? Date
|
|
69
|
-
: T extends 'date[]'
|
|
70
|
-
? Date[]
|
|
71
|
-
: T extends 'boolean'
|
|
72
|
-
? boolean
|
|
73
|
-
: T extends 'boolean[]'
|
|
74
|
-
? boolean[]
|
|
75
|
-
: T extends 'number'
|
|
76
|
-
? number
|
|
77
|
-
: T extends 'number[]'
|
|
78
|
-
? number[]
|
|
79
|
-
: T extends 'bigint'
|
|
80
|
-
? bigint
|
|
81
|
-
: T extends 'bigint[]'
|
|
82
|
-
? bigint[]
|
|
83
|
-
: unknown[];
|
|
347
|
+
/**
|
|
348
|
+
* Dynamic interface with multiple properties
|
|
349
|
+
*/
|
|
350
|
+
export type DI<K extends readonly string[], T> = { [P in K[number]]: T };
|
|
84
351
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
352
|
+
/**
|
|
353
|
+
* Dynamic interface with single property
|
|
354
|
+
*/
|
|
355
|
+
export type DIS<K extends string, T> = { [P in K]: T };
|
|
89
356
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
Array = 9
|
|
100
|
-
}
|
|
357
|
+
/**
|
|
358
|
+
* Convert value to target type
|
|
359
|
+
* @param input Input value
|
|
360
|
+
* @param target Target type
|
|
361
|
+
* @returns Converted value
|
|
362
|
+
*/
|
|
363
|
+
export function convert<T>(input: unknown, target: T): T | undefined {
|
|
364
|
+
// null or undefined
|
|
365
|
+
if (input == null) return undefined;
|
|
101
366
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
367
|
+
// Array
|
|
368
|
+
if (Array.isArray(target)) {
|
|
369
|
+
// Element item
|
|
370
|
+
const elementItem = target.length > 0 ? target[0] : input;
|
|
371
|
+
const elementType = getBasicNameByValue(elementItem, true);
|
|
106
372
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
*/
|
|
110
|
-
export enum ExtendedEnum {
|
|
111
|
-
Unkwown = 0,
|
|
112
|
-
|
|
113
|
-
Int = 10,
|
|
114
|
-
Money = 11,
|
|
115
|
-
IntMoney = 12,
|
|
116
|
-
DateTime = 13,
|
|
117
|
-
|
|
118
|
-
Email = 21,
|
|
119
|
-
Phone = 22,
|
|
120
|
-
URL = 23,
|
|
121
|
-
Logo = 24
|
|
373
|
+
if (elementType == null) return <T>input;
|
|
374
|
+
return <any>convertByType(input, elementType);
|
|
122
375
|
}
|
|
123
376
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
...ExtendedEnum
|
|
130
|
-
};
|
|
131
|
-
export type CombinedEnum = SimpleEnum | ExtendedEnum;
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Horizontal align enum
|
|
135
|
-
*/
|
|
136
|
-
export enum HAlignEnum {
|
|
137
|
-
Left = 1,
|
|
138
|
-
Center = 2,
|
|
139
|
-
Right = 3
|
|
377
|
+
// Target type
|
|
378
|
+
const targetType = getBasicNameByValue(target, false);
|
|
379
|
+
if (targetType == null) {
|
|
380
|
+
if (typeof input === typeof target) return <T>input;
|
|
381
|
+
return undefined;
|
|
140
382
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
383
|
+
return <T>convertByType(input, targetType);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Convert by type name like 'string'
|
|
388
|
+
* @param input Input value
|
|
389
|
+
* @param targetType Target type
|
|
390
|
+
* @returns Converted value
|
|
391
|
+
*/
|
|
392
|
+
export function convertByType<T extends BasicNames>(
|
|
393
|
+
input: unknown,
|
|
394
|
+
targetType: T
|
|
395
|
+
): BasicConditional<T> | undefined {
|
|
396
|
+
// null or undefined
|
|
397
|
+
// And avoid empty string to mass up in different type
|
|
398
|
+
if (input == null || (typeof input === "string" && input.trim() === ""))
|
|
399
|
+
return undefined;
|
|
400
|
+
|
|
401
|
+
// Return type
|
|
402
|
+
type returnType = BasicConditional<T>;
|
|
403
|
+
|
|
404
|
+
// Array
|
|
405
|
+
if (targetType.endsWith("[]")) {
|
|
406
|
+
// Input array
|
|
407
|
+
const inputArray = Array.isArray(input)
|
|
408
|
+
? input
|
|
409
|
+
: typeof input === "string"
|
|
410
|
+
? input.split(/,\s*/g) // Support comma separated array
|
|
411
|
+
: [input];
|
|
412
|
+
|
|
413
|
+
// Element type
|
|
414
|
+
const elementType = <BasicNames>(
|
|
415
|
+
targetType.slice(0, targetType.length - 2)
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
// Convert type
|
|
419
|
+
return <returnType>(
|
|
420
|
+
inputArray
|
|
421
|
+
.map((item) => convertByType(item, elementType))
|
|
422
|
+
.filter((item) => item != null) // Remove undefined item
|
|
423
|
+
);
|
|
154
424
|
}
|
|
155
425
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
TopRight,
|
|
168
|
-
|
|
169
|
-
MiddleLeft,
|
|
170
|
-
Center,
|
|
171
|
-
MiddleRight,
|
|
172
|
-
|
|
173
|
-
BottomLeft,
|
|
174
|
-
BottomCenter,
|
|
175
|
-
BottomRight,
|
|
176
|
-
|
|
177
|
-
Unknown // Reserved for modal, only one instance held at the same time
|
|
426
|
+
// Same type
|
|
427
|
+
if (typeof input === targetType) return <returnType>input;
|
|
428
|
+
|
|
429
|
+
// Date
|
|
430
|
+
if (targetType === "date") {
|
|
431
|
+
if (input instanceof Date) return <returnType>input;
|
|
432
|
+
if (typeof input === "string" || typeof input === "number") {
|
|
433
|
+
const date = new Date(input);
|
|
434
|
+
return date == null ? undefined : <returnType>date;
|
|
435
|
+
}
|
|
436
|
+
return undefined;
|
|
178
437
|
}
|
|
179
438
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
export type AddAndEditType<
|
|
190
|
-
T extends { [key in D]: IdType },
|
|
191
|
-
D extends string = 'id'
|
|
192
|
-
> =
|
|
193
|
-
| (Omit<T, D> & { [key in D]?: undefined | never })
|
|
194
|
-
| (Partial<T> & Readonly<Pick<T, D>> & { changedFields?: string[] });
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Add or edit conditional type
|
|
198
|
-
* ChangedFields for editing case
|
|
199
|
-
*/
|
|
200
|
-
export type AddOrEditType<
|
|
201
|
-
T extends { [key in D]: IdType }, // Entity modal
|
|
202
|
-
E extends boolean, // Editing or not
|
|
203
|
-
D extends string = 'id' // Default is 'id' field
|
|
204
|
-
> = E extends false
|
|
205
|
-
? Optional<T, D>
|
|
206
|
-
: Partial<T> & Readonly<Pick<T, D>> & { changedFields?: string[] };
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Key collection, like { key1: {}, key2: {} }
|
|
210
|
-
*/
|
|
211
|
-
export type KeyCollection<K extends readonly string[], I extends object> = {
|
|
212
|
-
[P in K[number]]: I;
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Enum value type
|
|
217
|
-
*/
|
|
218
|
-
export type EnumValue = number | string;
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Enum base type
|
|
222
|
-
*/
|
|
223
|
-
export type EnumBase = Record<string, EnumValue>;
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Function type
|
|
227
|
-
*/
|
|
228
|
-
export type Func<R> = (...args: any[]) => R;
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Mixins constructor
|
|
232
|
-
*/
|
|
233
|
-
export type MConstructor<T = {}> = new (...args: any[]) => T;
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Make properties optional
|
|
237
|
-
*/
|
|
238
|
-
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> &
|
|
239
|
-
Omit<T, K>;
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* String key, unknown value Record
|
|
243
|
-
*/
|
|
244
|
-
export type StringRecord = Record<string, unknown>;
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* String key, string value Record
|
|
248
|
-
*/
|
|
249
|
-
export type StringDictionary = Record<string, string>;
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Simple object, string key, simple type and null value Record
|
|
253
|
-
*/
|
|
254
|
-
export type SimpleObject = Record<string, Simple | null | undefined>;
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Item with id property
|
|
258
|
-
*/
|
|
259
|
-
export type IdItem<T extends IdType = number> = {
|
|
260
|
-
/**
|
|
261
|
-
* Id field
|
|
262
|
-
*/
|
|
263
|
-
id: T;
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Item with id and label property
|
|
268
|
-
*/
|
|
269
|
-
export type IdLabelItem<T extends IdType = number> = IdItem<T> & {
|
|
270
|
-
/**
|
|
271
|
-
* label field
|
|
272
|
-
*/
|
|
273
|
-
label: string;
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Item with id and name property
|
|
278
|
-
*/
|
|
279
|
-
export type IdNameItem<T extends IdType = number> = IdItem<T> & {
|
|
280
|
-
/**
|
|
281
|
-
* name field
|
|
282
|
-
*/
|
|
283
|
-
name: string;
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Item with id and title property
|
|
288
|
-
*/
|
|
289
|
-
export type IdTitleItem<T extends IdType = number> = IdItem<T> & {
|
|
290
|
-
/**
|
|
291
|
-
* title field
|
|
292
|
-
*/
|
|
293
|
-
title: string;
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Item with id and label dynamic type
|
|
298
|
-
*/
|
|
299
|
-
export type IdLabelType<
|
|
300
|
-
I extends string,
|
|
301
|
-
L extends string,
|
|
302
|
-
D extends IdType = number
|
|
303
|
-
> = DIS<I, D> & DIS<L, string>;
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Get specific type keys
|
|
307
|
-
*/
|
|
308
|
-
export type Keys<T extends object, R = IdType> = {
|
|
309
|
-
[k in keyof T]: T[k] extends R ? k : never;
|
|
310
|
-
}[keyof T];
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Require at least one property of the keys
|
|
314
|
-
*/
|
|
315
|
-
export type RequireAtLeastOne<T, Keys extends keyof T> = Pick<
|
|
316
|
-
T,
|
|
317
|
-
Exclude<keyof T, Keys>
|
|
318
|
-
> &
|
|
319
|
-
{
|
|
320
|
-
[K in Keys]-?: Required<Pick<T, K>> &
|
|
321
|
-
Partial<Pick<T, Exclude<Keys, K>>>;
|
|
322
|
-
}[Keys];
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Culture definiton
|
|
326
|
-
*/
|
|
327
|
-
export type CultureDefinition<T extends StringRecord = StringRecord> = {
|
|
328
|
-
/**
|
|
329
|
-
* Name, like zh-CN
|
|
330
|
-
*/
|
|
331
|
-
readonly name: string;
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Label for description, like Simplifined Chinese
|
|
335
|
-
*/
|
|
336
|
-
label: string;
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Resources
|
|
340
|
-
*/
|
|
341
|
-
resources: T | (() => Promise<T>);
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Compatible names
|
|
345
|
-
*/
|
|
346
|
-
readonly compatibleNames?: string[];
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Dynamic interface with multiple properties
|
|
351
|
-
*/
|
|
352
|
-
export type DI<K extends readonly string[], T> = { [P in K[number]]: T };
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Dynamic interface with single property
|
|
356
|
-
*/
|
|
357
|
-
export type DIS<K extends string, T> = { [P in K]: T };
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Convert value to target type
|
|
361
|
-
* @param input Input value
|
|
362
|
-
* @param target Target type
|
|
363
|
-
* @returns Converted value
|
|
364
|
-
*/
|
|
365
|
-
export function convert<T>(input: unknown, target: T): T | undefined {
|
|
366
|
-
// null or undefined
|
|
367
|
-
if (input == null) return undefined;
|
|
368
|
-
|
|
369
|
-
// Array
|
|
370
|
-
if (Array.isArray(target)) {
|
|
371
|
-
// Element item
|
|
372
|
-
const elementItem = target.length > 0 ? target[0] : input;
|
|
373
|
-
const elementType = getBasicNameByValue(elementItem, true);
|
|
374
|
-
|
|
375
|
-
if (elementType == null) return <T>input;
|
|
376
|
-
return <any>convertByType(input, elementType);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Target type
|
|
380
|
-
const targetType = getBasicNameByValue(target, false);
|
|
381
|
-
if (targetType == null) {
|
|
382
|
-
if (typeof input === typeof target) return <T>input;
|
|
383
|
-
return undefined;
|
|
384
|
-
}
|
|
385
|
-
return <T>convertByType(input, targetType);
|
|
439
|
+
// Bigint
|
|
440
|
+
if (targetType === "bigint") {
|
|
441
|
+
if (
|
|
442
|
+
typeof input === "string" ||
|
|
443
|
+
typeof input === "number" ||
|
|
444
|
+
typeof input === "boolean"
|
|
445
|
+
)
|
|
446
|
+
return <returnType>BigInt(input);
|
|
447
|
+
return undefined;
|
|
386
448
|
}
|
|
387
449
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
): BasicConditional<T> | undefined {
|
|
398
|
-
// null or undefined
|
|
399
|
-
// And avoid empty string to mass up in different type
|
|
400
|
-
if (input == null || (typeof input === 'string' && input.trim() === ''))
|
|
401
|
-
return undefined;
|
|
402
|
-
|
|
403
|
-
// Return type
|
|
404
|
-
type returnType = BasicConditional<T>;
|
|
405
|
-
|
|
406
|
-
// Array
|
|
407
|
-
if (targetType.endsWith('[]')) {
|
|
408
|
-
// Input array
|
|
409
|
-
const inputArray = Array.isArray(input)
|
|
410
|
-
? input
|
|
411
|
-
: typeof input === 'string'
|
|
412
|
-
? input.split(/,\s*/g) // Support comma separated array
|
|
413
|
-
: [input];
|
|
414
|
-
|
|
415
|
-
// Element type
|
|
416
|
-
const elementType = <BasicNames>(
|
|
417
|
-
targetType.slice(0, targetType.length - 2)
|
|
418
|
-
);
|
|
419
|
-
|
|
420
|
-
// Convert type
|
|
421
|
-
return <returnType>(
|
|
422
|
-
inputArray
|
|
423
|
-
.map((item) => convertByType(item, elementType))
|
|
424
|
-
.filter((item) => item != null) // Remove undefined item
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Same type
|
|
429
|
-
if (typeof input === targetType) return <returnType>input;
|
|
430
|
-
|
|
431
|
-
// Date
|
|
432
|
-
if (targetType === 'date') {
|
|
433
|
-
if (input instanceof Date) return <returnType>input;
|
|
434
|
-
if (typeof input === 'string' || typeof input === 'number') {
|
|
435
|
-
const date = new Date(input);
|
|
436
|
-
return date == null ? undefined : <returnType>date;
|
|
437
|
-
}
|
|
438
|
-
return undefined;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// Bigint
|
|
442
|
-
if (targetType === 'bigint') {
|
|
443
|
-
if (
|
|
444
|
-
typeof input === 'string' ||
|
|
445
|
-
typeof input === 'number' ||
|
|
446
|
-
typeof input === 'boolean'
|
|
447
|
-
)
|
|
448
|
-
return <returnType>BigInt(input);
|
|
449
|
-
return undefined;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Boolean
|
|
453
|
-
if (targetType === 'boolean') {
|
|
454
|
-
if (typeof input === 'string' || typeof input === 'number') {
|
|
455
|
-
// Here are different with official definition
|
|
456
|
-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
|
457
|
-
if (input === '0' || input === 'false')
|
|
458
|
-
return <returnType>false;
|
|
459
|
-
return <returnType>Boolean(input);
|
|
460
|
-
}
|
|
461
|
-
return undefined;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// Number
|
|
465
|
-
if (targetType === 'number') {
|
|
466
|
-
const number = Number(input);
|
|
467
|
-
return isNaN(number) ? undefined : <returnType>number;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// String
|
|
471
|
-
if (targetType === 'string') {
|
|
472
|
-
return <returnType>String(input);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// Default
|
|
476
|
-
return undefined;
|
|
450
|
+
// Boolean
|
|
451
|
+
if (targetType === "boolean") {
|
|
452
|
+
if (typeof input === "string" || typeof input === "number") {
|
|
453
|
+
// Here are different with official definition
|
|
454
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
|
455
|
+
if (input === "0" || input === "false") return <returnType>false;
|
|
456
|
+
return <returnType>Boolean(input);
|
|
457
|
+
}
|
|
458
|
+
return undefined;
|
|
477
459
|
}
|
|
478
460
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
* @returns Converted type
|
|
484
|
-
*/
|
|
485
|
-
export function convertSimple(
|
|
486
|
-
input: unknown,
|
|
487
|
-
enumType: CombinedEnum
|
|
488
|
-
): Simple | unknown[] | undefined {
|
|
489
|
-
const type = getBasicName(enumType);
|
|
490
|
-
const value = convertByType(input, type);
|
|
491
|
-
if (value == null) return undefined;
|
|
492
|
-
|
|
493
|
-
if (typeof value === 'number') {
|
|
494
|
-
if (
|
|
495
|
-
enumType === CombinedEnum.Int ||
|
|
496
|
-
enumType === CombinedEnum.IntMoney
|
|
497
|
-
)
|
|
498
|
-
return Math.round(value);
|
|
499
|
-
|
|
500
|
-
if (enumType === CombinedEnum.Money)
|
|
501
|
-
return Math.round(10000 * value) / 10000;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
return value;
|
|
461
|
+
// Number
|
|
462
|
+
if (targetType === "number") {
|
|
463
|
+
const number = Number(input);
|
|
464
|
+
return isNaN(number) ? undefined : <returnType>number;
|
|
505
465
|
}
|
|
506
466
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
* @returns Basic type name result
|
|
511
|
-
*/
|
|
512
|
-
export function getBasicName(enumType: CombinedEnum): BasicNames {
|
|
513
|
-
switch (enumType) {
|
|
514
|
-
case CombinedEnum.Array:
|
|
515
|
-
return 'unknown[]';
|
|
516
|
-
case CombinedEnum.Bigint:
|
|
517
|
-
return 'bigint';
|
|
518
|
-
case CombinedEnum.Boolean:
|
|
519
|
-
return 'boolean';
|
|
520
|
-
case CombinedEnum.Date:
|
|
521
|
-
case CombinedEnum.DateTime:
|
|
522
|
-
return 'date';
|
|
523
|
-
case CombinedEnum.Number:
|
|
524
|
-
case CombinedEnum.Int:
|
|
525
|
-
case CombinedEnum.IntMoney:
|
|
526
|
-
case CombinedEnum.Money:
|
|
527
|
-
return 'number';
|
|
528
|
-
default:
|
|
529
|
-
return 'string';
|
|
530
|
-
}
|
|
467
|
+
// String
|
|
468
|
+
if (targetType === "string") {
|
|
469
|
+
return <returnType>String(input);
|
|
531
470
|
}
|
|
532
471
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
return typeName;
|
|
472
|
+
// Default
|
|
473
|
+
return undefined;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Convert value to target enum type
|
|
478
|
+
* @param input Input value
|
|
479
|
+
* @param enumType Target enum type
|
|
480
|
+
* @returns Converted type
|
|
481
|
+
*/
|
|
482
|
+
export function convertSimple(
|
|
483
|
+
input: unknown,
|
|
484
|
+
enumType: CombinedEnum
|
|
485
|
+
): Simple | unknown[] | undefined {
|
|
486
|
+
const type = getBasicName(enumType);
|
|
487
|
+
const value = convertByType(input, type);
|
|
488
|
+
if (value == null) return undefined;
|
|
489
|
+
|
|
490
|
+
if (typeof value === "number") {
|
|
491
|
+
if (enumType === CombinedEnum.Int || enumType === CombinedEnum.IntMoney)
|
|
492
|
+
return Math.round(value);
|
|
493
|
+
|
|
494
|
+
if (enumType === CombinedEnum.Money)
|
|
495
|
+
return Math.round(10000 * value) / 10000;
|
|
559
496
|
}
|
|
560
497
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
)
|
|
571
|
-
|
|
572
|
-
return
|
|
498
|
+
return value;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Get basic type name from Enum type
|
|
503
|
+
* @param enumType Enum type
|
|
504
|
+
* @returns Basic type name result
|
|
505
|
+
*/
|
|
506
|
+
export function getBasicName(enumType: CombinedEnum): BasicNames {
|
|
507
|
+
switch (enumType) {
|
|
508
|
+
case CombinedEnum.Array:
|
|
509
|
+
return "unknown[]";
|
|
510
|
+
case CombinedEnum.Bigint:
|
|
511
|
+
return "bigint";
|
|
512
|
+
case CombinedEnum.Boolean:
|
|
513
|
+
return "boolean";
|
|
514
|
+
case CombinedEnum.Date:
|
|
515
|
+
case CombinedEnum.DateTime:
|
|
516
|
+
return "date";
|
|
517
|
+
case CombinedEnum.Number:
|
|
518
|
+
case CombinedEnum.Int:
|
|
519
|
+
case CombinedEnum.IntMoney:
|
|
520
|
+
case CombinedEnum.Money:
|
|
521
|
+
return "number";
|
|
522
|
+
default:
|
|
523
|
+
return "string";
|
|
573
524
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Get value's basic type name
|
|
529
|
+
* @param value Input value
|
|
530
|
+
* @param isArray Is array
|
|
531
|
+
* @returns Value's basic type name
|
|
532
|
+
*/
|
|
533
|
+
export function getBasicNameByValue(
|
|
534
|
+
value: unknown,
|
|
535
|
+
isArray: boolean = false
|
|
536
|
+
): BasicNames | undefined {
|
|
537
|
+
// null or undefined
|
|
538
|
+
if (value == null) return undefined;
|
|
539
|
+
|
|
540
|
+
// Date
|
|
541
|
+
if (value instanceof Date) {
|
|
542
|
+
return isArray ? "date[]" : "date";
|
|
587
543
|
}
|
|
588
544
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
545
|
+
// No array
|
|
546
|
+
|
|
547
|
+
// Other cases
|
|
548
|
+
const valueType = typeof value;
|
|
549
|
+
const typeName = isArray ? valueType + "[]" : valueType;
|
|
550
|
+
if (!isBasicName(typeName)) return undefined;
|
|
551
|
+
|
|
552
|
+
return typeName;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Get enum item from key
|
|
557
|
+
* @param enumItem Enum
|
|
558
|
+
* @param key Key
|
|
559
|
+
* @returns Enum item
|
|
560
|
+
*/
|
|
561
|
+
export function getEnumByKey<T extends EnumBase, K extends keyof T>(
|
|
562
|
+
enumItem: T,
|
|
563
|
+
key: string
|
|
564
|
+
): T[K] | undefined {
|
|
565
|
+
if (key in enumItem) return <T[K]>enumItem[key];
|
|
566
|
+
return undefined;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Get enum item from value
|
|
571
|
+
* @param enumItem Enum
|
|
572
|
+
* @param value Key
|
|
573
|
+
* @returns Enum item or undefined
|
|
574
|
+
*/
|
|
575
|
+
export function getEnumByValue<T extends EnumBase, K extends keyof T>(
|
|
576
|
+
enumItem: T,
|
|
577
|
+
value: EnumValue
|
|
578
|
+
): T[K] | undefined {
|
|
579
|
+
if (value in enumItem) return <T[K]>value;
|
|
580
|
+
return undefined;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Get enum string literal type value
|
|
585
|
+
* @param enumItem Enum item
|
|
586
|
+
* @param value Value
|
|
587
|
+
* @returns Result
|
|
588
|
+
*/
|
|
589
|
+
export function getEnumKey(enumItem: EnumBase, value: EnumValue) {
|
|
590
|
+
return enumItem[value].toString();
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Get Enum keys
|
|
595
|
+
* @param input Input Enum
|
|
596
|
+
* @returns Keys
|
|
597
|
+
*/
|
|
598
|
+
export function getEnumKeys<T extends EnumBase, K extends keyof T & string>(
|
|
599
|
+
input: T
|
|
600
|
+
): K[] {
|
|
601
|
+
return Object.keys(input)
|
|
602
|
+
.filter((key) => !/^\d+$/.test(key))
|
|
603
|
+
.map((item) => <K>item);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Get ListType2 item label
|
|
608
|
+
* @param item Item
|
|
609
|
+
* @returns Result
|
|
610
|
+
*/
|
|
611
|
+
export function getListItemLabel<D extends ListType2>(item: D) {
|
|
612
|
+
return "label" in item
|
|
613
|
+
? item.label
|
|
614
|
+
: "name" in item
|
|
615
|
+
? item.name
|
|
616
|
+
: item.title;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Get object item label
|
|
621
|
+
* @param item Item
|
|
622
|
+
* @returns Result
|
|
623
|
+
*/
|
|
624
|
+
export function getObjectItemLabel(item: object): string {
|
|
625
|
+
return "label" in item
|
|
626
|
+
? `${item.label}`
|
|
627
|
+
: "name" in item
|
|
628
|
+
? `${item.name}`
|
|
629
|
+
: "title" in item
|
|
630
|
+
? `${item.title}`
|
|
631
|
+
: `${item}`;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Get object field value
|
|
636
|
+
* @param data Data
|
|
637
|
+
* @param key Property name
|
|
638
|
+
* @returns Value
|
|
639
|
+
*/
|
|
640
|
+
export function getValue<T extends object, K extends keyof T | string>(
|
|
641
|
+
data: T | undefined | null,
|
|
642
|
+
key: K
|
|
643
|
+
): K extends keyof T ? T[K] : undefined {
|
|
644
|
+
if (data != null && typeof key === "string" && key in data) {
|
|
645
|
+
return Reflect.get(data, key);
|
|
597
646
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
647
|
+
return undefined as any;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Get object id field value
|
|
652
|
+
* @param data Data
|
|
653
|
+
* @param key Property name
|
|
654
|
+
* @returns Id value
|
|
655
|
+
*/
|
|
656
|
+
export function getIdValue<T extends object, K extends Keys<T, IdType>>(
|
|
657
|
+
data: T,
|
|
658
|
+
key: K
|
|
659
|
+
): T[K] {
|
|
660
|
+
return data[key];
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Get object id field value 1
|
|
665
|
+
* @param data Data
|
|
666
|
+
* @param key Property name
|
|
667
|
+
* @returns Id value
|
|
668
|
+
*/
|
|
669
|
+
export function getIdValue1<T extends object, K extends keyof T | string>(
|
|
670
|
+
data: T | undefined | null,
|
|
671
|
+
key: K
|
|
672
|
+
): K extends keyof T ? (T[K] extends number ? number : string) : undefined {
|
|
673
|
+
const value = getValue(data, key);
|
|
674
|
+
if (value == null) return undefined as any;
|
|
675
|
+
if (typeof value === "number") return value as any;
|
|
676
|
+
return `${value}` as any;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Get object string field value
|
|
681
|
+
* @param data Data
|
|
682
|
+
* @param key Property name
|
|
683
|
+
* @returns String value
|
|
684
|
+
*/
|
|
685
|
+
export function getStringValue<T extends object>(
|
|
686
|
+
data: T | undefined | null,
|
|
687
|
+
key: keyof T | string
|
|
688
|
+
): string | undefined {
|
|
689
|
+
const value = getValue(data, key);
|
|
690
|
+
if (value == null) return undefined;
|
|
691
|
+
if (typeof value === "string") return value;
|
|
692
|
+
return `${value}`;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Check the type is a basic type or not (type guard)
|
|
697
|
+
* @param name Type name
|
|
698
|
+
* @returns Is basic type
|
|
699
|
+
*/
|
|
700
|
+
export function isBasicName(name: string): name is BasicNames {
|
|
701
|
+
return BasicArray.includes(<BasicNames>name);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Is the target a simple object (Type guard)
|
|
706
|
+
* @param input Test data
|
|
707
|
+
* @param includeArray Include array as simple type
|
|
708
|
+
* @returns Result
|
|
709
|
+
*/
|
|
710
|
+
export function isSimpleObject(
|
|
711
|
+
input: unknown,
|
|
712
|
+
includeArray: boolean = true
|
|
713
|
+
): input is SimpleObject {
|
|
714
|
+
return (
|
|
715
|
+
typeof input === "object" &&
|
|
716
|
+
input != null &&
|
|
717
|
+
Object.values(input).every((value) => isSimpleType(value, includeArray))
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Is the input value simple type, include null and undefined
|
|
723
|
+
* @param input Input value
|
|
724
|
+
* @param includeArray Is array included, first non null element shoud also be basic type
|
|
725
|
+
*/
|
|
726
|
+
export function isSimpleType(
|
|
727
|
+
input: unknown,
|
|
728
|
+
includeArray: boolean = true
|
|
729
|
+
): boolean {
|
|
730
|
+
// null & undefined
|
|
731
|
+
if (input == null) return true;
|
|
732
|
+
|
|
733
|
+
// Date
|
|
734
|
+
if (input instanceof Date) return true;
|
|
735
|
+
|
|
736
|
+
// Array
|
|
737
|
+
if (Array.isArray(input)) {
|
|
738
|
+
if (includeArray) {
|
|
739
|
+
return isSimpleType(input.find((item) => item != null));
|
|
740
|
+
} else {
|
|
741
|
+
// No array needed
|
|
742
|
+
return false;
|
|
743
|
+
}
|
|
610
744
|
}
|
|
611
745
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
return
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
* @returns Id value
|
|
661
|
-
*/
|
|
662
|
-
export function getIdValue<T extends object, K extends Keys<T, IdType>>(
|
|
663
|
-
data: T,
|
|
664
|
-
key: K
|
|
665
|
-
): T[K] {
|
|
666
|
-
return data[key];
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
* Get object id field value 1
|
|
671
|
-
* @param data Data
|
|
672
|
-
* @param key Property name
|
|
673
|
-
* @returns Id value
|
|
674
|
-
*/
|
|
675
|
-
export function getIdValue1<T extends object, K extends keyof T | string>(
|
|
676
|
-
data: T | undefined | null,
|
|
677
|
-
key: K
|
|
678
|
-
): K extends keyof T ? (T[K] extends number ? number : string) : undefined {
|
|
679
|
-
const value = getValue(data, key);
|
|
680
|
-
if (value == null) return undefined as any;
|
|
681
|
-
if (typeof value === 'number') return value as any;
|
|
682
|
-
return `${value}` as any;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
/**
|
|
686
|
-
* Get object string field value
|
|
687
|
-
* @param data Data
|
|
688
|
-
* @param key Property name
|
|
689
|
-
* @returns String value
|
|
690
|
-
*/
|
|
691
|
-
export function getStringValue<T extends object>(
|
|
692
|
-
data: T | undefined | null,
|
|
693
|
-
key: keyof T | string
|
|
694
|
-
): string | undefined {
|
|
695
|
-
const value = getValue(data, key);
|
|
696
|
-
if (value == null) return undefined;
|
|
697
|
-
if (typeof value === 'string') return value;
|
|
698
|
-
return `${value}`;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
/**
|
|
702
|
-
* Check the type is a basic type or not (type guard)
|
|
703
|
-
* @param name Type name
|
|
704
|
-
* @returns Is basic type
|
|
705
|
-
*/
|
|
706
|
-
export function isBasicName(name: string): name is BasicNames {
|
|
707
|
-
return BasicArray.includes(<BasicNames>name);
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
/**
|
|
711
|
-
* Is the target a simple object (Type guard)
|
|
712
|
-
* @param input Test data
|
|
713
|
-
* @param includeArray Include array as simple type
|
|
714
|
-
* @returns Result
|
|
715
|
-
*/
|
|
716
|
-
export function isSimpleObject(
|
|
717
|
-
input: unknown,
|
|
718
|
-
includeArray: boolean = true
|
|
719
|
-
): input is SimpleObject {
|
|
720
|
-
return (
|
|
721
|
-
typeof input === 'object' &&
|
|
722
|
-
input != null &&
|
|
723
|
-
Object.values(input).every((value) =>
|
|
724
|
-
isSimpleType(value, includeArray)
|
|
725
|
-
)
|
|
726
|
-
);
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
/**
|
|
730
|
-
* Is the input value simple type, include null and undefined
|
|
731
|
-
* @param input Input value
|
|
732
|
-
* @param includeArray Is array included, first non null element shoud also be basic type
|
|
733
|
-
*/
|
|
734
|
-
export function isSimpleType(
|
|
735
|
-
input: unknown,
|
|
736
|
-
includeArray: boolean = true
|
|
737
|
-
): boolean {
|
|
738
|
-
// null & undefined
|
|
739
|
-
if (input == null) return true;
|
|
740
|
-
|
|
741
|
-
// Date
|
|
742
|
-
if (input instanceof Date) return true;
|
|
743
|
-
|
|
744
|
-
// Array
|
|
745
|
-
if (Array.isArray(input)) {
|
|
746
|
-
if (includeArray) {
|
|
747
|
-
return isSimpleType(input.find((item) => item != null));
|
|
748
|
-
} else {
|
|
749
|
-
// No array needed
|
|
750
|
-
return false;
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
// Other cases
|
|
755
|
-
const type = typeof input;
|
|
756
|
-
if (type === 'function' || type === 'object' || type === 'symbol')
|
|
757
|
-
return false;
|
|
758
|
-
|
|
759
|
-
return true;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
/**
|
|
763
|
-
* JSON.stringify replacer with full path
|
|
764
|
-
* https://stackoverflow.com/questions/61681176/json-stringify-replacer-how-to-get-full-path
|
|
765
|
-
*/
|
|
766
|
-
export function jsonReplacer(
|
|
767
|
-
replacer: (this: any, key: string, value: any, path: string) => any
|
|
768
|
-
) {
|
|
769
|
-
const m = new Map();
|
|
770
|
-
|
|
771
|
-
return function (this: any, key: any, value: any) {
|
|
772
|
-
const path =
|
|
773
|
-
m.get(this) + (Array.isArray(this) ? `[${key}]` : '.' + key);
|
|
774
|
-
if (value === Object(value)) m.set(value, path);
|
|
775
|
-
|
|
776
|
-
return replacer.call(
|
|
777
|
-
this,
|
|
778
|
-
key,
|
|
779
|
-
value,
|
|
780
|
-
path.replace(/undefined\.\.?/, '')
|
|
781
|
-
);
|
|
782
|
-
};
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* JSON.stringify receiver for bigint
|
|
787
|
-
* @param args Keys or paths to convert to bigint
|
|
788
|
-
* @returns JSON receiver function
|
|
789
|
-
*/
|
|
790
|
-
export function jsonBigintReceiver(...args: string[]) {
|
|
791
|
-
return jsonReplacer(function (key, value, path) {
|
|
792
|
-
if (
|
|
793
|
-
(args.includes(key) || args.includes(path)) &&
|
|
794
|
-
typeof value === 'string'
|
|
795
|
-
) {
|
|
796
|
-
if (value.endsWith('n')) return BigInt(value.slice(0, -1));
|
|
797
|
-
else return BigInt(value);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
return value;
|
|
801
|
-
});
|
|
802
|
-
}
|
|
746
|
+
// Other cases
|
|
747
|
+
const type = typeof input;
|
|
748
|
+
if (type === "function" || type === "object" || type === "symbol")
|
|
749
|
+
return false;
|
|
750
|
+
|
|
751
|
+
return true;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* JSON.stringify replacer with full path
|
|
756
|
+
* https://stackoverflow.com/questions/61681176/json-stringify-replacer-how-to-get-full-path
|
|
757
|
+
*/
|
|
758
|
+
export function jsonReplacer(
|
|
759
|
+
replacer: (this: any, key: string, value: any, path: string) => any
|
|
760
|
+
) {
|
|
761
|
+
const m = new Map();
|
|
762
|
+
|
|
763
|
+
return function (this: any, key: any, value: any) {
|
|
764
|
+
const path = m.get(this) + (Array.isArray(this) ? `[${key}]` : "." + key);
|
|
765
|
+
if (value === Object(value)) m.set(value, path);
|
|
766
|
+
|
|
767
|
+
return replacer.call(
|
|
768
|
+
this,
|
|
769
|
+
key,
|
|
770
|
+
value,
|
|
771
|
+
path.replace(/undefined\.\.?/, "")
|
|
772
|
+
);
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* JSON.stringify receiver for bigint
|
|
778
|
+
* @param args Keys or paths to convert to bigint
|
|
779
|
+
* @returns JSON receiver function
|
|
780
|
+
*/
|
|
781
|
+
export function jsonBigintReceiver(...args: string[]) {
|
|
782
|
+
return jsonReplacer(function (key, value, path) {
|
|
783
|
+
if (
|
|
784
|
+
(args.includes(key) || args.includes(path)) &&
|
|
785
|
+
typeof value === "string"
|
|
786
|
+
) {
|
|
787
|
+
if (value.endsWith("n")) return BigInt(value.slice(0, -1));
|
|
788
|
+
else return BigInt(value);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
return value;
|
|
792
|
+
});
|
|
793
|
+
}
|
|
803
794
|
}
|
|
804
795
|
|
|
805
796
|
/**
|
|
@@ -821,27 +812,27 @@ export type ListType1 = DataTypes.IdLabelItem<string>;
|
|
|
821
812
|
* List item with compatible id and name / label / title
|
|
822
813
|
*/
|
|
823
814
|
export type ListType2 = {
|
|
824
|
-
|
|
815
|
+
id: IdType;
|
|
825
816
|
} & ({ label: string } | { name: string } | { title: string });
|
|
826
817
|
|
|
827
818
|
/**
|
|
828
819
|
* Id default type
|
|
829
820
|
*/
|
|
830
821
|
export type IdDefaultType<
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
> = T extends { id: I } ? DataTypes.Keys<T, I> &
|
|
822
|
+
T extends object,
|
|
823
|
+
I extends IdType = IdType
|
|
824
|
+
> = T extends { id: I } ? DataTypes.Keys<T, I> & "id" : DataTypes.Keys<T, I>;
|
|
834
825
|
|
|
835
826
|
/**
|
|
836
827
|
* Label default type
|
|
837
828
|
*/
|
|
838
829
|
export type LabelDefaultType<T extends object> = T extends { label: string }
|
|
839
|
-
|
|
840
|
-
|
|
830
|
+
? DataTypes.Keys<T, string> & "label"
|
|
831
|
+
: DataTypes.Keys<T, string>;
|
|
841
832
|
|
|
842
833
|
/**
|
|
843
834
|
* Title default type
|
|
844
835
|
*/
|
|
845
836
|
export type TitleDefaultType<T extends object> = T extends { title: string }
|
|
846
|
-
|
|
847
|
-
|
|
837
|
+
? DataTypes.Keys<T, string> & "title"
|
|
838
|
+
: DataTypes.Keys<T, string>;
|