@terzogenito/json-utils 1.0.8 → 1.0.10

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 +431 -1
  2. package/index.js +467 -8
  3. package/package.json +39 -31
package/README.md CHANGED
@@ -1 +1,431 @@
1
- # json-utils
1
+ # Documentation
2
+
3
+ ## Overview
4
+ This module provides various functions for reading, validating, and processing JSON files and URL content.
5
+
6
+ ## Installation
7
+ ```bash
8
+ npm install @terzogenito/json-utils
9
+ ```
10
+
11
+ ## Function List
12
+
13
+ ### 1. `getData(path)`
14
+ ```javascript
15
+ console.log(await app.getData('./test-data.json'));
16
+ ```
17
+
18
+ **Description**: Reads and returns data from a file asynchronously.
19
+
20
+ **Parameters**:
21
+ - `path` (String): Path to the file to be read
22
+
23
+ ---
24
+
25
+ ### 2. `getString(path)`
26
+ ```javascript
27
+ console.log(app.getString('test-data.json'));
28
+ ```
29
+
30
+ **Description**: Reads a file and returns its content as a string.
31
+
32
+ **Parameters**:
33
+ - `path` (String): Path to the file to be read
34
+
35
+ ---
36
+
37
+ ### 3. `getFile(path, callback)`
38
+ ```javascript
39
+ app.getFile('test-data.json', data => {
40
+ console.log(app.isValid(data));
41
+ });
42
+ ```
43
+
44
+ **Description**: Reads a file and processes the data using a callback function.
45
+
46
+ **Parameters**:
47
+ - `path` (String): Path to the file to be read
48
+ - `callback` (Function): Function to be called with the file data
49
+
50
+ ---
51
+
52
+ ### 4. `isValid(data)`
53
+ ```javascript
54
+ app.getFile('test-data.json', data => {
55
+ console.log(app.isValid(data));
56
+ });
57
+ ```
58
+
59
+ **Description**: Validates whether the data is valid JSON.
60
+
61
+ **Parameters**:
62
+ - `data` (Any): Data to be validated
63
+
64
+ ---
65
+
66
+ ### 5. `toString(data)`
67
+ ```javascript
68
+ app.getFile('test-data.json', data => {
69
+ console.log(app.toString(data));
70
+ });
71
+ ```
72
+
73
+ **Description**: Converts JSON data to a string.
74
+
75
+ **Parameters**:
76
+ - `data` (Object): JSON data to be converted
77
+
78
+ ---
79
+
80
+ ### 6. `readJSON(jsonString)`
81
+ ```javascript
82
+ console.log(app.readJSON('{"name":"John","age":30,"isActive":true}'));
83
+ ```
84
+
85
+ **Description**: Reads and parses a JSON string into a JavaScript object.
86
+
87
+ **Parameters**:
88
+ - `jsonString` (String): JSON string to be parsed
89
+
90
+ ---
91
+
92
+ ### 7. `isJSON(jsonString)`
93
+ ```javascript
94
+ console.log(app.isJSON('{"name":"John","age":30,"isActive":true}'));
95
+ ```
96
+
97
+ **Description**: Checks if a string is valid JSON.
98
+
99
+ **Parameters**:
100
+ - `jsonString` (String): String to be checked
101
+
102
+ ---
103
+
104
+ ### 8. `isJSONObject(obj)`
105
+ ```javascript
106
+ console.log(app.isJSONObject({"name": "John","age": 30,"isActive": true}));
107
+ ```
108
+
109
+ **Description**: Checks if an object is a valid JSON object.
110
+
111
+ **Parameters**:
112
+ - `obj` (Object): Object to be checked
113
+
114
+ ---
115
+
116
+ ### 9. `beautifyJSON(jsonString, indent)`
117
+ ```javascript
118
+ console.log(app.beautifyJSON(jsonString));
119
+ console.log(app.beautifyJSON(jsonString, 4));
120
+ ```
121
+
122
+ **Description**: Formats a JSON string with customizable indentation.
123
+
124
+ **Parameters**:
125
+ - `jsonString` (String): JSON string to be formatted
126
+ - `indent` (Number, optional): Number of spaces for indentation (default: 2)
127
+
128
+ ---
129
+
130
+ ### 10. `beautify(jsonObject)`
131
+ ```javascript
132
+ console.log(app.beautify(sampleJSONObject));
133
+ ```
134
+
135
+ **Description**: Formats a JSON object into a readable string.
136
+
137
+ **Parameters**:
138
+ - `jsonObject` (Object): JSON object to be formatted
139
+
140
+ ---
141
+
142
+ ### 11. `getURL(url, callback)`
143
+ ```javascript
144
+ app.getURL("https://example.com/data.txt", data => {
145
+ console.log(data);
146
+ });
147
+ ```
148
+
149
+ **Description**: Fetches string content from a URL.
150
+
151
+ **Parameters**:
152
+ - `url` (String): Target URL
153
+ - `callback` (Function): Callback function that receives the data
154
+
155
+ ---
156
+
157
+ ### 12. `getJSON(url, callback)`
158
+ ```javascript
159
+ app.getJSON("https://example.com/data.json", data => {
160
+ console.log(data);
161
+ });
162
+ ```
163
+
164
+ **Description**: Fetches and parses JSON content from a URL.
165
+
166
+ **Parameters**:
167
+ - `url` (String): URL pointing to JSON file
168
+ - `callback` (Function): Callback function that receives JSON data
169
+
170
+ ## Usage Examples
171
+
172
+ ```javascript
173
+ const app = require('./index');
174
+
175
+ // Reading local file
176
+ const data = await app.getData('./data.json');
177
+
178
+ // Validating JSON
179
+ const isValid = app.isJSON('{"key": "value"}');
180
+
181
+ // Formatting JSON
182
+ const beautified = app.beautifyJSON('{"key":"value"}', 4);
183
+
184
+ // Fetching data from URL
185
+ app.getJSON("https://api.example.com/data", jsonData => {
186
+ console.log(jsonData);
187
+ });
188
+ ```
189
+
190
+ ### 13. getAttributes(jsonObject)
191
+ ```javascript
192
+ const dataJSON = app.readJSON(data);
193
+ const attributes = app.getAttributes(dataJSON);
194
+ // Output: ['name', 'age', 'isActive', 'address', 'hobbies']
195
+ ```
196
+
197
+ **Description**: Extracts all attribute/keys from a JSON object and returns them as an array.
198
+
199
+ **Parameters**:
200
+ - jsonObject (Object|String): JSON object or JSON string
201
+
202
+ Returns: Array of attribute names
203
+
204
+ ### 14. getMeta(jsonObject)
205
+ ```javascript
206
+ const meta = app.getMeta(dataJSON);
207
+ // Output: {"name": "string", "age": "integer", "isActive": "boolean"}
208
+ ```
209
+
210
+ **Description**: Generates metadata showing attribute names and their data types.
211
+
212
+ **Parameters**:
213
+ - jsonObject (Object|String): JSON object or JSON string
214
+
215
+ Returns: Object with attribute names as keys and data types as values
216
+
217
+ Data Types Identified:
218
+ - string, integer, float, boolean, array, object, null, date
219
+
220
+ ### 15. getMetaDetail(jsonObject)
221
+ ```javascript
222
+ const metaDetail = app.getMetaDetail(dataJSON);
223
+ // Output: Detailed metadata including nested structures
224
+ ```
225
+
226
+ **Description**: Generates comprehensive metadata including nested attributes, data types, paths, and structural information.
227
+
228
+ **Parameters**:
229
+ - jsonObject (Object|String): JSON object or JSON string
230
+
231
+ Returns: Object with detailed metadata for each attribute
232
+
233
+ Metadata Includes:
234
+ - type: Data type
235
+ - isRequired: Whether attribute exists
236
+ - path: Full path to attribute
237
+ - children: Nested attributes (for objects)
238
+ - length: Array length (for arrays)
239
+ - elementType: Type of array elements
240
+
241
+ ### 16. getMetaCompact(jsonObject)
242
+ ```javascript
243
+ const metaCompact = app.getMetaCompact(dataJSON);
244
+ // Output: Compact metadata format
245
+ ```
246
+
247
+ **Description**: Creates a compact metadata representation showing the structure hierarchy.
248
+
249
+ **Parameters**:
250
+ - jsonObject (Object|String): JSON object or JSON string
251
+
252
+ Returns: Compact representation of JSON structure
253
+
254
+ Format Examples:
255
+ - "array[string]": Array of strings
256
+ - "array[object]": Array of objects
257
+ - Nested objects shown as nested objects
258
+
259
+ ### 17. getPartial(jsonObject, attributes)
260
+ ```javascript
261
+ const partial = app.getPartial(dataJSON, ["name", "age"]);
262
+ // Output: {"name": "John", "age": 30}
263
+ ```
264
+
265
+ **Description**: Extracts specific attributes from a JSON object.
266
+
267
+ **Parameters**:
268
+ - jsonObject (Object|String): JSON object or JSON string
269
+ - attributes (Array|String|Object): Attributes to extract
270
+
271
+ attribute Parameter Types:
272
+ - Array: List of attribute names to extract
273
+ ```javascript
274
+ app.getPartial(data, ["name", "age"])
275
+ ```
276
+ - String: Single attribute name
277
+ ```javascript
278
+ app.getPartial(data, "name")
279
+ ```
280
+ - Object: Mapping of new names to original attributes
281
+ ```javascript
282
+ app.getPartial(data, {"fullName": "name", "yearsOld": "age"})
283
+ ```
284
+
285
+ Returns: Object containing only the specified attributes
286
+
287
+ ### 18. getPartialDeep(jsonObject, attributePaths)
288
+ ```javascript
289
+ const deepPartial = app.getPartialDeep(dataJSON, ["name", "address.city", "hobbies.length"]);
290
+ // Output: {"name": "John", "city": "Jakarta", "length": 2}
291
+ ```
292
+
293
+ **Description**: Extracts attributes using nested paths (dot notation).
294
+
295
+ **Parameters**:
296
+ - jsonObject (Object|String): JSON object or JSON string
297
+ - attributePaths (Array|Object): Paths to extract
298
+
299
+ attributePaths Parameter Types:
300
+ - Array: List of dot-notated paths
301
+ ```javascript
302
+ app.getPartialDeep(data, ["user.profile.name", "user.contact.email"])
303
+ ```
304
+ - Object: Mapping of new names to paths
305
+ ```javascript
306
+ app.getPartialDeep(data, {"userName": "user.profile.name", "userEmail": "user.contact.email"})
307
+ ```
308
+
309
+ Returns: Object with extracted values (uses last path segment as key for array input)
310
+
311
+ ### 19. getPartialWithDefaults(jsonObject, attributesConfig)
312
+ ```javascript
313
+ 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
+ }
323
+ });
324
+ ```
325
+
326
+ **Description**: Extracts attributes with advanced configuration including default values and transformations.
327
+
328
+ **Parameters**:
329
+ - jsonObject (Object|String): JSON object or JSON string
330
+ - attributesConfig (Object): Configuration object
331
+
332
+ Configuration Options:
333
+ - String: Simple path extraction
334
+ ```javascript
335
+ "name": "user.fullName"
336
+ ```
337
+ - Object: Advanced configuration
338
+ ```javascript
339
+ "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
343
+ }
344
+ ```
345
+
346
+ Returns: Object with extracted and processed values
347
+
348
+ ### 20. excludeAttributes(jsonObject, attributesToExclude)
349
+ ```javascript
350
+ const filtered = app.excludeAttributes(dataJSON, ["isActive", "address"]);
351
+ // Output: {"name": "John", "age": 30, "hobbies": ["reading", "coding"]}
352
+ ```
353
+
354
+ **Description**: Creates a new JSON object excluding specified attributes.
355
+
356
+ **Parameters**:
357
+ - jsonObject (Object|String): JSON object or JSON string
358
+ - attributesToExclude (Array|String): Attributes to remove
359
+
360
+ attributesToExclude Parameter Types:
361
+ - Array: List of attribute names to exclude
362
+ ```javascript
363
+ app.excludeAttributes(data, ["password", "secretKey"])
364
+ ```
365
+ - String: Single attribute name to exclude
366
+ ```javascript
367
+ app.excludeAttributes(data, "password")
368
+ ```
369
+
370
+ Returns: New object without the excluded attributes
371
+
372
+ ### 21. getAttributeValue(jsonObject, attributeName, defaultValue)
373
+ ```javascript
374
+ const name = app.getAttributeValue(dataJSON, "name");
375
+ const email = app.getAttributeValue(dataJSON, "email", "default@email.com");
376
+ ```
377
+
378
+ **Description**: Gets the value of a specific attribute with optional default value.
379
+
380
+ **Parameters**:
381
+ - jsonObject (Object|String): JSON object or JSON string
382
+ - attributeName (String): Name of the attribute to retrieve
383
+ - defaultValue (Any, optional): Default value if attribute doesn't exist
384
+
385
+ Returns: Attribute value or default value
386
+
387
+ Advanced Usage Examples
388
+ ```javascript
389
+ const app = require('./index');
390
+
391
+ // Get all attributes from JSON
392
+ const data = await app.getData('./data.json');
393
+ const jsonData = app.readJSON(data);
394
+ const attributes = app.getAttributes(jsonData);
395
+
396
+ // Get metadata information
397
+ const meta = app.getMeta(jsonData);
398
+ const metaDetail = app.getMetaDetail(jsonData);
399
+
400
+ // Extract specific data
401
+ const userInfo = app.getPartial(jsonData, ["name", "email", "phone"]);
402
+ const nestedData = app.getPartialDeep(jsonData, ["user.profile.name", "user.contact.email"]);
403
+
404
+ // Extract with transformations and defaults
405
+ 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
+ }
415
+ });
416
+
417
+ // Exclude sensitive information
418
+ const safeData = app.excludeAttributes(jsonData, ["password", "ssn", "creditCard"]);
419
+
420
+ // Analyze complex nested structures
421
+ const complexMeta = app.getMetaDetail(complexJSON);
422
+ console.log(complexMeta.user?.children?.contact?.children?.email?.type); // "string"
423
+
424
+ // Get single attribute value
425
+ const userName = app.getAttributeValue(jsonData, "name");
426
+ const userEmail = app.getAttributeValue(jsonData, "email", "no-email@example.com");
427
+ ```
428
+
429
+ ## Requirements
430
+ - Node.js 12 or higher
431
+ - Internet connection (for URL functions)
package/index.js CHANGED
@@ -1,4 +1,67 @@
1
- const fileUtils = require('@terzogenito/file-utils');
1
+ const fs = require('fs');
2
+ const https = require('https');
3
+
4
+ function getString(filePath) {
5
+ return fs.readFileSync(filePath, 'utf-8');
6
+ }
7
+
8
+ function getFile(filePath, callback) {
9
+ fs.readFile(filePath, 'utf8', (err, data) => {
10
+ if (err) {
11
+ return;
12
+ } else {
13
+ callback(data);
14
+ }
15
+ });
16
+ }
17
+
18
+ function loadFile(filePath) {
19
+ return new Promise((resolve, reject) => {
20
+ fs.readFile(filePath, 'utf8', (err, data) => {
21
+ if (err) {
22
+ reject(err);
23
+ } else {
24
+ resolve(data);
25
+ }
26
+ });
27
+ });
28
+ }
29
+
30
+ async function getData(filePath) {
31
+ try {
32
+ const data = await loadFile(filePath);
33
+ return data;
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+
39
+ function getURL(url, callback) {
40
+ https.get(url, (response) => {
41
+ let data = '';
42
+ response.on('data', chunk => {
43
+ data += chunk;
44
+ });
45
+ response.on('end', () => {
46
+ callback(data || null);
47
+ });
48
+ }).on('error', (err) => {
49
+ callback(null);
50
+ });
51
+ }
52
+
53
+ function isUrl(input) {
54
+ const urlPattern = /^(https?:\/\/|ftp:\/\/|www\.)/i;
55
+ return urlPattern.test(input);
56
+ }
57
+
58
+ function getContent(target, callback) {
59
+ if (isUrl(target)) {
60
+ getURL(target, callback);
61
+ } else {
62
+ getFile(target, callback);
63
+ }
64
+ }
2
65
 
3
66
  function readJSON(jsonString) {
4
67
  return JSON.parse(jsonString);
@@ -12,8 +75,7 @@ function isValid(jsonString) {
12
75
  try {
13
76
  JSON.parse(jsonString);
14
77
  return true;
15
- } catch (error) {
16
- console.log("The string is not valid JSON.");
78
+ } catch {
17
79
  return false;
18
80
  }
19
81
  }
@@ -27,30 +89,427 @@ function isJSON(jsonObject) {
27
89
  }
28
90
  }
29
91
 
92
+ function isJSONObject(jsonObject) {
93
+ try {
94
+ return typeof jsonObject === 'object' && jsonObject !== null && jsonObject !== undefined;
95
+ } catch (error) {
96
+ return false;
97
+ }
98
+ }
99
+
30
100
  function getJSON(target, callback) {
31
- fileUtils.getContent(target, data => {
32
- if (isValid(data)) {
101
+ getContent(target, data => {
102
+ if (!data) {
103
+ return callback(null);
104
+ }
105
+ if (!isValid(data)) {
106
+ return callback(null);
107
+ }
108
+ try {
33
109
  callback(readJSON(data));
110
+ } catch {
111
+ callback(null);
34
112
  }
35
113
  });
36
114
  }
37
115
 
38
- function beautifyJSON(jsonString, indent) {
116
+ function beautifyJSON(jsonString, indent = 2) {
39
117
  try {
118
+ if (typeof jsonString !== 'string') return null;
40
119
  const jsonObject = JSON.parse(jsonString);
120
+ return JSON.stringify(jsonObject, null, indent);
121
+ } catch {
122
+ return null;
123
+ }
124
+ }
125
+
126
+ function beautify(jsonObject, indent) {
127
+ try {
41
128
  if (!indent) indent = 2;
42
129
  return JSON.stringify(jsonObject, null, indent);
43
130
  } catch (error) {
44
- console.error("Invalid JSON string:", error);
45
131
  return null;
46
132
  }
47
133
  }
48
134
 
135
+ function getAttributes(jsonObject) {
136
+ try {
137
+ if (typeof jsonObject === 'string') {
138
+ jsonObject = JSON.parse(jsonObject);
139
+ }
140
+
141
+ if (typeof jsonObject !== 'object' || jsonObject === null) {
142
+ return [];
143
+ }
144
+
145
+ return Object.keys(jsonObject);
146
+ } catch (error) {
147
+ return [];
148
+ }
149
+ }
150
+
151
+ function getMeta(jsonObject) {
152
+ try {
153
+ if (typeof jsonObject === 'string') {
154
+ jsonObject = JSON.parse(jsonObject);
155
+ }
156
+
157
+ if (typeof jsonObject !== 'object' || jsonObject === null) {
158
+ return {};
159
+ }
160
+
161
+ const meta = {};
162
+
163
+ for (const [key, value] of Object.entries(jsonObject)) {
164
+ let type = typeof value;
165
+
166
+ if (type === 'object') {
167
+ if (value === null) {
168
+ type = 'null';
169
+ } else if (Array.isArray(value)) {
170
+ type = 'array';
171
+ } else if (value instanceof Date) {
172
+ type = 'date';
173
+ } else {
174
+ type = 'object';
175
+ }
176
+ } else if (type === 'number') {
177
+ type = Number.isInteger(value) ? 'integer' : 'float';
178
+ }
179
+
180
+ meta[key] = type;
181
+ }
182
+
183
+ return meta;
184
+ } catch (error) {
185
+ return {};
186
+ }
187
+ }
188
+
189
+ function getMetaDetail(jsonObject) {
190
+ try {
191
+ if (typeof jsonObject === 'string') {
192
+ jsonObject = JSON.parse(jsonObject);
193
+ }
194
+
195
+ if (typeof jsonObject !== 'object' || jsonObject === null) {
196
+ return {};
197
+ }
198
+
199
+ function getNestedMeta(obj, path = '') {
200
+ const meta = {};
201
+
202
+ for (const [key, value] of Object.entries(obj)) {
203
+ const currentPath = path ? `${path}.${key}` : key;
204
+ const attributeMeta = {};
205
+
206
+ let type = typeof value;
207
+
208
+ if (value === null) {
209
+ type = 'null';
210
+ attributeMeta.type = type;
211
+ attributeMeta.isRequired = false;
212
+ attributeMeta.path = currentPath;
213
+ } else if (Array.isArray(value)) {
214
+ type = 'array';
215
+ attributeMeta.type = type;
216
+ attributeMeta.length = value.length;
217
+ attributeMeta.isRequired = true;
218
+ attributeMeta.path = currentPath;
219
+
220
+ if (value.length > 0) {
221
+ const firstElement = value[0];
222
+ const elementType = typeof firstElement;
223
+
224
+ if (elementType === 'object' && firstElement !== null) {
225
+ if (Array.isArray(firstElement)) {
226
+ attributeMeta.elementType = 'array';
227
+ } else {
228
+ attributeMeta.elementType = 'object';
229
+ attributeMeta.children = getNestedMeta(firstElement, `${currentPath}[0]`);
230
+ }
231
+ } else {
232
+ attributeMeta.elementType = elementType;
233
+ }
234
+ } else {
235
+ attributeMeta.elementType = 'unknown';
236
+ }
237
+ } else if (value instanceof Date) {
238
+ type = 'date';
239
+ attributeMeta.type = type;
240
+ attributeMeta.isRequired = true;
241
+ attributeMeta.path = currentPath;
242
+ } else if (type === 'object') {
243
+ type = 'object';
244
+ attributeMeta.type = type;
245
+ attributeMeta.isRequired = true;
246
+ attributeMeta.path = currentPath;
247
+ attributeMeta.keysCount = Object.keys(value).length;
248
+
249
+ attributeMeta.children = getNestedMeta(value, currentPath);
250
+ } else {
251
+ attributeMeta.type = type;
252
+ attributeMeta.isRequired = true;
253
+ attributeMeta.path = currentPath;
254
+
255
+ if (type === 'number') {
256
+ attributeMeta.numberType = Number.isInteger(value) ? 'integer' : 'float';
257
+ }
258
+ }
259
+
260
+ meta[key] = attributeMeta;
261
+ }
262
+
263
+ return meta;
264
+ }
265
+
266
+ return getNestedMeta(jsonObject);
267
+ } catch (error) {
268
+ console.error('Error in getMetaDetail:', error);
269
+ return {};
270
+ }
271
+ }
272
+
273
+ function getMetaCompact(jsonObject) {
274
+ try {
275
+ if (typeof jsonObject === 'string') {
276
+ jsonObject = JSON.parse(jsonObject);
277
+ }
278
+
279
+ if (typeof jsonObject !== 'object' || jsonObject === null) {
280
+ return {};
281
+ }
282
+
283
+ function getCompactMeta(obj) {
284
+ const meta = {};
285
+
286
+ for (const [key, value] of Object.entries(obj)) {
287
+ let type = typeof value;
288
+
289
+ if (value === null) {
290
+ meta[key] = 'null';
291
+ } else if (Array.isArray(value)) {
292
+ if (value.length > 0) {
293
+ const firstElement = value[0];
294
+ const elementType = typeof firstElement;
295
+ if (elementType === 'object' && firstElement !== null) {
296
+ meta[key] = `array[${Array.isArray(firstElement) ? 'array' : 'object'}]`;
297
+ } else {
298
+ meta[key] = `array[${elementType}]`;
299
+ }
300
+ } else {
301
+ meta[key] = 'array[]';
302
+ }
303
+ } else if (value instanceof Date) {
304
+ meta[key] = 'date';
305
+ } else if (type === 'object') {
306
+ meta[key] = getCompactMeta(value);
307
+ } else if (type === 'number') {
308
+ meta[key] = Number.isInteger(value) ? 'integer' : 'float';
309
+ } else {
310
+ meta[key] = type;
311
+ }
312
+ }
313
+
314
+ return meta;
315
+ }
316
+
317
+ return getCompactMeta(jsonObject);
318
+ } catch (error) {
319
+ console.error('Error in getMetaCompact:', error);
320
+ return {};
321
+ }
322
+ }
323
+
324
+ function getPartial(jsonObject, attributes) {
325
+ try {
326
+ if (typeof jsonObject === 'string') {
327
+ jsonObject = JSON.parse(jsonObject);
328
+ }
329
+
330
+ if (typeof jsonObject !== 'object' || jsonObject === null) {
331
+ return {};
332
+ }
333
+
334
+ const result = {};
335
+
336
+ if (Array.isArray(attributes)) {
337
+ for (const attr of attributes) {
338
+ if (attr in jsonObject) {
339
+ result[attr] = jsonObject[attr];
340
+ }
341
+ }
342
+ }
343
+ else if (typeof attributes === 'string') {
344
+ if (attributes in jsonObject) {
345
+ result[attributes] = jsonObject[attributes];
346
+ }
347
+ }
348
+ else if (typeof attributes === 'object' && attributes !== null) {
349
+ for (const [newKey, originalKey] of Object.entries(attributes)) {
350
+ if (originalKey in jsonObject) {
351
+ result[newKey] = jsonObject[originalKey];
352
+ }
353
+ }
354
+ }
355
+
356
+ return result;
357
+ } catch (error) {
358
+ console.error('Error in getPartial:', error);
359
+ return {};
360
+ }
361
+ }
362
+
363
+ function getPartialDeep(jsonObject, attributePaths) {
364
+ try {
365
+ if (typeof jsonObject === 'string') {
366
+ jsonObject = JSON.parse(jsonObject);
367
+ }
368
+
369
+ if (typeof jsonObject !== 'object' || jsonObject === null) {
370
+ return {};
371
+ }
372
+
373
+ const result = {};
374
+
375
+ function getValueFromPath(obj, path) {
376
+ const parts = path.split('.');
377
+ let current = obj;
378
+
379
+ for (const part of parts) {
380
+ if (current && typeof current === 'object' && part in current) {
381
+ current = current[part];
382
+ } else {
383
+ return undefined;
384
+ }
385
+ }
386
+
387
+ return current;
388
+ }
389
+
390
+ if (Array.isArray(attributePaths)) {
391
+ for (const path of attributePaths) {
392
+ const value = getValueFromPath(jsonObject, path);
393
+ if (value !== undefined) {
394
+ const key = path.split('.').pop();
395
+ result[key] = value;
396
+ }
397
+ }
398
+ }
399
+ else if (typeof attributePaths === 'object' && attributePaths !== null) {
400
+ for (const [newKey, path] of Object.entries(attributePaths)) {
401
+ const value = getValueFromPath(jsonObject, path);
402
+ if (value !== undefined) {
403
+ result[newKey] = value;
404
+ }
405
+ }
406
+ }
407
+
408
+ return result;
409
+ } catch (error) {
410
+ console.error('Error in getPartialDeep:', error);
411
+ return {};
412
+ }
413
+ }
414
+
415
+ function getPartialWithDefaults(jsonObject, attributesConfig) {
416
+ try {
417
+ if (typeof jsonObject === 'string') {
418
+ jsonObject = JSON.parse(jsonObject);
419
+ }
420
+
421
+ if (typeof jsonObject !== 'object' || jsonObject === null) {
422
+ return {};
423
+ }
424
+
425
+ const result = {};
426
+
427
+ function getValueFromPath(obj, path, defaultValue) {
428
+ const parts = path.split('.');
429
+ let current = obj;
430
+
431
+ for (const part of parts) {
432
+ if (current && typeof current === 'object' && part in current) {
433
+ current = current[part];
434
+ } else {
435
+ return defaultValue;
436
+ }
437
+ }
438
+
439
+ return current;
440
+ }
441
+
442
+ for (const [outputKey, config] of Object.entries(attributesConfig)) {
443
+ if (typeof config === 'string') {
444
+ result[outputKey] = getValueFromPath(jsonObject, config, undefined);
445
+ } else if (typeof config === 'object' && config !== null) {
446
+ const path = config.path || outputKey;
447
+ const defaultValue = config.default;
448
+ let value = getValueFromPath(jsonObject, path, defaultValue);
449
+
450
+ if (config.transform && typeof config.transform === 'function') {
451
+ value = config.transform(value);
452
+ }
453
+
454
+ result[outputKey] = value;
455
+ }
456
+ }
457
+
458
+ return result;
459
+ } catch (error) {
460
+ console.error('Error in getPartialWithDefaults:', error);
461
+ return {};
462
+ }
463
+ }
464
+
465
+ function excludeAttributes(jsonObject, attributesToExclude) {
466
+ try {
467
+ if (typeof jsonObject === 'string') {
468
+ jsonObject = JSON.parse(jsonObject);
469
+ }
470
+
471
+ if (typeof jsonObject !== 'object' || jsonObject === null) {
472
+ return {};
473
+ }
474
+
475
+ const result = { ...jsonObject };
476
+
477
+ if (Array.isArray(attributesToExclude)) {
478
+ for (const attr of attributesToExclude) {
479
+ delete result[attr];
480
+ }
481
+ }
482
+ else if (typeof attributesToExclude === 'string') {
483
+ delete result[attributesToExclude];
484
+ }
485
+
486
+ return result;
487
+ } catch (error) {
488
+ console.error('Error in excludeAttributes:', error);
489
+ return {};
490
+ }
491
+ }
492
+
49
493
  module.exports = {
494
+ getString,
495
+ getFile,
496
+ getData,
497
+ getURL,
498
+ getContent,
50
499
  readJSON,
51
500
  toString,
52
501
  isValid,
53
502
  isJSON,
503
+ isJSONObject,
54
504
  getJSON,
55
505
  beautifyJSON,
56
- };
506
+ beautify,
507
+ getAttributes,
508
+ getMeta,
509
+ getMetaDetail,
510
+ getMetaCompact,
511
+ getPartial,
512
+ getPartialDeep,
513
+ getPartialWithDefaults,
514
+ excludeAttributes,
515
+ };
package/package.json CHANGED
@@ -1,31 +1,39 @@
1
- {
2
- "name": "@terzogenito/json-utils",
3
- "version": "1.0.8",
4
- "description": "Check JSON Format",
5
- "main": "index.js",
6
- "files": [
7
- "index.js"
8
- ],
9
- "scripts": {
10
- "start": "node test.js",
11
- "test": "echo \"Error: no test specified\" && exit 1"
12
- },
13
- "publishConfig": {
14
- "access": "public"
15
- },
16
- "engines": {
17
- "node": ">=21.6.1"
18
- },
19
- "keywords": [
20
- "nodejs",
21
- "module",
22
- "json",
23
- "check",
24
- "utils"
25
- ],
26
- "author": "Terzogenito",
27
- "license": "MIT",
28
- "dependencies": {
29
- "@terzogenito/file-utils": "^1.0.0"
30
- }
31
- }
1
+ {
2
+ "name": "@terzogenito/json-utils",
3
+ "version": "1.0.10",
4
+ "description": "JSON data utilities",
5
+ "main": "index.js",
6
+ "files": [
7
+ "index.js"
8
+ ],
9
+ "scripts": {
10
+ "start": "node test.js",
11
+ "test": "echo \"Error: no test specified\" && exit 1"
12
+ },
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "engines": {
17
+ "node": ">=21.6.1"
18
+ },
19
+ "keywords": [
20
+ "nodejs",
21
+ "module",
22
+ "utils",
23
+ "tools",
24
+ "json",
25
+ "check",
26
+ "beautify",
27
+ "analysis"
28
+ ],
29
+ "author": "Terzogenito",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
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
+ }
39
+ }