@terzogenito/json-utils 1.0.10 → 1.0.12
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 +29 -21
- package/index.js +154 -0
- package/package.json +1 -5
package/README.md
CHANGED
|
@@ -8,6 +8,14 @@ This module provides various functions for reading, validating, and processing J
|
|
|
8
8
|
npm install @terzogenito/json-utils
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Quick Start
|
|
12
|
+
```javascript
|
|
13
|
+
import jsonUtils from '@terzogenito/json-utils';
|
|
14
|
+
|
|
15
|
+
const jsonAttributes = jsonUtils.getAttributes(jsonData);
|
|
16
|
+
console.log(jsonAttributes);
|
|
17
|
+
```
|
|
18
|
+
|
|
11
19
|
## Function List
|
|
12
20
|
|
|
13
21
|
### 1. `getData(path)`
|
|
@@ -311,15 +319,15 @@ Returns: Object with extracted values (uses last path segment as key for array i
|
|
|
311
319
|
### 19. getPartialWithDefaults(jsonObject, attributesConfig)
|
|
312
320
|
```javascript
|
|
313
321
|
const partialWithDefaults = app.getPartialWithDefaults(dataJSON, {
|
|
314
|
-
"name": "name",
|
|
315
|
-
"status": {
|
|
316
|
-
path: "isActive",
|
|
317
|
-
transform: (val) => val ? "Active" : "Inactive"
|
|
318
|
-
},
|
|
319
|
-
"email": {
|
|
320
|
-
path: "contact.email",
|
|
321
|
-
default: "no-email@example.com"
|
|
322
|
-
}
|
|
322
|
+
"name": "name",
|
|
323
|
+
"status": {
|
|
324
|
+
path: "isActive",
|
|
325
|
+
transform: (val) => val ? "Active" : "Inactive"
|
|
326
|
+
},
|
|
327
|
+
"email": {
|
|
328
|
+
path: "contact.email",
|
|
329
|
+
default: "no-email@example.com"
|
|
330
|
+
}
|
|
323
331
|
});
|
|
324
332
|
```
|
|
325
333
|
|
|
@@ -337,9 +345,9 @@ Configuration Options:
|
|
|
337
345
|
- Object: Advanced configuration
|
|
338
346
|
```javascript
|
|
339
347
|
"formattedAge": {
|
|
340
|
-
path: "age", // Required: Path to attribute
|
|
341
|
-
default: 0, // Optional: Default value if path doesn't exist
|
|
342
|
-
transform: (val) => ${val} years old // Optional: Transformation function
|
|
348
|
+
path: "age", // Required: Path to attribute
|
|
349
|
+
default: 0, // Optional: Default value if path doesn't exist
|
|
350
|
+
transform: (val) => ${val} years old // Optional: Transformation function
|
|
343
351
|
}
|
|
344
352
|
```
|
|
345
353
|
|
|
@@ -403,15 +411,15 @@ const nestedData = app.getPartialDeep(jsonData, ["user.profile.name", "user.cont
|
|
|
403
411
|
|
|
404
412
|
// Extract with transformations and defaults
|
|
405
413
|
const processedData = app.getPartialWithDefaults(jsonData, {
|
|
406
|
-
"fullName": "user.name",
|
|
407
|
-
"ageFormatted": {
|
|
408
|
-
path: "user.age",
|
|
409
|
-
transform: (age) => ${age} years old
|
|
410
|
-
},
|
|
411
|
-
"country": {
|
|
412
|
-
path: "user.address.country",
|
|
413
|
-
default: "Unknown"
|
|
414
|
-
}
|
|
414
|
+
"fullName": "user.name",
|
|
415
|
+
"ageFormatted": {
|
|
416
|
+
path: "user.age",
|
|
417
|
+
transform: (age) => ${age} years old
|
|
418
|
+
},
|
|
419
|
+
"country": {
|
|
420
|
+
path: "user.address.country",
|
|
421
|
+
default: "Unknown"
|
|
422
|
+
}
|
|
415
423
|
});
|
|
416
424
|
|
|
417
425
|
// Exclude sensitive information
|
package/index.js
CHANGED
|
@@ -490,6 +490,155 @@ function excludeAttributes(jsonObject, attributesToExclude) {
|
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
492
|
|
|
493
|
+
function getSize(jsonObject) {
|
|
494
|
+
try {
|
|
495
|
+
const jsonString = typeof jsonObject === 'string'
|
|
496
|
+
? jsonObject
|
|
497
|
+
: JSON.stringify(jsonObject);
|
|
498
|
+
return new Blob([jsonString]).size;
|
|
499
|
+
} catch (error) {
|
|
500
|
+
console.error('Error in getSize:', error);
|
|
501
|
+
return 0;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function sortBy(array, key, ascending = true) {
|
|
506
|
+
try {
|
|
507
|
+
if (!Array.isArray(array)) return array;
|
|
508
|
+
|
|
509
|
+
return [...array].sort((a, b) => {
|
|
510
|
+
const aValue = typeof key === 'function' ? key(a) : a[key];
|
|
511
|
+
const bValue = typeof key === 'function' ? key(b) : b[key];
|
|
512
|
+
|
|
513
|
+
if (aValue < bValue) return ascending ? -1 : 1;
|
|
514
|
+
if (aValue > bValue) return ascending ? 1 : -1;
|
|
515
|
+
return 0;
|
|
516
|
+
});
|
|
517
|
+
} catch (error) {
|
|
518
|
+
console.error('Error in sortBy:', error);
|
|
519
|
+
return array;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
function findKeys(jsonObject, keyName) {
|
|
524
|
+
try {
|
|
525
|
+
if (typeof jsonObject === 'string') {
|
|
526
|
+
jsonObject = JSON.parse(jsonObject);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (typeof jsonObject !== 'object' || jsonObject === null) {
|
|
530
|
+
return [];
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const results = [];
|
|
534
|
+
const pattern = keyName.includes('*')
|
|
535
|
+
? new RegExp('^' + keyName.replace(/\*/g, '.*') + '$')
|
|
536
|
+
: null;
|
|
537
|
+
|
|
538
|
+
function search(obj, path = '') {
|
|
539
|
+
if (typeof obj !== 'object' || obj === null) return;
|
|
540
|
+
|
|
541
|
+
if (Array.isArray(obj)) {
|
|
542
|
+
obj.forEach((item, index) => {
|
|
543
|
+
search(item, path ? `${path}[${index}]` : `[${index}]`);
|
|
544
|
+
});
|
|
545
|
+
} else {
|
|
546
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
547
|
+
const newPath = path ? `${path}.${key}` : key;
|
|
548
|
+
|
|
549
|
+
const isMatch = pattern ? pattern.test(key) : key === keyName;
|
|
550
|
+
if (isMatch) {
|
|
551
|
+
results.push({ path: newPath, value });
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (typeof value === 'object' && value !== null) {
|
|
555
|
+
search(value, newPath);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
search(jsonObject);
|
|
562
|
+
return results;
|
|
563
|
+
} catch (error) {
|
|
564
|
+
console.error('Error in findKeys:', error);
|
|
565
|
+
return [];
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
function deepEqual(obj1, obj2) {
|
|
570
|
+
if (obj1 === obj2) return true;
|
|
571
|
+
|
|
572
|
+
if (typeof obj1 !== 'object' || obj1 === null ||
|
|
573
|
+
typeof obj2 !== 'object' || obj2 === null) {
|
|
574
|
+
return false;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
const keys1 = Object.keys(obj1);
|
|
578
|
+
const keys2 = Object.keys(obj2);
|
|
579
|
+
|
|
580
|
+
if (keys1.length !== keys2.length) return false;
|
|
581
|
+
|
|
582
|
+
for (const key of keys1) {
|
|
583
|
+
if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {
|
|
584
|
+
return false;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
return true;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
function diff(obj1, obj2, path = '') {
|
|
592
|
+
const differences = [];
|
|
593
|
+
|
|
594
|
+
if (typeof obj1 !== 'object' || obj1 === null ||
|
|
595
|
+
typeof obj2 !== 'object' || obj2 === null) {
|
|
596
|
+
if (obj1 !== obj2) {
|
|
597
|
+
differences.push({
|
|
598
|
+
path,
|
|
599
|
+
type: 'value',
|
|
600
|
+
old: obj1,
|
|
601
|
+
new: obj2
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
return differences;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
const allKeys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]);
|
|
608
|
+
|
|
609
|
+
for (const key of allKeys) {
|
|
610
|
+
const newPath = path ? `${path}.${key}` : key;
|
|
611
|
+
|
|
612
|
+
if (!(key in obj1)) {
|
|
613
|
+
differences.push({
|
|
614
|
+
path: newPath,
|
|
615
|
+
type: 'added',
|
|
616
|
+
value: obj2[key]
|
|
617
|
+
});
|
|
618
|
+
} else if (!(key in obj2)) {
|
|
619
|
+
differences.push({
|
|
620
|
+
path: newPath,
|
|
621
|
+
type: 'removed',
|
|
622
|
+
value: obj1[key]
|
|
623
|
+
});
|
|
624
|
+
} else if (!deepEqual(obj1[key], obj2[key])) {
|
|
625
|
+
if (typeof obj1[key] === 'object' && obj1[key] !== null &&
|
|
626
|
+
typeof obj2[key] === 'object' && obj2[key] !== null) {
|
|
627
|
+
differences.push(...diff(obj1[key], obj2[key], newPath));
|
|
628
|
+
} else {
|
|
629
|
+
differences.push({
|
|
630
|
+
path: newPath,
|
|
631
|
+
type: 'changed',
|
|
632
|
+
old: obj1[key],
|
|
633
|
+
new: obj2[key]
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
return differences;
|
|
640
|
+
}
|
|
641
|
+
|
|
493
642
|
module.exports = {
|
|
494
643
|
getString,
|
|
495
644
|
getFile,
|
|
@@ -512,4 +661,9 @@ module.exports = {
|
|
|
512
661
|
getPartialDeep,
|
|
513
662
|
getPartialWithDefaults,
|
|
514
663
|
excludeAttributes,
|
|
664
|
+
getSize,
|
|
665
|
+
sortBy,
|
|
666
|
+
findKeys,
|
|
667
|
+
deepEqual,
|
|
668
|
+
diff
|
|
515
669
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@terzogenito/json-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "JSON data utilities",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -31,9 +31,5 @@
|
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
33
|
"url": "https://github.com/terzogenito/json-utils.git"
|
|
34
|
-
},
|
|
35
|
-
"homepage": "https://github.com/terzogenito/json-utils#readme",
|
|
36
|
-
"bugs": {
|
|
37
|
-
"url": "https://github.com/terzogenito/json-utils/issues"
|
|
38
34
|
}
|
|
39
35
|
}
|