@etsoo/shared 1.0.74 → 1.0.78

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 CHANGED
@@ -122,13 +122,17 @@ Storage related utilities
122
122
  |setLocalData|Set local storage data|
123
123
  |setSessionData|Set session storage data|
124
124
  |getLocalData|Get local storage data|
125
+ |getLocalObject|Get local storage object data|
125
126
  |getSessionData|Get session storage data|
127
+ |getSessionObject|Get session storage object data|
126
128
 
127
129
  ## Utils
128
130
  String and other related utilities
129
131
 
130
132
  |Name|Description|
131
133
  |---:|---|
134
+ |charsToNumber|Base64 chars to number|
135
+ |equals|Two values equal|
132
136
  |formatInitial|Format inital character to lower case or upper case|
133
137
  |formatString|Format string with parameters|
134
138
  |getDataChanges|Get data changed fields with input data updated|
@@ -137,7 +141,10 @@ String and other related utilities
137
141
  |mergeFormData|Merge form data to primary one|
138
142
  |mergeClasses|Merge class names|
139
143
  |newGUID|Create a GUID|
144
+ |numberToChars|Number to base64 chars|
140
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|
141
148
  |parseString|Parse string (JSON) to specific type|
142
149
  |setLabels|Set source with new labels|
143
150
  |snakeNameToWord|Snake name to works, 'snake_name' to 'Snake Name'|
@@ -12,3 +12,17 @@ test('Tests for all', () => {
12
12
  expect(StorageUtils.getSessionData('number', 0)).toBe(3.14);
13
13
  expect(StorageUtils.getSessionData('test', {})).toHaveProperty('id', 123);
14
14
  });
15
+
16
+ test('Tests for getLocalObject', () => {
17
+ StorageUtils.setLocalData('test', { id: 123, name: 'test' });
18
+ const data = StorageUtils.getLocalObject<{ id: number }>('test');
19
+ expect(data?.id).toBe(123);
20
+ expect(data).toHaveProperty('name', 'test');
21
+ });
22
+
23
+ test('Tests for getSessionObject', () => {
24
+ StorageUtils.setSessionData('test', { id: 123, name: 'test' });
25
+ const data = StorageUtils.getSessionObject<{ id: number }>('test');
26
+ expect(data?.id).toBe(123);
27
+ expect(data).toHaveProperty('name', 'test');
28
+ });
@@ -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,14 +84,21 @@ 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
103
  expect(Utils.parseString('test', '')).toBe('test');
88
104
  expect(Utils.parseString('true', false)).toBe(true);
@@ -21,9 +21,19 @@ export declare namespace StorageUtils {
21
21
  * @param defaultValue Default value
22
22
  */
23
23
  function getLocalData<T>(key: string, defaultValue: T): T;
24
+ /**
25
+ * Get local storage object data
26
+ * @param key Key name
27
+ */
28
+ function getLocalObject<T extends {}>(key: string): T | undefined;
24
29
  /**
25
30
  * Get session storage data
26
31
  * @param key Key name
27
32
  */
28
33
  function getSessionData<T>(key: string, defaultValue: T): T;
34
+ /**
35
+ * Get session storage object data
36
+ * @param key Key name
37
+ */
38
+ function getSessionObject<T extends {}>(key: string): T | undefined;
29
39
  }
@@ -51,6 +51,18 @@ var StorageUtils;
51
51
  return Utils_1.Utils.parseString(data, defaultValue);
52
52
  }
53
53
  StorageUtils.getLocalData = getLocalData;
54
+ /**
55
+ * Get local storage object data
56
+ * @param key Key name
57
+ */
58
+ function getLocalObject(key) {
59
+ // Get storage
60
+ const data = localStorage.getItem(key);
61
+ if (data == null)
62
+ return undefined;
63
+ return JSON.parse(data);
64
+ }
65
+ StorageUtils.getLocalObject = getLocalObject;
54
66
  /**
55
67
  * Get session storage data
56
68
  * @param key Key name
@@ -62,4 +74,16 @@ var StorageUtils;
62
74
  return Utils_1.Utils.parseString(data, defaultValue);
63
75
  }
64
76
  StorageUtils.getSessionData = getSessionData;
77
+ /**
78
+ * Get session storage object data
79
+ * @param key Key name
80
+ */
81
+ function getSessionObject(key) {
82
+ // Get storage
83
+ const data = sessionStorage.getItem(key);
84
+ if (data == null)
85
+ return undefined;
86
+ return JSON.parse(data);
87
+ }
88
+ StorageUtils.getSessionObject = getSessionObject;
65
89
  })(StorageUtils = exports.StorageUtils || (exports.StorageUtils = {}));
