@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.
Files changed (3) hide show
  1. package/README.md +29 -21
  2. package/index.js +154 -0
  3. 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.10",
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
  }