some-common-functions-js 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -2
- package/README.md +286 -26
- package/index.d.ts +281 -0
- package/index.js +635 -658
- package/index.js.map +1 -0
- package/index.ts +733 -0
- package/package.json +9 -4
- package/tsconfig.json +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -70,5 +70,12 @@ Changed an additional recursive function to an iterative function.
|
|
|
70
70
|
- During object assignment, deepClone() function uses object spread to remove references to the original object.
|
|
71
71
|
- get() function replaces falsy-value evaluation (!obj) with 'in' operator for field existence checks. Because the falsy-value evaluation also evaluates to true with existent fields with values that are empty strings or null, which is not desirable.
|
|
72
72
|
|
|
73
|
-
## Version 1.2.0 - 2026/01/10 - ITA
|
|
74
|
-
get() and unset() functions: for field existence checks, switched from the use of 'in' operator to checking whether the field value is undefined. This prevents from crashes when a non-existent field value is encountered.
|
|
73
|
+
## Version 1.2.0 - 2026/01/10 to 2026/01/10 - ITA
|
|
74
|
+
get() and unset() functions: for field existence checks, switched from the use of 'in' operator to checking whether the field value is undefined. This prevents from crashes when a non-existent field value is encountered.
|
|
75
|
+
|
|
76
|
+
## Version 1.2.1 - 2026/01/10 to 2026/01/10 - ITA
|
|
77
|
+
Added more robustness in dealing with non-existent fields in the get() and unset() functions.
|
|
78
|
+
|
|
79
|
+
## Version 2.0.0 - 2026/05/07 to 2026/05/08 - ITA
|
|
80
|
+
- Migrated to Typescript.
|
|
81
|
+
- Added more robustness in verifying whether variables are plain Typescript/Javascript objects or not.
|
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
# JavaScript Object Utilities, Field Validation Functions, Array Binary Search, and Date timestamp Functions.
|
|
1
|
+
# Typescript/JavaScript Object Utilities, Field Validation Functions, Array Binary Search, and Date timestamp Functions.
|
|
2
2
|
|
|
3
|
-
Common functions used for working with JavaScript objects and validating field values.
|
|
3
|
+
Common functions used for working with Typescript/JavaScript objects and validating field values.
|
|
4
|
+
Full support for Typescript use.
|
|
4
5
|
|
|
5
6
|
---
|
|
6
7
|
## Installation
|
|
@@ -8,17 +9,100 @@ Common functions used for working with JavaScript objects and validating field v
|
|
|
8
9
|
npm install some-common-functions-js
|
|
9
10
|
```
|
|
10
11
|
|
|
11
|
-
## 1. JavaScript Object Utilities
|
|
12
|
+
## 1. Typescript/JavaScript Object Utilities
|
|
12
13
|
|
|
13
14
|
### `deepClone(anObject)`
|
|
14
|
-
Returns a deep clone of a plain Javascript object. The clone, while it has field equal to that of the original object, is separate from the original object.
|
|
15
|
+
Returns a deep clone of a plain Typescript/Javascript object. The clone, while it has field equal to that of the original object, is separate from the original object.
|
|
16
|
+
NB: Cloneable fields include primitive types, strings and dates. For fields other types, e.g arrays and class instances, they must be cloned individually using other means.
|
|
17
|
+
|
|
18
|
+
***Example in Javascript***
|
|
19
|
+
```
|
|
20
|
+
import { deepClone } from "some-common-functions-js";
|
|
21
|
+
|
|
22
|
+
const vehicle = {
|
|
23
|
+
make: "Cherry",
|
|
24
|
+
model: "SX1",
|
|
25
|
+
year: 2024,
|
|
26
|
+
type: "Coupe"
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const vehicleClone = deepClone(vehicle); // Wholly cloned.
|
|
30
|
+
|
|
31
|
+
const student = {
|
|
32
|
+
firstName: "Zack", // firstName - cloneable
|
|
33
|
+
lastName: "Zama", // lastName - cloneable
|
|
34
|
+
dateOfBirth: new Date("1990-01-01"), // dateOfBirth - cloneable
|
|
35
|
+
address: {
|
|
36
|
+
streetNum: "243", // address.streetNum - cloneable
|
|
37
|
+
streetName: "Milkwood Str.", // address.streetName - cloneable
|
|
38
|
+
subPlace: "Ext.1", // address.subPlace - cloneable
|
|
39
|
+
mainPlace: "Lakeside", // address.mainPlace - cloneable
|
|
40
|
+
municipality: "City of Johannesburg Metro", // address.municipality - cloneable
|
|
41
|
+
province: "Gauteng" // address.province - cloneable
|
|
42
|
+
},
|
|
43
|
+
subjects: ["CS-1", "CS-2", "MA-1"] // Not cloneable
|
|
44
|
+
};
|
|
45
|
+
const studentClone = deepClone(student); // All fields except "subjects" not cloned, because it is an array and not primitive, string or date type.
|
|
46
|
+
```
|
|
15
47
|
|
|
16
|
-
|
|
17
|
-
|
|
48
|
+
***Example in Typescript***
|
|
49
|
+
```
|
|
50
|
+
import { deepClone } from "some-common-functions-js";
|
|
51
|
+
|
|
52
|
+
interface Vehicle {
|
|
53
|
+
make: string;
|
|
54
|
+
model: string;
|
|
55
|
+
year: number;
|
|
56
|
+
type: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const vehicle: Vehicle = {
|
|
60
|
+
make: "Cherry",
|
|
61
|
+
model: "SX1",
|
|
62
|
+
year: 2024,
|
|
63
|
+
type: "Coupe"
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const vehicleClone = deepClone(vehicle); // Wholly cloned.
|
|
67
|
+
|
|
68
|
+
interface Student {
|
|
69
|
+
firstName: string;
|
|
70
|
+
lastName: string;
|
|
71
|
+
dateOfBirth: Date;
|
|
72
|
+
address: {
|
|
73
|
+
streetNum: string;
|
|
74
|
+
streetName: string;
|
|
75
|
+
subPlace: string;
|
|
76
|
+
mainPlace: string;
|
|
77
|
+
municipality: string;
|
|
78
|
+
province: string;
|
|
79
|
+
},
|
|
80
|
+
subjects: string[];
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const student: Student = {
|
|
84
|
+
firstName: "Zack", // firstName - cloneable
|
|
85
|
+
lastName: "Zama", // lastName - cloneable
|
|
86
|
+
dateOfBirth: new Date("1990-01-01"), // dateOfBirth - cloneable
|
|
87
|
+
address: {
|
|
88
|
+
streetNum: "243", // address.streetNum - cloneable
|
|
89
|
+
streetName: "Milkwood Str.", // address.streetName - cloneable
|
|
90
|
+
subPlace: "Ext.1", // address.subPlace - cloneable
|
|
91
|
+
mainPlace: "Lakeside", // address.mainPlace - cloneable
|
|
92
|
+
municipality: "City of Johannesburg Metro", // address.municipality - cloneable
|
|
93
|
+
province: "Gauteng" // address.province - cloneable
|
|
94
|
+
},
|
|
95
|
+
subjects: ["CS-1", "CS-2", "MA-1"] // Not cloneable
|
|
96
|
+
};
|
|
97
|
+
const studentClone = deepClone(student);
|
|
98
|
+
```
|
|
18
99
|
|
|
19
|
-
|
|
100
|
+
### `getPaths(anObject)`
|
|
101
|
+
Returns a string array of path/field names inside a Typescript/JavaScript object.
|
|
102
|
+
|
|
103
|
+
***Example in Javascript***
|
|
20
104
|
```
|
|
21
|
-
|
|
105
|
+
import { getPaths } from "some-common-functions-js";
|
|
22
106
|
let client = {
|
|
23
107
|
name: "Jack",
|
|
24
108
|
surname: "Stober",
|
|
@@ -37,14 +121,54 @@ let client = {
|
|
|
37
121
|
let paths = getPaths(client);
|
|
38
122
|
// ["name", "surname", "address.streetNum", "address.streetName", "address.suburb",
|
|
39
123
|
// "address.town", "address.country.name", "address.country.code"]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
***Example in Typescript***
|
|
40
127
|
```
|
|
128
|
+
import { getPaths } from "some-common-functions-js";
|
|
129
|
+
|
|
130
|
+
interface Client {
|
|
131
|
+
name: string;
|
|
132
|
+
surname: string;
|
|
133
|
+
address: {
|
|
134
|
+
streetNum: string;
|
|
135
|
+
streetName: string;
|
|
136
|
+
suburb: string;
|
|
137
|
+
town: string;
|
|
138
|
+
country {
|
|
139
|
+
name: string;
|
|
140
|
+
code: string;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
let client: Client = {
|
|
145
|
+
name: "Jack",
|
|
146
|
+
surname: "Stober",
|
|
147
|
+
address: {
|
|
148
|
+
streetNum: "57",
|
|
149
|
+
streetName: "Tiger Drive",
|
|
150
|
+
suburb: "Lakeside Ext.1",
|
|
151
|
+
town: "Lakeside",
|
|
152
|
+
country {
|
|
153
|
+
name: "South Africa",
|
|
154
|
+
code: "za"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
let paths = getPaths(client);
|
|
160
|
+
// ["name", "surname", "address.streetNum", "address.streetName", "address.suburb",
|
|
161
|
+
// "address.town", "address.country.name", "address.country.code"]
|
|
162
|
+
```
|
|
163
|
+
|
|
41
164
|
|
|
42
165
|
### `getSortedObject(anObject)`
|
|
43
166
|
Returns an object with sorted fields, ordered by field name ascending.
|
|
44
167
|
|
|
45
|
-
***Examples***
|
|
168
|
+
***Examples in Javascript***
|
|
46
169
|
```
|
|
47
|
-
|
|
170
|
+
import { get } from "some-common-functions-js";
|
|
171
|
+
|
|
48
172
|
const client = {
|
|
49
173
|
firstName: "Isaiah",
|
|
50
174
|
lastName: "Tshabalala",
|
|
@@ -80,14 +204,67 @@ const sortedObject = getSortedObject(client);
|
|
|
80
204
|
}
|
|
81
205
|
*/
|
|
82
206
|
```
|
|
207
|
+
|
|
208
|
+
***Example in Typescript***
|
|
209
|
+
```
|
|
210
|
+
interface Client {
|
|
211
|
+
name: string;
|
|
212
|
+
surname: string;
|
|
213
|
+
address: {
|
|
214
|
+
streetNum: string;
|
|
215
|
+
streetName: string;
|
|
216
|
+
suburb: string;
|
|
217
|
+
town: string;
|
|
218
|
+
country {
|
|
219
|
+
name: string;
|
|
220
|
+
code: string;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const client: Client = {
|
|
226
|
+
firstName: "Isaiah",
|
|
227
|
+
lastName: "Tshabalala",
|
|
228
|
+
address: {
|
|
229
|
+
houseNum: "5520",
|
|
230
|
+
streetName: "Main Road",
|
|
231
|
+
mainPlace: "Evaton",
|
|
232
|
+
subPlace: "Evaton Small Farms",
|
|
233
|
+
city: "Vereeniging",
|
|
234
|
+
country: {
|
|
235
|
+
name: "South Africa",
|
|
236
|
+
code: "ZA"
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const sortedObject = getSortedObject(client);
|
|
242
|
+
/*
|
|
243
|
+
{
|
|
244
|
+
address: {
|
|
245
|
+
city: 'Vereeniging',
|
|
246
|
+
country: {
|
|
247
|
+
code: 'ZA',
|
|
248
|
+
name: 'South Africa'
|
|
249
|
+
},
|
|
250
|
+
houseNum: '5520',
|
|
251
|
+
mainPlace: 'Evaton',
|
|
252
|
+
streetName: 'Main Road',
|
|
253
|
+
subPlace: 'Evaton Small Farms'
|
|
254
|
+
},
|
|
255
|
+
firstName: 'Isaiah',
|
|
256
|
+
lastName: 'Tshabalala'
|
|
257
|
+
}
|
|
258
|
+
*/
|
|
259
|
+
```
|
|
83
260
|
|
|
84
261
|
### `get(anObject, path)`
|
|
85
262
|
Returns the value of an object at the specified path.
|
|
86
263
|
Can take the place of lodash get() function.
|
|
87
264
|
|
|
88
|
-
***Examples***
|
|
265
|
+
***Examples in Javascript***
|
|
89
266
|
```
|
|
90
|
-
|
|
267
|
+
import { get } from "some-common-functions-js";
|
|
91
268
|
const client = {
|
|
92
269
|
firstName: "Isaiah",
|
|
93
270
|
lastName: "Tshabalala",
|
|
@@ -111,13 +288,56 @@ result = get(client, "address.country.code");
|
|
|
111
288
|
// "ZA"
|
|
112
289
|
```
|
|
113
290
|
|
|
291
|
+
|
|
292
|
+
***Examples in Typescript***
|
|
293
|
+
```
|
|
294
|
+
import { get } from "some-common-functions-js";
|
|
295
|
+
|
|
296
|
+
interface Client {
|
|
297
|
+
name: string;
|
|
298
|
+
surname: string;
|
|
299
|
+
address: {
|
|
300
|
+
streetNum: string;
|
|
301
|
+
streetName: string;
|
|
302
|
+
suburb: string;
|
|
303
|
+
town: string;
|
|
304
|
+
country {
|
|
305
|
+
name: string;
|
|
306
|
+
code: string;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const client: Client = {
|
|
312
|
+
firstName: "Isaiah",
|
|
313
|
+
lastName: "Tshabalala",
|
|
314
|
+
address: {
|
|
315
|
+
houseNum: "5520",
|
|
316
|
+
streetName: "Main Road",
|
|
317
|
+
mainPlace: "Evaton",
|
|
318
|
+
subPlace: "Evaton Small Farms",
|
|
319
|
+
city: "Vereeniging",
|
|
320
|
+
country: {
|
|
321
|
+
name: "South Africa",
|
|
322
|
+
code: "ZA"
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
let result = get(client, "address.country"); // The result is type 'any', so must be cast to the type of that field.
|
|
328
|
+
// { name: "South Africa", code: "ZA" }
|
|
329
|
+
|
|
330
|
+
result = get(client, "address.country.code");
|
|
331
|
+
// "ZA"
|
|
332
|
+
```
|
|
333
|
+
|
|
114
334
|
### `set(anObject, path)`
|
|
115
335
|
Sets the value of an object at the specified path.
|
|
116
336
|
Can take the place of lodash set() function.
|
|
117
337
|
|
|
118
|
-
***Examples***
|
|
338
|
+
***Examples in Javascript***
|
|
119
339
|
```
|
|
120
|
-
const { set }
|
|
340
|
+
const { set } from "some-common-functions-js";
|
|
121
341
|
|
|
122
342
|
let emptyObj = {};
|
|
123
343
|
set(emptyObj, "address.country.name", "South Africa");
|
|
@@ -133,14 +353,54 @@ console.log(emptyObj);
|
|
|
133
353
|
}
|
|
134
354
|
*/
|
|
135
355
|
```
|
|
356
|
+
|
|
357
|
+
***Examples in Typescript***
|
|
358
|
+
```
|
|
359
|
+
import { set } from "some-common-functions-js";
|
|
360
|
+
|
|
361
|
+
interface Client {
|
|
362
|
+
name: string;
|
|
363
|
+
surname: string;
|
|
364
|
+
address: {
|
|
365
|
+
streetNum: string;
|
|
366
|
+
streetName: string;
|
|
367
|
+
suburb: string;
|
|
368
|
+
town: string;
|
|
369
|
+
country {
|
|
370
|
+
name: string;
|
|
371
|
+
code: string;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const client: Client = {
|
|
377
|
+
firstName: "Isaiah",
|
|
378
|
+
lastName: "Tshabalala",
|
|
379
|
+
address: {
|
|
380
|
+
houseNum: "5520",
|
|
381
|
+
streetName: "Main Road",
|
|
382
|
+
mainPlace: "Evaton",
|
|
383
|
+
subPlace: "Evaton Small Farms",
|
|
384
|
+
city: "Vereeniging",
|
|
385
|
+
country: {
|
|
386
|
+
name: "South Africa",
|
|
387
|
+
code: "ZA"
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
set(client, "address.country.code", "zaf");
|
|
393
|
+
// client.address.country.code assigned "zaf"
|
|
394
|
+
```
|
|
395
|
+
|
|
136
396
|
|
|
137
397
|
### `unset(anObject, path)`
|
|
138
|
-
Remove a field from an object at the specified path.
|
|
398
|
+
Remove a field from an object at the specified path. Calls for caution when dealing with objects in Typescript: not to remove non-optional fields.
|
|
139
399
|
Can take the place of lodash unset() function.
|
|
140
400
|
|
|
141
401
|
***Example***
|
|
142
402
|
```
|
|
143
|
-
|
|
403
|
+
import {unset} from "some-common-functions-js";
|
|
144
404
|
let testObj = {
|
|
145
405
|
firstName: 'John',
|
|
146
406
|
lastName: 'Rambo',
|
|
@@ -163,7 +423,7 @@ Returns `true` if the object contains **only** some or all of the specified fiel
|
|
|
163
423
|
|
|
164
424
|
***Examples***
|
|
165
425
|
```
|
|
166
|
-
|
|
426
|
+
import { hasOnly } from "some-common-functions-js";
|
|
167
427
|
|
|
168
428
|
let car = {
|
|
169
429
|
make: "Ford",
|
|
@@ -189,7 +449,7 @@ The object may contain additional fields.
|
|
|
189
449
|
|
|
190
450
|
***Examples***
|
|
191
451
|
```
|
|
192
|
-
|
|
452
|
+
import { hasAll } from "some-common-functions-js";
|
|
193
453
|
let car = {
|
|
194
454
|
make: "Ford",
|
|
195
455
|
model: "Ranger",
|
|
@@ -209,7 +469,7 @@ Return `true` if an object contains only all the specified fields, nothing more,
|
|
|
209
469
|
|
|
210
470
|
***Examples***
|
|
211
471
|
```
|
|
212
|
-
|
|
472
|
+
import { hasOnlyAll } from "some-common-functions-js";
|
|
213
473
|
let car = {
|
|
214
474
|
make: "Ford",
|
|
215
475
|
model: "Ranger",
|
|
@@ -260,7 +520,7 @@ Compares two values of the same primitive type, according to the sort direction.
|
|
|
260
520
|
|
|
261
521
|
***Examples***
|
|
262
522
|
```
|
|
263
|
-
|
|
523
|
+
import { compare } from "some-common-functions-js";
|
|
264
524
|
|
|
265
525
|
let x = "Jiāng Fāng";
|
|
266
526
|
let y = "Isaiah Tshabalala";
|
|
@@ -282,7 +542,7 @@ Binary Searches a sorted primitive type array for a value and returns the index.
|
|
|
282
542
|
|
|
283
543
|
***Example***
|
|
284
544
|
```
|
|
285
|
-
|
|
545
|
+
import { binarySearch, compare } from "some-common-functions-js";
|
|
286
546
|
let myArray = [100, 101, 102, 103, 104, 105, 106, 107];
|
|
287
547
|
let index = binarySearch(myArray, 103); // 3
|
|
288
548
|
let result = compare(103, myArray[index]); // 0, 103 === myArray[index].
|
|
@@ -298,7 +558,7 @@ Compare 2 objects according to the comparison fields specified in the comparison
|
|
|
298
558
|
|
|
299
559
|
***Example***
|
|
300
560
|
```
|
|
301
|
-
|
|
561
|
+
import { objCompare } from "some-common-functions-js";
|
|
302
562
|
let anObject = {
|
|
303
563
|
firstName: "Isaiah",
|
|
304
564
|
lastName: "Tshabalala",
|
|
@@ -459,7 +719,7 @@ Binary Search the sorted (ascending or descending order) array of objects for a
|
|
|
459
719
|
|
|
460
720
|
***Example***
|
|
461
721
|
```
|
|
462
|
-
|
|
722
|
+
import { objCompare, binarySearchObj } from "some-common-functions-js";
|
|
463
723
|
let teamsArray = [
|
|
464
724
|
{ score: 90, numGames: 10 },
|
|
465
725
|
{ score: 90, numGames: 12 },
|
|
@@ -483,7 +743,7 @@ Create an array of objects with duplicates eliminated. Taking only the first or
|
|
|
483
743
|
|
|
484
744
|
***Example***
|
|
485
745
|
```
|
|
486
|
-
|
|
746
|
+
import { getObjArrayWithNoDuplicates } from "some-common-functions-js";
|
|
487
747
|
let teamsArray = [
|
|
488
748
|
{ score: 90, numGames: 10, name: "John" },
|
|
489
749
|
{ score: 90, numGames: 10, name: "Jane" },
|
|
@@ -524,14 +784,14 @@ console.log(noDuplicatesArray);
|
|
|
524
784
|
```
|
|
525
785
|
|
|
526
786
|
### `getNextDifferent(objArray, targetObj, startFrom, ...comparisonFields)`
|
|
527
|
-
Get the index in the array of objects, of the next element that is distinct from the target object.
|
|
787
|
+
Get the index in the sorted array of objects, of the next element that is distinct from the target object.
|
|
528
788
|
Comparison fields must match the field & sort order of the object array.
|
|
529
789
|
Throw an error if the target object is greater than objArray[startFrom] in terms of sort order.
|
|
530
790
|
Examples of comparison fields: "firstName", "lastName desc", "address.province asc", "address.townOrCity".
|
|
531
791
|
|
|
532
792
|
***Example***
|
|
533
793
|
```
|
|
534
|
-
|
|
794
|
+
import { getNextDifferent } from "some-common-functions-js";
|
|
535
795
|
|
|
536
796
|
teamsArray = [
|
|
537
797
|
{ score: 90, numGames: 10, name: "John" },
|