@@ -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
@@ -98,6 +117,23 @@ export declare namespace Utils {
98
117
  * @returns Result
99
118
  */
100
119
  function objectEqual(obj1: {}, obj2: {}, ignoreFields?: string[], strict?: number): boolean;
120
+ /**
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[];
101
137
  /**
102
138
  * Parse string (JSON) to specific type
103
139
  * @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 === initValue) {
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,28 +216,56 @@ var Utils;
158
216
  * @returns Result
159
217
  */
160
218
  function objectEqual(obj1, obj2, ignoreFields = [], strict = 1) {
161
- // Keys
162
- const keys = new Set([
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
- // Null and undefined case
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;
231
+ /**
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;
183
269
  /**
184
270
  * Parse string (JSON) to specific type
185
271
  * @param input Input string
@@ -21,9 +21,19 @@ export declare namespace StorageUtils {
21
21
  * @param defaultValue Default value
22
22
  */
23
23
  function getLocalData<T>(key: string, defaultValue: T): T;
24
+ /**
25
+ * Get local storage object data
26
+ * @param key Key name
27
+ */
28
+ function getLocalObject<T extends {}>(key: string): T | undefined;
24
29
  /**
25
30
  * Get session storage data
26
31
  * @param key Key name
27
32
  */
28
33
  function getSessionData<T>(key: string, defaultValue: T): T;
34
+ /**
35
+ * Get session storage object data
36
+ * @param key Key name
37
+ */
38
+ function getSessionObject<T extends {}>(key: string): T | undefined;
29
39
  }
@@ -48,6 +48,18 @@ export var StorageUtils;
48
48
  return Utils.parseString(data, defaultValue);
49
49
  }
50
50
  StorageUtils.getLocalData = getLocalData;
51
+ /**
52
+ * Get local storage object data
53
+ * @param key Key name
54
+ */
55
+ function getLocalObject(key) {
56
+ // Get storage
57
+ const data = localStorage.getItem(key);
58
+ if (data == null)
59
+ return undefined;
60
+ return JSON.parse(data);
61
+ }
62
+ StorageUtils.getLocalObject = getLocalObject;
51
63
  /**
52
64
  * Get session storage data
53
65
  * @param key Key name
@@ -59,4 +71,16 @@ export var StorageUtils;
59
71
  return Utils.parseString(data, defaultValue);
60
72
  }
61
73
  StorageUtils.getSessionData = getSessionData;
74
+ /**
75
+ * Get session storage object data
76
+ * @param key Key name
77
+ */
78
+ function getSessionObject(key) {
79
+ // Get storage
80
+ const data = sessionStorage.getItem(key);
81
+ if (data == null)
82
+ return undefined;
83
+ return JSON.parse(data);
84
+ }
85
+ StorageUtils.getSessionObject = getSessionObject;
62
86
  })(StorageUtils || (StorageUtils = {}));
@@ -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
@@ -98,6 +117,23 @@ export declare namespace Utils {
98
117
  * @returns Result
99
118
  */
100
119
  function objectEqual(obj1: {}, obj2: {}, ignoreFields?: string[], strict?: number): boolean;
120
+ /**
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[];
101
137
  /**
102
138
  * Parse string (JSON) to specific type
103
139
  * @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 === initValue) {
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,28 +213,56 @@ export var Utils;
155
213
  * @returns Result
156
214
  */
157
215
  function objectEqual(obj1, obj2, ignoreFields = [], strict = 1) {
158
- // Keys
159
- const keys = new Set([
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
- // Null and undefined case
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;
228
+ /**
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;
180
266
  /**
181
267
  * Parse string (JSON) to specific type
182
268
  * @param input Input string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/shared",
3
- "version": "1.0.74",
3
+ "version": "1.0.78",
4
4
  "description": "TypeScript shared utilities and functions",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -54,7 +54,7 @@
54
54
  "homepage": "https://github.com/ETSOO/Shared#readme",
55
55
  "dependencies": {},
56
56
  "devDependencies": {
57
- "@types/jest": "^27.0.2",
57
+ "@types/jest": "^27.0.3",
58
58
  "@typescript-eslint/eslint-plugin": "^5.4.0",
59
59
  "@typescript-eslint/parser": "^5.4.0",
60
60
  "eslint": "^8.2.0",
@@ -57,6 +57,17 @@ export namespace StorageUtils {
57
57
  return Utils.parseString(data, defaultValue);
58
58
  }
59
59
 
60
+ /**
61
+ * Get local storage object data
62
+ * @param key Key name
63
+ */
64
+ export function getLocalObject<T extends {}>(key: string) {
65
+ // Get storage
66
+ const data = localStorage.getItem(key);
67
+ if (data == null) return undefined;
68
+ return <T>JSON.parse(data);
69
+ }
70
+
60
71
  /**
61
72
  * Get session storage data
62
73
  * @param key Key name
@@ -68,4 +79,15 @@ export namespace StorageUtils {
68
79
  // Return
69
80
  return Utils.parseString(data, defaultValue);
70
81
  }
82
+
83
+ /**
84
+ * Get session storage object data
85
+ * @param key Key name
86
+ */
87
+ export function getSessionObject<T extends {}>(key: string) {
88
+ // Get storage
89
+ const data = sessionStorage.getItem(key);
90
+ if (data == null) return undefined;
91
+ return <T>JSON.parse(data);
92
+ }
71
93
  }
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 === initValue) {
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,28 +293,72 @@ export namespace Utils {
232
293
  ignoreFields: string[] = [],
233
294
  strict = 1
234
295
  ) {
235
- // Keys
236
- const keys = new Set([
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
- // Null and undefined case
247
- if (v1 == null && v2 == null && strict <= 1) continue;
304
+ if (!Utils.equals(v1, v2, strict)) return false;
305
+ }
248
306
 
249
- // 1 and '1' case
250
- if (strict === 0 && v1 == v2) continue;
307
+ return true;
308
+ }
251
309
 
252
- // Strict equal
253
- if (v1 !== v2) return false;
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
+ );
326
+
327
+ // Unique keys
328
+ return new Set(allKeys);
329
+ }
330
+
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 true;
361
+ return fields;
257
362
  }
258
363
 
259
364
  /**