@etsoo/shared 1.0.75 → 1.0.79
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/README.md +5 -0
- package/__tests__/Utils.ts +23 -5
- package/lib/cjs/StorageUtils.d.ts +2 -2
- package/lib/cjs/Utils.d.ts +39 -2
- package/lib/cjs/Utils.js +107 -25
- package/lib/mjs/StorageUtils.d.ts +2 -2
- package/lib/mjs/Utils.d.ts +39 -2
- package/lib/mjs/Utils.js +107 -25
- package/package.json +7 -7
- package/src/StorageUtils.ts +2 -2
- package/src/Utils.ts +126 -26
package/README.md
CHANGED
|
@@ -131,6 +131,8 @@ String and other related utilities
|
|
|
131
131
|
|
|
132
132
|
|Name|Description|
|
|
133
133
|
|---:|---|
|
|
134
|
+
|charsToNumber|Base64 chars to number|
|
|
135
|
+
|equals|Two values equal|
|
|
134
136
|
|formatInitial|Format inital character to lower case or upper case|
|
|
135
137
|
|formatString|Format string with parameters|
|
|
136
138
|
|getDataChanges|Get data changed fields with input data updated|
|
|
@@ -139,7 +141,10 @@ String and other related utilities
|
|
|
139
141
|
|mergeFormData|Merge form data to primary one|
|
|
140
142
|
|mergeClasses|Merge class names|
|
|
141
143
|
|newGUID|Create a GUID|
|
|
144
|
+
|numberToChars|Number to base64 chars|
|
|
142
145
|
|objectEqual|Test two objects are equal or not|
|
|
146
|
+
|objectKeys|Get two object's unqiue properties|
|
|
147
|
+
|objectUpdated|Get the new object's updated fields contrast to the previous object|
|
|
143
148
|
|parseString|Parse string (JSON) to specific type|
|
|
144
149
|
|setLabels|Set source with new labels|
|
|
145
150
|
|snakeNameToWord|Snake name to works, 'snake_name' to 'Snake Name'|
|
package/__tests__/Utils.ts
CHANGED
|
@@ -9,7 +9,8 @@ test('Tests for getDataChanges', () => {
|
|
|
9
9
|
price: '6.0',
|
|
10
10
|
amount: '',
|
|
11
11
|
enabled: true,
|
|
12
|
-
value: undefined
|
|
12
|
+
value: undefined,
|
|
13
|
+
ids: [1, 2]
|
|
13
14
|
};
|
|
14
15
|
const initData = {
|
|
15
16
|
id: 1,
|
|
@@ -18,7 +19,8 @@ test('Tests for getDataChanges', () => {
|
|
|
18
19
|
brand: 'ETSOO',
|
|
19
20
|
price: 6,
|
|
20
21
|
amount: 0,
|
|
21
|
-
enabled: true
|
|
22
|
+
enabled: true,
|
|
23
|
+
ids: [1, 2]
|
|
22
24
|
};
|
|
23
25
|
const fields = Utils.getDataChanges(input, initData);
|
|
24
26
|
expect(fields).toStrictEqual(['gender', 'brand', 'amount']);
|
|
@@ -67,6 +69,13 @@ test('Tests for newGUID', () => {
|
|
|
67
69
|
expect(id1.length).toBe(id2.length);
|
|
68
70
|
});
|
|
69
71
|
|
|
72
|
+
test('Tests for numberToChars and charsToNumber', () => {
|
|
73
|
+
const num = 1638777042242;
|
|
74
|
+
const chars = Utils.numberToChars(num);
|
|
75
|
+
expect(chars).toEqual('QmpkdVgv');
|
|
76
|
+
expect(Utils.charsToNumber(chars)).toEqual(num);
|
|
77
|
+
});
|
|
78
|
+
|
|
70
79
|
test('Tests for removeNonLetters', () => {
|
|
71
80
|
const input = '1234-5678@abc.';
|
|
72
81
|
const result = '12345678abc';
|
|
@@ -75,17 +84,26 @@ test('Tests for removeNonLetters', () => {
|
|
|
75
84
|
});
|
|
76
85
|
|
|
77
86
|
test('Tests for objectEqual', () => {
|
|
78
|
-
const obj1 = { a: 1, b: 'abc', c: true, d: null };
|
|
79
|
-
const obj2 = { a: '1', b: 'abc', c: true };
|
|
87
|
+
const obj1 = { a: 1, b: 'abc', c: true, d: null, f: [1, 2] };
|
|
88
|
+
const obj2 = { a: '1', b: 'abc', c: true, f: [1, 2] };
|
|
80
89
|
expect(Utils.objectEqual(obj1, obj2)).toBeFalsy();
|
|
81
90
|
expect(Utils.objectEqual(obj1, obj2, [], 0)).toBeTruthy();
|
|
82
91
|
expect(Utils.objectEqual(obj1, obj2, ['a'])).toBeTruthy();
|
|
83
92
|
expect(Utils.objectEqual(obj1, obj2, ['a'], 2)).toBeFalsy();
|
|
84
93
|
});
|
|
85
94
|
|
|
95
|
+
test('Tests for objectUpdated', () => {
|
|
96
|
+
const objPrev = { a: 1, b: 'abc', c: true, d: null, f: [1, 2] };
|
|
97
|
+
const objNew = { a: 2, b: 'abc', d: new Date(), f: [1, 2, 3] };
|
|
98
|
+
const fields = Utils.objectUpdated(objNew, objPrev, ['d']);
|
|
99
|
+
expect(fields.sort()).toStrictEqual(['a', 'c', 'f']);
|
|
100
|
+
});
|
|
101
|
+
|
|
86
102
|
test('Tests for parseString', () => {
|
|
87
|
-
expect(Utils.parseString('test'
|
|
103
|
+
expect(Utils.parseString<string>('test')).toBe('test');
|
|
88
104
|
expect(Utils.parseString('true', false)).toBe(true);
|
|
105
|
+
expect(Utils.parseString('', false)).toBeFalsy();
|
|
106
|
+
expect(Utils.parseString<number>(undefined)).toBeUndefined();
|
|
89
107
|
expect(Utils.parseString('3.14', 0)).toBe(3.14);
|
|
90
108
|
expect(Utils.parseString('2021/4/13', new Date())).toStrictEqual(
|
|
91
109
|
new Date('2021/4/13')
|
|
@@ -20,7 +20,7 @@ export declare namespace StorageUtils {
|
|
|
20
20
|
* @param key Key name
|
|
21
21
|
* @param defaultValue Default value
|
|
22
22
|
*/
|
|
23
|
-
function getLocalData<T>(key: string, defaultValue
|
|
23
|
+
function getLocalData<T>(key: string, defaultValue?: T): T | undefined;
|
|
24
24
|
/**
|
|
25
25
|
* Get local storage object data
|
|
26
26
|
* @param key Key name
|
|
@@ -30,7 +30,7 @@ export declare namespace StorageUtils {
|
|
|
30
30
|
* Get session storage data
|
|
31
31
|
* @param key Key name
|
|
32
32
|
*/
|
|
33
|
-
function getSessionData<T>(key: string, defaultValue
|
|
33
|
+
function getSessionData<T>(key: string, defaultValue?: T): T | undefined;
|
|
34
34
|
/**
|
|
35
35
|
* Get session storage object data
|
|
36
36
|
* @param key Key name
|
package/lib/cjs/Utils.d.ts
CHANGED
|
@@ -35,6 +35,19 @@ declare global {
|
|
|
35
35
|
* Utilities
|
|
36
36
|
*/
|
|
37
37
|
export declare namespace Utils {
|
|
38
|
+
/**
|
|
39
|
+
* Base64 chars to number
|
|
40
|
+
* @param base64Chars Base64 chars
|
|
41
|
+
* @returns Number
|
|
42
|
+
*/
|
|
43
|
+
function charsToNumber(base64Chars: string): number;
|
|
44
|
+
/**
|
|
45
|
+
* Two values equal
|
|
46
|
+
* @param v1 Value 1
|
|
47
|
+
* @param v2 Value 2
|
|
48
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
49
|
+
*/
|
|
50
|
+
function equals(v1: unknown, v2: unknown, strict?: number): boolean;
|
|
38
51
|
/**
|
|
39
52
|
* Format inital character to lower case or upper case
|
|
40
53
|
* @param input Input string
|
|
@@ -89,6 +102,12 @@ export declare namespace Utils {
|
|
|
89
102
|
* Create a GUID
|
|
90
103
|
*/
|
|
91
104
|
function newGUID(): string;
|
|
105
|
+
/**
|
|
106
|
+
* Number to base64 chars
|
|
107
|
+
* @param num Input number
|
|
108
|
+
* @returns Result
|
|
109
|
+
*/
|
|
110
|
+
function numberToChars(num: number): string;
|
|
92
111
|
/**
|
|
93
112
|
* Test two objects are equal or not
|
|
94
113
|
* @param obj1 Object 1
|
|
@@ -99,12 +118,30 @@ export declare namespace Utils {
|
|
|
99
118
|
*/
|
|
100
119
|
function objectEqual(obj1: {}, obj2: {}, ignoreFields?: string[], strict?: number): boolean;
|
|
101
120
|
/**
|
|
102
|
-
*
|
|
121
|
+
* Get two object's unqiue properties
|
|
122
|
+
* @param obj1 Object 1
|
|
123
|
+
* @param obj2 Object 2
|
|
124
|
+
* @param ignoreFields Ignored fields
|
|
125
|
+
* @returns Unique properties
|
|
126
|
+
*/
|
|
127
|
+
function objectKeys(obj1: {}, obj2: {}, ignoreFields?: string[]): Set<string>;
|
|
128
|
+
/**
|
|
129
|
+
* Get the new object's updated fields contrast to the previous object
|
|
130
|
+
* @param objNew New object
|
|
131
|
+
* @param objPre Previous object
|
|
132
|
+
* @param ignoreFields Ignored fields
|
|
133
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
134
|
+
* @returns Updated fields
|
|
135
|
+
*/
|
|
136
|
+
function objectUpdated(objNew: {}, objPrev: {}, ignoreFields?: string[], strict?: number): string[];
|
|
137
|
+
/**
|
|
138
|
+
* Parse string (JSON) to specific type, no type conversion
|
|
139
|
+
* For type conversion, please use DataTypes.convert
|
|
103
140
|
* @param input Input string
|
|
104
141
|
* @param defaultValue Default value
|
|
105
142
|
* @returns Parsed value
|
|
106
143
|
*/
|
|
107
|
-
function parseString<T>(input: string | undefined | null, defaultValue
|
|
144
|
+
function parseString<T>(input: string | undefined | null, defaultValue?: T): T | undefined;
|
|
108
145
|
/**
|
|
109
146
|
* Remove non letters
|
|
110
147
|
* @param input Input string
|
package/lib/cjs/Utils.js
CHANGED
|
@@ -29,6 +29,43 @@ String.prototype.removeNonLetters = function () {
|
|
|
29
29
|
*/
|
|
30
30
|
var Utils;
|
|
31
31
|
(function (Utils) {
|
|
32
|
+
/**
|
|
33
|
+
* Base64 chars to number
|
|
34
|
+
* @param base64Chars Base64 chars
|
|
35
|
+
* @returns Number
|
|
36
|
+
*/
|
|
37
|
+
function charsToNumber(base64Chars) {
|
|
38
|
+
const chars = typeof Buffer === 'undefined'
|
|
39
|
+
? [...atob(base64Chars)].map((char) => char.charCodeAt(0))
|
|
40
|
+
: [...Buffer.from(base64Chars, 'base64')];
|
|
41
|
+
return chars.reduce((previousValue, currentValue, currentIndex) => {
|
|
42
|
+
return previousValue + currentValue * Math.pow(128, currentIndex);
|
|
43
|
+
}, 0);
|
|
44
|
+
}
|
|
45
|
+
Utils.charsToNumber = charsToNumber;
|
|
46
|
+
/**
|
|
47
|
+
* Two values equal
|
|
48
|
+
* @param v1 Value 1
|
|
49
|
+
* @param v2 Value 2
|
|
50
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
51
|
+
*/
|
|
52
|
+
function equals(v1, v2, strict = 1) {
|
|
53
|
+
// Null and undefined case
|
|
54
|
+
if (v1 == null || v2 == null) {
|
|
55
|
+
if (strict <= 1 && v1 == v2)
|
|
56
|
+
return true;
|
|
57
|
+
return v1 === v2;
|
|
58
|
+
}
|
|
59
|
+
// For array and object
|
|
60
|
+
if (typeof v1 === 'object')
|
|
61
|
+
return JSON.stringify(v1) === JSON.stringify(v2);
|
|
62
|
+
// 1 and '1' case
|
|
63
|
+
if (strict === 0)
|
|
64
|
+
return v1 == v2;
|
|
65
|
+
// Strict equal
|
|
66
|
+
return v1 === v2;
|
|
67
|
+
}
|
|
68
|
+
Utils.equals = equals;
|
|
32
69
|
/**
|
|
33
70
|
* Format inital character to lower case or upper case
|
|
34
71
|
* @param input Input string
|
|
@@ -71,7 +108,7 @@ var Utils;
|
|
|
71
108
|
}
|
|
72
109
|
if (initValue != null) {
|
|
73
110
|
const newValue = DataTypes_1.DataTypes.convert(value, initValue);
|
|
74
|
-
if (newValue
|
|
111
|
+
if (Utils.equals(newValue, initValue)) {
|
|
75
112
|
Reflect.deleteProperty(input, key);
|
|
76
113
|
return;
|
|
77
114
|
}
|
|
@@ -149,6 +186,27 @@ var Utils;
|
|
|
149
186
|
});
|
|
150
187
|
}
|
|
151
188
|
Utils.newGUID = newGUID;
|
|
189
|
+
/**
|
|
190
|
+
* Number to base64 chars
|
|
191
|
+
* @param num Input number
|
|
192
|
+
* @returns Result
|
|
193
|
+
*/
|
|
194
|
+
function numberToChars(num) {
|
|
195
|
+
const codes = [];
|
|
196
|
+
while (num > 0) {
|
|
197
|
+
const code = num % 128;
|
|
198
|
+
codes.push(code);
|
|
199
|
+
num = (num - code) / 128;
|
|
200
|
+
}
|
|
201
|
+
if (typeof Buffer === 'undefined') {
|
|
202
|
+
return btoa(String.fromCharCode(...codes));
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
const buffer = Buffer.from(codes);
|
|
206
|
+
return buffer.toString('base64');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
Utils.numberToChars = numberToChars;
|
|
152
210
|
/**
|
|
153
211
|
* Test two objects are equal or not
|
|
154
212
|
* @param obj1 Object 1
|
|
@@ -158,37 +216,66 @@ var Utils;
|
|
|
158
216
|
* @returns Result
|
|
159
217
|
*/
|
|
160
218
|
function objectEqual(obj1, obj2, ignoreFields = [], strict = 1) {
|
|
161
|
-
//
|
|
162
|
-
const keys =
|
|
163
|
-
...Object.keys(obj1).filter((item) => !ignoreFields.includes(item)),
|
|
164
|
-
...Object.keys(obj2).filter((item) => !ignoreFields.includes(item))
|
|
165
|
-
]);
|
|
219
|
+
// Unique keys
|
|
220
|
+
const keys = Utils.objectKeys(obj1, obj2, ignoreFields);
|
|
166
221
|
for (const key of keys) {
|
|
167
222
|
// Values
|
|
168
223
|
const v1 = Reflect.get(obj1, key);
|
|
169
224
|
const v2 = Reflect.get(obj2, key);
|
|
170
|
-
|
|
171
|
-
if (v1 == null && v2 == null && strict <= 1)
|
|
172
|
-
continue;
|
|
173
|
-
// 1 and '1' case
|
|
174
|
-
if (strict === 0 && v1 == v2)
|
|
175
|
-
continue;
|
|
176
|
-
// Strict equal
|
|
177
|
-
if (v1 !== v2)
|
|
225
|
+
if (!Utils.equals(v1, v2, strict))
|
|
178
226
|
return false;
|
|
179
227
|
}
|
|
180
228
|
return true;
|
|
181
229
|
}
|
|
182
230
|
Utils.objectEqual = objectEqual;
|
|
183
231
|
/**
|
|
184
|
-
*
|
|
232
|
+
* Get two object's unqiue properties
|
|
233
|
+
* @param obj1 Object 1
|
|
234
|
+
* @param obj2 Object 2
|
|
235
|
+
* @param ignoreFields Ignored fields
|
|
236
|
+
* @returns Unique properties
|
|
237
|
+
*/
|
|
238
|
+
function objectKeys(obj1, obj2, ignoreFields = []) {
|
|
239
|
+
// All keys
|
|
240
|
+
const allKeys = [...Object.keys(obj1), ...Object.keys(obj2)].filter((item) => !ignoreFields.includes(item));
|
|
241
|
+
// Unique keys
|
|
242
|
+
return new Set(allKeys);
|
|
243
|
+
}
|
|
244
|
+
Utils.objectKeys = objectKeys;
|
|
245
|
+
/**
|
|
246
|
+
* Get the new object's updated fields contrast to the previous object
|
|
247
|
+
* @param objNew New object
|
|
248
|
+
* @param objPre Previous object
|
|
249
|
+
* @param ignoreFields Ignored fields
|
|
250
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
251
|
+
* @returns Updated fields
|
|
252
|
+
*/
|
|
253
|
+
function objectUpdated(objNew, objPrev, ignoreFields = [], strict = 1) {
|
|
254
|
+
// Fields
|
|
255
|
+
const fields = [];
|
|
256
|
+
// Unique keys
|
|
257
|
+
const keys = Utils.objectKeys(objNew, objPrev, ignoreFields);
|
|
258
|
+
for (const key of keys) {
|
|
259
|
+
// Values
|
|
260
|
+
const vNew = Reflect.get(objNew, key);
|
|
261
|
+
const vPrev = Reflect.get(objPrev, key);
|
|
262
|
+
if (!Utils.equals(vNew, vPrev, strict)) {
|
|
263
|
+
fields.push(key);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return fields;
|
|
267
|
+
}
|
|
268
|
+
Utils.objectUpdated = objectUpdated;
|
|
269
|
+
/**
|
|
270
|
+
* Parse string (JSON) to specific type, no type conversion
|
|
271
|
+
* For type conversion, please use DataTypes.convert
|
|
185
272
|
* @param input Input string
|
|
186
273
|
* @param defaultValue Default value
|
|
187
274
|
* @returns Parsed value
|
|
188
275
|
*/
|
|
189
276
|
function parseString(input, defaultValue) {
|
|
190
|
-
// Undefined case, return default value
|
|
191
|
-
if (input == null)
|
|
277
|
+
// Undefined and empty case, return default value
|
|
278
|
+
if (input == null || input === '')
|
|
192
279
|
return defaultValue;
|
|
193
280
|
// String
|
|
194
281
|
if (typeof defaultValue === 'string')
|
|
@@ -206,16 +293,11 @@ var Utils;
|
|
|
206
293
|
// Return
|
|
207
294
|
return json;
|
|
208
295
|
}
|
|
209
|
-
catch
|
|
210
|
-
|
|
296
|
+
catch {
|
|
297
|
+
if (defaultValue == null)
|
|
298
|
+
return input;
|
|
211
299
|
return defaultValue;
|
|
212
300
|
}
|
|
213
|
-
/*
|
|
214
|
-
finally part will still return the boolean value
|
|
215
|
-
finally {
|
|
216
|
-
return defaultValue
|
|
217
|
-
}
|
|
218
|
-
*/
|
|
219
301
|
}
|
|
220
302
|
Utils.parseString = parseString;
|
|
221
303
|
/**
|
|
@@ -20,7 +20,7 @@ export declare namespace StorageUtils {
|
|
|
20
20
|
* @param key Key name
|
|
21
21
|
* @param defaultValue Default value
|
|
22
22
|
*/
|
|
23
|
-
function getLocalData<T>(key: string, defaultValue
|
|
23
|
+
function getLocalData<T>(key: string, defaultValue?: T): T | undefined;
|
|
24
24
|
/**
|
|
25
25
|
* Get local storage object data
|
|
26
26
|
* @param key Key name
|
|
@@ -30,7 +30,7 @@ export declare namespace StorageUtils {
|
|
|
30
30
|
* Get session storage data
|
|
31
31
|
* @param key Key name
|
|
32
32
|
*/
|
|
33
|
-
function getSessionData<T>(key: string, defaultValue
|
|
33
|
+
function getSessionData<T>(key: string, defaultValue?: T): T | undefined;
|
|
34
34
|
/**
|
|
35
35
|
* Get session storage object data
|
|
36
36
|
* @param key Key name
|
package/lib/mjs/Utils.d.ts
CHANGED
|
@@ -35,6 +35,19 @@ declare global {
|
|
|
35
35
|
* Utilities
|
|
36
36
|
*/
|
|
37
37
|
export declare namespace Utils {
|
|
38
|
+
/**
|
|
39
|
+
* Base64 chars to number
|
|
40
|
+
* @param base64Chars Base64 chars
|
|
41
|
+
* @returns Number
|
|
42
|
+
*/
|
|
43
|
+
function charsToNumber(base64Chars: string): number;
|
|
44
|
+
/**
|
|
45
|
+
* Two values equal
|
|
46
|
+
* @param v1 Value 1
|
|
47
|
+
* @param v2 Value 2
|
|
48
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
49
|
+
*/
|
|
50
|
+
function equals(v1: unknown, v2: unknown, strict?: number): boolean;
|
|
38
51
|
/**
|
|
39
52
|
* Format inital character to lower case or upper case
|
|
40
53
|
* @param input Input string
|
|
@@ -89,6 +102,12 @@ export declare namespace Utils {
|
|
|
89
102
|
* Create a GUID
|
|
90
103
|
*/
|
|
91
104
|
function newGUID(): string;
|
|
105
|
+
/**
|
|
106
|
+
* Number to base64 chars
|
|
107
|
+
* @param num Input number
|
|
108
|
+
* @returns Result
|
|
109
|
+
*/
|
|
110
|
+
function numberToChars(num: number): string;
|
|
92
111
|
/**
|
|
93
112
|
* Test two objects are equal or not
|
|
94
113
|
* @param obj1 Object 1
|
|
@@ -99,12 +118,30 @@ export declare namespace Utils {
|
|
|
99
118
|
*/
|
|
100
119
|
function objectEqual(obj1: {}, obj2: {}, ignoreFields?: string[], strict?: number): boolean;
|
|
101
120
|
/**
|
|
102
|
-
*
|
|
121
|
+
* Get two object's unqiue properties
|
|
122
|
+
* @param obj1 Object 1
|
|
123
|
+
* @param obj2 Object 2
|
|
124
|
+
* @param ignoreFields Ignored fields
|
|
125
|
+
* @returns Unique properties
|
|
126
|
+
*/
|
|
127
|
+
function objectKeys(obj1: {}, obj2: {}, ignoreFields?: string[]): Set<string>;
|
|
128
|
+
/**
|
|
129
|
+
* Get the new object's updated fields contrast to the previous object
|
|
130
|
+
* @param objNew New object
|
|
131
|
+
* @param objPre Previous object
|
|
132
|
+
* @param ignoreFields Ignored fields
|
|
133
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
134
|
+
* @returns Updated fields
|
|
135
|
+
*/
|
|
136
|
+
function objectUpdated(objNew: {}, objPrev: {}, ignoreFields?: string[], strict?: number): string[];
|
|
137
|
+
/**
|
|
138
|
+
* Parse string (JSON) to specific type, no type conversion
|
|
139
|
+
* For type conversion, please use DataTypes.convert
|
|
103
140
|
* @param input Input string
|
|
104
141
|
* @param defaultValue Default value
|
|
105
142
|
* @returns Parsed value
|
|
106
143
|
*/
|
|
107
|
-
function parseString<T>(input: string | undefined | null, defaultValue
|
|
144
|
+
function parseString<T>(input: string | undefined | null, defaultValue?: T): T | undefined;
|
|
108
145
|
/**
|
|
109
146
|
* Remove non letters
|
|
110
147
|
* @param input Input string
|
package/lib/mjs/Utils.js
CHANGED
|
@@ -26,6 +26,43 @@ String.prototype.removeNonLetters = function () {
|
|
|
26
26
|
*/
|
|
27
27
|
export var Utils;
|
|
28
28
|
(function (Utils) {
|
|
29
|
+
/**
|
|
30
|
+
* Base64 chars to number
|
|
31
|
+
* @param base64Chars Base64 chars
|
|
32
|
+
* @returns Number
|
|
33
|
+
*/
|
|
34
|
+
function charsToNumber(base64Chars) {
|
|
35
|
+
const chars = typeof Buffer === 'undefined'
|
|
36
|
+
? [...atob(base64Chars)].map((char) => char.charCodeAt(0))
|
|
37
|
+
: [...Buffer.from(base64Chars, 'base64')];
|
|
38
|
+
return chars.reduce((previousValue, currentValue, currentIndex) => {
|
|
39
|
+
return previousValue + currentValue * Math.pow(128, currentIndex);
|
|
40
|
+
}, 0);
|
|
41
|
+
}
|
|
42
|
+
Utils.charsToNumber = charsToNumber;
|
|
43
|
+
/**
|
|
44
|
+
* Two values equal
|
|
45
|
+
* @param v1 Value 1
|
|
46
|
+
* @param v2 Value 2
|
|
47
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
48
|
+
*/
|
|
49
|
+
function equals(v1, v2, strict = 1) {
|
|
50
|
+
// Null and undefined case
|
|
51
|
+
if (v1 == null || v2 == null) {
|
|
52
|
+
if (strict <= 1 && v1 == v2)
|
|
53
|
+
return true;
|
|
54
|
+
return v1 === v2;
|
|
55
|
+
}
|
|
56
|
+
// For array and object
|
|
57
|
+
if (typeof v1 === 'object')
|
|
58
|
+
return JSON.stringify(v1) === JSON.stringify(v2);
|
|
59
|
+
// 1 and '1' case
|
|
60
|
+
if (strict === 0)
|
|
61
|
+
return v1 == v2;
|
|
62
|
+
// Strict equal
|
|
63
|
+
return v1 === v2;
|
|
64
|
+
}
|
|
65
|
+
Utils.equals = equals;
|
|
29
66
|
/**
|
|
30
67
|
* Format inital character to lower case or upper case
|
|
31
68
|
* @param input Input string
|
|
@@ -68,7 +105,7 @@ export var Utils;
|
|
|
68
105
|
}
|
|
69
106
|
if (initValue != null) {
|
|
70
107
|
const newValue = DataTypes.convert(value, initValue);
|
|
71
|
-
if (newValue
|
|
108
|
+
if (Utils.equals(newValue, initValue)) {
|
|
72
109
|
Reflect.deleteProperty(input, key);
|
|
73
110
|
return;
|
|
74
111
|
}
|
|
@@ -146,6 +183,27 @@ export var Utils;
|
|
|
146
183
|
});
|
|
147
184
|
}
|
|
148
185
|
Utils.newGUID = newGUID;
|
|
186
|
+
/**
|
|
187
|
+
* Number to base64 chars
|
|
188
|
+
* @param num Input number
|
|
189
|
+
* @returns Result
|
|
190
|
+
*/
|
|
191
|
+
function numberToChars(num) {
|
|
192
|
+
const codes = [];
|
|
193
|
+
while (num > 0) {
|
|
194
|
+
const code = num % 128;
|
|
195
|
+
codes.push(code);
|
|
196
|
+
num = (num - code) / 128;
|
|
197
|
+
}
|
|
198
|
+
if (typeof Buffer === 'undefined') {
|
|
199
|
+
return btoa(String.fromCharCode(...codes));
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
const buffer = Buffer.from(codes);
|
|
203
|
+
return buffer.toString('base64');
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
Utils.numberToChars = numberToChars;
|
|
149
207
|
/**
|
|
150
208
|
* Test two objects are equal or not
|
|
151
209
|
* @param obj1 Object 1
|
|
@@ -155,37 +213,66 @@ export var Utils;
|
|
|
155
213
|
* @returns Result
|
|
156
214
|
*/
|
|
157
215
|
function objectEqual(obj1, obj2, ignoreFields = [], strict = 1) {
|
|
158
|
-
//
|
|
159
|
-
const keys =
|
|
160
|
-
...Object.keys(obj1).filter((item) => !ignoreFields.includes(item)),
|
|
161
|
-
...Object.keys(obj2).filter((item) => !ignoreFields.includes(item))
|
|
162
|
-
]);
|
|
216
|
+
// Unique keys
|
|
217
|
+
const keys = Utils.objectKeys(obj1, obj2, ignoreFields);
|
|
163
218
|
for (const key of keys) {
|
|
164
219
|
// Values
|
|
165
220
|
const v1 = Reflect.get(obj1, key);
|
|
166
221
|
const v2 = Reflect.get(obj2, key);
|
|
167
|
-
|
|
168
|
-
if (v1 == null && v2 == null && strict <= 1)
|
|
169
|
-
continue;
|
|
170
|
-
// 1 and '1' case
|
|
171
|
-
if (strict === 0 && v1 == v2)
|
|
172
|
-
continue;
|
|
173
|
-
// Strict equal
|
|
174
|
-
if (v1 !== v2)
|
|
222
|
+
if (!Utils.equals(v1, v2, strict))
|
|
175
223
|
return false;
|
|
176
224
|
}
|
|
177
225
|
return true;
|
|
178
226
|
}
|
|
179
227
|
Utils.objectEqual = objectEqual;
|
|
180
228
|
/**
|
|
181
|
-
*
|
|
229
|
+
* Get two object's unqiue properties
|
|
230
|
+
* @param obj1 Object 1
|
|
231
|
+
* @param obj2 Object 2
|
|
232
|
+
* @param ignoreFields Ignored fields
|
|
233
|
+
* @returns Unique properties
|
|
234
|
+
*/
|
|
235
|
+
function objectKeys(obj1, obj2, ignoreFields = []) {
|
|
236
|
+
// All keys
|
|
237
|
+
const allKeys = [...Object.keys(obj1), ...Object.keys(obj2)].filter((item) => !ignoreFields.includes(item));
|
|
238
|
+
// Unique keys
|
|
239
|
+
return new Set(allKeys);
|
|
240
|
+
}
|
|
241
|
+
Utils.objectKeys = objectKeys;
|
|
242
|
+
/**
|
|
243
|
+
* Get the new object's updated fields contrast to the previous object
|
|
244
|
+
* @param objNew New object
|
|
245
|
+
* @param objPre Previous object
|
|
246
|
+
* @param ignoreFields Ignored fields
|
|
247
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
248
|
+
* @returns Updated fields
|
|
249
|
+
*/
|
|
250
|
+
function objectUpdated(objNew, objPrev, ignoreFields = [], strict = 1) {
|
|
251
|
+
// Fields
|
|
252
|
+
const fields = [];
|
|
253
|
+
// Unique keys
|
|
254
|
+
const keys = Utils.objectKeys(objNew, objPrev, ignoreFields);
|
|
255
|
+
for (const key of keys) {
|
|
256
|
+
// Values
|
|
257
|
+
const vNew = Reflect.get(objNew, key);
|
|
258
|
+
const vPrev = Reflect.get(objPrev, key);
|
|
259
|
+
if (!Utils.equals(vNew, vPrev, strict)) {
|
|
260
|
+
fields.push(key);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return fields;
|
|
264
|
+
}
|
|
265
|
+
Utils.objectUpdated = objectUpdated;
|
|
266
|
+
/**
|
|
267
|
+
* Parse string (JSON) to specific type, no type conversion
|
|
268
|
+
* For type conversion, please use DataTypes.convert
|
|
182
269
|
* @param input Input string
|
|
183
270
|
* @param defaultValue Default value
|
|
184
271
|
* @returns Parsed value
|
|
185
272
|
*/
|
|
186
273
|
function parseString(input, defaultValue) {
|
|
187
|
-
// Undefined case, return default value
|
|
188
|
-
if (input == null)
|
|
274
|
+
// Undefined and empty case, return default value
|
|
275
|
+
if (input == null || input === '')
|
|
189
276
|
return defaultValue;
|
|
190
277
|
// String
|
|
191
278
|
if (typeof defaultValue === 'string')
|
|
@@ -203,16 +290,11 @@ export var Utils;
|
|
|
203
290
|
// Return
|
|
204
291
|
return json;
|
|
205
292
|
}
|
|
206
|
-
catch
|
|
207
|
-
|
|
293
|
+
catch {
|
|
294
|
+
if (defaultValue == null)
|
|
295
|
+
return input;
|
|
208
296
|
return defaultValue;
|
|
209
297
|
}
|
|
210
|
-
/*
|
|
211
|
-
finally part will still return the boolean value
|
|
212
|
-
finally {
|
|
213
|
-
return defaultValue
|
|
214
|
-
}
|
|
215
|
-
*/
|
|
216
298
|
}
|
|
217
299
|
Utils.parseString = parseString;
|
|
218
300
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/shared",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.79",
|
|
4
4
|
"description": "TypeScript shared utilities and functions",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/mjs/index.js",
|
|
@@ -55,13 +55,13 @@
|
|
|
55
55
|
"dependencies": {},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/jest": "^27.0.3",
|
|
58
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
59
|
-
"@typescript-eslint/parser": "^5.
|
|
60
|
-
"eslint": "^8.
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^5.8.0",
|
|
59
|
+
"@typescript-eslint/parser": "^5.8.0",
|
|
60
|
+
"eslint": "^8.5.0",
|
|
61
61
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
62
62
|
"eslint-plugin-import": "^2.25.3",
|
|
63
|
-
"jest": "^27.
|
|
64
|
-
"ts-jest": "^27.
|
|
65
|
-
"typescript": "^4.5.
|
|
63
|
+
"jest": "^27.4.5",
|
|
64
|
+
"ts-jest": "^27.1.2",
|
|
65
|
+
"typescript": "^4.5.4"
|
|
66
66
|
}
|
|
67
67
|
}
|
package/src/StorageUtils.ts
CHANGED
|
@@ -49,7 +49,7 @@ export namespace StorageUtils {
|
|
|
49
49
|
* @param key Key name
|
|
50
50
|
* @param defaultValue Default value
|
|
51
51
|
*/
|
|
52
|
-
export function getLocalData<T>(key: string, defaultValue
|
|
52
|
+
export function getLocalData<T>(key: string, defaultValue?: T) {
|
|
53
53
|
// Get storage
|
|
54
54
|
const data = localStorage.getItem(key);
|
|
55
55
|
|
|
@@ -72,7 +72,7 @@ export namespace StorageUtils {
|
|
|
72
72
|
* Get session storage data
|
|
73
73
|
* @param key Key name
|
|
74
74
|
*/
|
|
75
|
-
export function getSessionData<T>(key: string, defaultValue
|
|
75
|
+
export function getSessionData<T>(key: string, defaultValue?: T) {
|
|
76
76
|
// Get storage
|
|
77
77
|
const data = sessionStorage.getItem(key);
|
|
78
78
|
|
package/src/Utils.ts
CHANGED
|
@@ -77,6 +77,46 @@ String.prototype.removeNonLetters = function (this: string) {
|
|
|
77
77
|
* Utilities
|
|
78
78
|
*/
|
|
79
79
|
export namespace Utils {
|
|
80
|
+
/**
|
|
81
|
+
* Base64 chars to number
|
|
82
|
+
* @param base64Chars Base64 chars
|
|
83
|
+
* @returns Number
|
|
84
|
+
*/
|
|
85
|
+
export function charsToNumber(base64Chars: string) {
|
|
86
|
+
const chars =
|
|
87
|
+
typeof Buffer === 'undefined'
|
|
88
|
+
? [...atob(base64Chars)].map((char) => char.charCodeAt(0))
|
|
89
|
+
: [...Buffer.from(base64Chars, 'base64')];
|
|
90
|
+
|
|
91
|
+
return chars.reduce((previousValue, currentValue, currentIndex) => {
|
|
92
|
+
return previousValue + currentValue * Math.pow(128, currentIndex);
|
|
93
|
+
}, 0);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Two values equal
|
|
98
|
+
* @param v1 Value 1
|
|
99
|
+
* @param v2 Value 2
|
|
100
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
101
|
+
*/
|
|
102
|
+
export function equals(v1: unknown, v2: unknown, strict = 1) {
|
|
103
|
+
// Null and undefined case
|
|
104
|
+
if (v1 == null || v2 == null) {
|
|
105
|
+
if (strict <= 1 && v1 == v2) return true;
|
|
106
|
+
return v1 === v2;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// For array and object
|
|
110
|
+
if (typeof v1 === 'object')
|
|
111
|
+
return JSON.stringify(v1) === JSON.stringify(v2);
|
|
112
|
+
|
|
113
|
+
// 1 and '1' case
|
|
114
|
+
if (strict === 0) return v1 == v2;
|
|
115
|
+
|
|
116
|
+
// Strict equal
|
|
117
|
+
return v1 === v2;
|
|
118
|
+
}
|
|
119
|
+
|
|
80
120
|
/**
|
|
81
121
|
* Format inital character to lower case or upper case
|
|
82
122
|
* @param input Input string
|
|
@@ -126,7 +166,7 @@ export namespace Utils {
|
|
|
126
166
|
|
|
127
167
|
if (initValue != null) {
|
|
128
168
|
const newValue = DataTypes.convert(value, initValue);
|
|
129
|
-
if (newValue
|
|
169
|
+
if (Utils.equals(newValue, initValue)) {
|
|
130
170
|
Reflect.deleteProperty(input, key);
|
|
131
171
|
return;
|
|
132
172
|
}
|
|
@@ -218,6 +258,27 @@ export namespace Utils {
|
|
|
218
258
|
});
|
|
219
259
|
}
|
|
220
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Number to base64 chars
|
|
263
|
+
* @param num Input number
|
|
264
|
+
* @returns Result
|
|
265
|
+
*/
|
|
266
|
+
export function numberToChars(num: number) {
|
|
267
|
+
const codes = [];
|
|
268
|
+
while (num > 0) {
|
|
269
|
+
const code = num % 128;
|
|
270
|
+
codes.push(code);
|
|
271
|
+
num = (num - code) / 128;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (typeof Buffer === 'undefined') {
|
|
275
|
+
return btoa(String.fromCharCode(...codes));
|
|
276
|
+
} else {
|
|
277
|
+
const buffer = Buffer.from(codes);
|
|
278
|
+
return buffer.toString('base64');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
221
282
|
/**
|
|
222
283
|
* Test two objects are equal or not
|
|
223
284
|
* @param obj1 Object 1
|
|
@@ -232,42 +293,87 @@ export namespace Utils {
|
|
|
232
293
|
ignoreFields: string[] = [],
|
|
233
294
|
strict = 1
|
|
234
295
|
) {
|
|
235
|
-
//
|
|
236
|
-
const keys =
|
|
237
|
-
...Object.keys(obj1).filter((item) => !ignoreFields.includes(item)),
|
|
238
|
-
...Object.keys(obj2).filter((item) => !ignoreFields.includes(item))
|
|
239
|
-
]);
|
|
296
|
+
// Unique keys
|
|
297
|
+
const keys = Utils.objectKeys(obj1, obj2, ignoreFields);
|
|
240
298
|
|
|
241
299
|
for (const key of keys) {
|
|
242
300
|
// Values
|
|
243
301
|
const v1 = Reflect.get(obj1, key);
|
|
244
302
|
const v2 = Reflect.get(obj2, key);
|
|
245
303
|
|
|
246
|
-
|
|
247
|
-
|
|
304
|
+
if (!Utils.equals(v1, v2, strict)) return false;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Get two object's unqiue properties
|
|
312
|
+
* @param obj1 Object 1
|
|
313
|
+
* @param obj2 Object 2
|
|
314
|
+
* @param ignoreFields Ignored fields
|
|
315
|
+
* @returns Unique properties
|
|
316
|
+
*/
|
|
317
|
+
export function objectKeys(
|
|
318
|
+
obj1: {},
|
|
319
|
+
obj2: {},
|
|
320
|
+
ignoreFields: string[] = []
|
|
321
|
+
) {
|
|
322
|
+
// All keys
|
|
323
|
+
const allKeys = [...Object.keys(obj1), ...Object.keys(obj2)].filter(
|
|
324
|
+
(item) => !ignoreFields.includes(item)
|
|
325
|
+
);
|
|
248
326
|
|
|
249
|
-
|
|
250
|
-
|
|
327
|
+
// Unique keys
|
|
328
|
+
return new Set(allKeys);
|
|
329
|
+
}
|
|
251
330
|
|
|
252
|
-
|
|
253
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Get the new object's updated fields contrast to the previous object
|
|
333
|
+
* @param objNew New object
|
|
334
|
+
* @param objPre Previous object
|
|
335
|
+
* @param ignoreFields Ignored fields
|
|
336
|
+
* @param strict Strict level, 0 with ==, 1 === but null equal undefined, 2 ===
|
|
337
|
+
* @returns Updated fields
|
|
338
|
+
*/
|
|
339
|
+
export function objectUpdated(
|
|
340
|
+
objNew: {},
|
|
341
|
+
objPrev: {},
|
|
342
|
+
ignoreFields: string[] = [],
|
|
343
|
+
strict = 1
|
|
344
|
+
) {
|
|
345
|
+
// Fields
|
|
346
|
+
const fields: string[] = [];
|
|
347
|
+
|
|
348
|
+
// Unique keys
|
|
349
|
+
const keys = Utils.objectKeys(objNew, objPrev, ignoreFields);
|
|
350
|
+
|
|
351
|
+
for (const key of keys) {
|
|
352
|
+
// Values
|
|
353
|
+
const vNew = Reflect.get(objNew, key);
|
|
354
|
+
const vPrev = Reflect.get(objPrev, key);
|
|
355
|
+
|
|
356
|
+
if (!Utils.equals(vNew, vPrev, strict)) {
|
|
357
|
+
fields.push(key);
|
|
358
|
+
}
|
|
254
359
|
}
|
|
255
360
|
|
|
256
|
-
return
|
|
361
|
+
return fields;
|
|
257
362
|
}
|
|
258
363
|
|
|
259
364
|
/**
|
|
260
|
-
* Parse string (JSON) to specific type
|
|
365
|
+
* Parse string (JSON) to specific type, no type conversion
|
|
366
|
+
* For type conversion, please use DataTypes.convert
|
|
261
367
|
* @param input Input string
|
|
262
368
|
* @param defaultValue Default value
|
|
263
369
|
* @returns Parsed value
|
|
264
370
|
*/
|
|
265
371
|
export function parseString<T>(
|
|
266
372
|
input: string | undefined | null,
|
|
267
|
-
defaultValue
|
|
268
|
-
): T {
|
|
269
|
-
// Undefined case, return default value
|
|
270
|
-
if (input == null) return defaultValue;
|
|
373
|
+
defaultValue?: T
|
|
374
|
+
): T | undefined {
|
|
375
|
+
// Undefined and empty case, return default value
|
|
376
|
+
if (input == null || input === '') return defaultValue;
|
|
271
377
|
|
|
272
378
|
// String
|
|
273
379
|
if (typeof defaultValue === 'string') return <any>input;
|
|
@@ -285,16 +391,10 @@ export namespace Utils {
|
|
|
285
391
|
|
|
286
392
|
// Return
|
|
287
393
|
return <T>json;
|
|
288
|
-
} catch
|
|
289
|
-
|
|
394
|
+
} catch {
|
|
395
|
+
if (defaultValue == null) return <any>input;
|
|
290
396
|
return defaultValue;
|
|
291
397
|
}
|
|
292
|
-
/*
|
|
293
|
-
finally part will still return the boolean value
|
|
294
|
-
finally {
|
|
295
|
-
return defaultValue
|
|
296
|
-
}
|
|
297
|
-
*/
|
|
298
398
|
}
|
|
299
399
|
|
|
300
400
|
/**
|