devkits-json-formatter 1.0.0 → 1.0.1
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 +103 -23
- package/index.js +153 -69
- package/package.json +17 -30
package/README.md
CHANGED
|
@@ -1,45 +1,125 @@
|
|
|
1
1
|
# @devkits/json-formatter
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://devkits-tools.surge.sh)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Format, validate, and minify JSON. Syntax error detection with position info. Zero-dependency JSON utility for developers.
|
|
6
|
+
|
|
7
|
+
## 🧰 DevKits Pro Tools
|
|
8
|
+
|
|
9
|
+
This package is part of **DevKits** — 82+ free developer tools. The online JSON Formatter includes schema validation, tree view, and query/filter tools.
|
|
10
|
+
|
|
11
|
+
**→ [Format JSON with Tree View](https://devkits-tools.surge.sh)**
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
6
14
|
|
|
7
15
|
```bash
|
|
8
|
-
npm install
|
|
16
|
+
npm install @devkits/json-formatter
|
|
9
17
|
```
|
|
10
18
|
|
|
11
19
|
## Usage
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
```javascript
|
|
22
|
+
const {
|
|
23
|
+
format,
|
|
24
|
+
minify,
|
|
25
|
+
isValid,
|
|
26
|
+
pretty,
|
|
27
|
+
countKeys,
|
|
28
|
+
getSizeInfo,
|
|
29
|
+
sortKeys,
|
|
30
|
+
formatSorted
|
|
31
|
+
} = require('@devkits/json-formatter');
|
|
32
|
+
|
|
33
|
+
const uglyJson = '{"name":"John","age":30,"city":"NYC"}';
|
|
34
|
+
|
|
35
|
+
// Format JSON with indentation
|
|
36
|
+
const result = format(uglyJson, { indent: 2 });
|
|
37
|
+
// {
|
|
38
|
+
// success: true,
|
|
39
|
+
// result: '{\n "name": "John",\n "age": 30,\n "city": "NYC"\n}'
|
|
40
|
+
// }
|
|
41
|
+
|
|
42
|
+
// Minify JSON
|
|
43
|
+
const min = minify(uglyJson);
|
|
44
|
+
// { success: true, result: '{"name":"John",...}', saved: 15 }
|
|
45
|
+
|
|
46
|
+
// Validate JSON
|
|
47
|
+
isValid('{"valid": true}');
|
|
48
|
+
// { valid: true }
|
|
49
|
+
|
|
50
|
+
isValid('{invalid}');
|
|
51
|
+
// { valid: false, error: 'Unexpected token...', position: {line: 1, column: 2} }
|
|
52
|
+
|
|
53
|
+
// Pretty print an object
|
|
54
|
+
pretty({ name: 'John', age: 30 });
|
|
55
|
+
// '{\n "name": "John",\n "age": 30\n}'
|
|
56
|
+
|
|
57
|
+
// Count keys recursively
|
|
58
|
+
const nested = { a: { b: { c: 1 } }, d: [1, 2, 3] };
|
|
59
|
+
countKeys(nested);
|
|
60
|
+
// 5
|
|
61
|
+
|
|
62
|
+
// Get size info
|
|
63
|
+
getSizeInfo(uglyJson);
|
|
64
|
+
// { original: 36, minified: 36, saved: 0, keys: 3 }
|
|
65
|
+
|
|
66
|
+
// Sort keys alphabetically
|
|
67
|
+
const unsorted = { z: 1, a: 2, m: 3 };
|
|
68
|
+
sortKeys(unsorted);
|
|
69
|
+
// { a: 2, m: 3, z: 1 }
|
|
70
|
+
|
|
71
|
+
// Format with sorted keys
|
|
72
|
+
formatSorted('{"z":1,"a":2}', 2);
|
|
73
|
+
// { success: true, result: '{\n "a": 2,\n "z": 1\n}' }
|
|
74
|
+
```
|
|
14
75
|
|
|
15
|
-
|
|
16
|
-
# From stdin
|
|
17
|
-
echo '{"name":"DevKits","tools":84}' | jsonfmt
|
|
76
|
+
## API
|
|
18
77
|
|
|
19
|
-
|
|
20
|
-
|
|
78
|
+
### `format(jsonString, options)`
|
|
79
|
+
Formats JSON with specified indentation (default: 2 spaces).
|
|
21
80
|
|
|
22
|
-
|
|
23
|
-
jsonfmt '{"test":true}'
|
|
24
|
-
```
|
|
81
|
+
Returns `{success, result?, error?}`.
|
|
25
82
|
|
|
26
|
-
###
|
|
83
|
+
### `minify(jsonString)`
|
|
84
|
+
Removes all whitespace from JSON.
|
|
27
85
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
86
|
+
Returns `{success, result?, error?, saved?}`.
|
|
87
|
+
|
|
88
|
+
### `isValid(jsonString)`
|
|
89
|
+
Validates JSON syntax with optional error position.
|
|
90
|
+
|
|
91
|
+
Returns `{valid, error?, position?}`.
|
|
92
|
+
|
|
93
|
+
### `pretty(obj, indent)`
|
|
94
|
+
Pretty prints a JavaScript object as JSON string.
|
|
95
|
+
|
|
96
|
+
### `countKeys(obj)`
|
|
97
|
+
Counts all keys in an object recursively.
|
|
98
|
+
|
|
99
|
+
### `getSizeInfo(jsonString)`
|
|
100
|
+
Returns size statistics: original size, minified size, bytes saved, key count.
|
|
101
|
+
|
|
102
|
+
### `sortKeys(obj)`
|
|
103
|
+
Returns new object with keys sorted alphabetically (recursive).
|
|
104
|
+
|
|
105
|
+
### `formatSorted(jsonString, indent)`
|
|
106
|
+
Formats JSON with keys sorted alphabetically.
|
|
32
107
|
|
|
33
|
-
|
|
108
|
+
## See Also
|
|
34
109
|
|
|
35
|
-
|
|
110
|
+
**Free Online Version:** [DevKits - JSON Formatter](https://devkits-tools.surge.sh)
|
|
36
111
|
|
|
37
|
-
###
|
|
112
|
+
### Other DevKits npm Packages
|
|
38
113
|
|
|
39
|
-
|
|
114
|
+
| Package | Description |
|
|
115
|
+
|---------|-------------|
|
|
116
|
+
| @devkits/base64-tool | Base64 encoding/decoding |
|
|
117
|
+
| @devkits/csv-json-converter | Convert between CSV and JSON |
|
|
118
|
+
| @devkits/markdown-tools | Markdown utilities |
|
|
119
|
+
| @devkits/env-editor | .env file utilities |
|
|
40
120
|
|
|
41
|
-
|
|
121
|
+
**Browse all 82 tools at [DevKits](https://devkits-tools.surge.sh)**
|
|
42
122
|
|
|
43
123
|
## License
|
|
44
124
|
|
|
45
|
-
MIT
|
|
125
|
+
MIT
|
package/index.js
CHANGED
|
@@ -1,93 +1,177 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* @devkits/json-formatter
|
|
2
|
+
* @devkits/json-formatter
|
|
5
3
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* echo '{"foo":"bar"}' | jsonfmt
|
|
9
|
-
* jsonfmt package.json
|
|
4
|
+
* Format, validate, and minify JSON.
|
|
5
|
+
* Works in both Node.js and browser environments.
|
|
10
6
|
*/
|
|
11
7
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
jsonfmt <file|json> [--minify]
|
|
22
|
-
jsonfmt package.json
|
|
23
|
-
jsonfmt '{"foo":"bar"}'
|
|
24
|
-
echo '{"test":true}' | jsonfmt
|
|
25
|
-
|
|
26
|
-
Options:
|
|
27
|
-
--minify, -m Minify JSON (remove whitespace)
|
|
28
|
-
--help, -h Show this help
|
|
29
|
-
|
|
30
|
-
Examples:
|
|
31
|
-
jsonfmt package.json
|
|
32
|
-
jsonfmt '{"foo":"bar"}' --minify
|
|
33
|
-
cat data.json | jsonfmt
|
|
8
|
+
/**
|
|
9
|
+
* Format JSON string with indentation
|
|
10
|
+
* @param {string} jsonString - JSON string to format
|
|
11
|
+
* @param {Object} options - Format options
|
|
12
|
+
* @param {number} options.indent - Indentation spaces (default: 2)
|
|
13
|
+
* @returns {{success: boolean, result?: string, error?: string}}
|
|
14
|
+
*/
|
|
15
|
+
function format(jsonString, options = {}) {
|
|
16
|
+
const { indent = 2 } = options;
|
|
34
17
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
18
|
+
try {
|
|
19
|
+
const parsed = JSON.parse(jsonString);
|
|
20
|
+
return {
|
|
21
|
+
success: true,
|
|
22
|
+
result: JSON.stringify(parsed, null, indent)
|
|
23
|
+
};
|
|
24
|
+
} catch (e) {
|
|
25
|
+
return {
|
|
26
|
+
success: false,
|
|
27
|
+
error: e.message
|
|
28
|
+
};
|
|
29
|
+
}
|
|
38
30
|
}
|
|
39
31
|
|
|
40
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Minify JSON (remove all whitespace)
|
|
34
|
+
* @param {string} jsonString - JSON string to minify
|
|
35
|
+
* @returns {{success: boolean, result?: string, error?: string, saved?: number}}
|
|
36
|
+
*/
|
|
37
|
+
function minify(jsonString) {
|
|
41
38
|
try {
|
|
42
|
-
|
|
39
|
+
const parsed = JSON.parse(jsonString);
|
|
40
|
+
const minified = JSON.stringify(parsed);
|
|
41
|
+
return {
|
|
42
|
+
success: true,
|
|
43
|
+
result: minified,
|
|
44
|
+
saved: jsonString.length - minified.length
|
|
45
|
+
};
|
|
46
|
+
} catch (e) {
|
|
47
|
+
return {
|
|
48
|
+
success: false,
|
|
49
|
+
error: e.message
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Validate JSON syntax
|
|
56
|
+
* @param {string} jsonString - JSON string to validate
|
|
57
|
+
* @returns {{valid: boolean, error?: string, position?: {line: number, column: number}}}
|
|
58
|
+
*/
|
|
59
|
+
function isValid(jsonString) {
|
|
60
|
+
try {
|
|
61
|
+
JSON.parse(jsonString);
|
|
62
|
+
return { valid: true };
|
|
63
|
+
} catch (e) {
|
|
64
|
+
// Try to extract position from error message
|
|
65
|
+
const posMatch = e.message.match(/position\s+(\d+)/i);
|
|
66
|
+
let position = null;
|
|
67
|
+
|
|
68
|
+
if (posMatch) {
|
|
69
|
+
const pos = parseInt(posMatch[1], 10);
|
|
70
|
+
const lines = jsonString.substring(0, pos).split('\n');
|
|
71
|
+
position = {
|
|
72
|
+
line: lines.length,
|
|
73
|
+
column: lines[lines.length - 1].length + 1
|
|
74
|
+
};
|
|
47
75
|
}
|
|
48
76
|
|
|
49
|
-
|
|
77
|
+
return {
|
|
78
|
+
valid: false,
|
|
79
|
+
error: e.message,
|
|
80
|
+
position
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
50
84
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Pretty print a JavaScript object as JSON
|
|
87
|
+
* @param {any} obj - Object to pretty print
|
|
88
|
+
* @param {number} [indent=2] - Indentation spaces
|
|
89
|
+
* @returns {string} Formatted JSON string
|
|
90
|
+
*/
|
|
91
|
+
function pretty(obj, indent = 2) {
|
|
92
|
+
return JSON.stringify(obj, null, indent);
|
|
93
|
+
}
|
|
57
94
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Count keys in a JSON object recursively
|
|
97
|
+
* @param {any} obj - Object to count keys in
|
|
98
|
+
* @returns {number} Total key count
|
|
99
|
+
*/
|
|
100
|
+
function countKeys(obj) {
|
|
101
|
+
if (typeof obj !== 'object' || obj === null) return 0;
|
|
102
|
+
if (Array.isArray(obj)) {
|
|
103
|
+
return obj.reduce((n, v) => n + countKeys(v), 0);
|
|
61
104
|
}
|
|
105
|
+
return Object.keys(obj).reduce((n, k) => n + 1 + countKeys(obj[k]), 0);
|
|
62
106
|
}
|
|
63
107
|
|
|
64
|
-
|
|
65
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Get JSON size info
|
|
110
|
+
* @param {string} jsonString - JSON string
|
|
111
|
+
* @returns {{original: number, minified?: number, saved?: number, keys?: number}}
|
|
112
|
+
*/
|
|
113
|
+
function getSizeInfo(jsonString) {
|
|
114
|
+
const info = { original: jsonString.length };
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const parsed = JSON.parse(jsonString);
|
|
118
|
+
info.keys = countKeys(parsed);
|
|
119
|
+
|
|
120
|
+
const minified = JSON.stringify(parsed);
|
|
121
|
+
info.minified = minified.length;
|
|
122
|
+
info.saved = jsonString.length - minified.length;
|
|
123
|
+
} catch (e) {
|
|
124
|
+
// Invalid JSON
|
|
125
|
+
}
|
|
66
126
|
|
|
67
|
-
|
|
68
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
69
|
-
showHelp();
|
|
70
|
-
process.exit(0);
|
|
127
|
+
return info;
|
|
71
128
|
}
|
|
72
129
|
|
|
73
|
-
|
|
74
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Sort object keys alphabetically
|
|
132
|
+
* @param {any} obj - Object to sort
|
|
133
|
+
* @returns {any} Object with sorted keys
|
|
134
|
+
*/
|
|
135
|
+
function sortKeys(obj) {
|
|
136
|
+
if (obj === null || typeof obj !== 'object') return obj;
|
|
137
|
+
if (Array.isArray(obj)) return obj.map(sortKeys);
|
|
138
|
+
|
|
139
|
+
const sorted = {};
|
|
140
|
+
Object.keys(obj).sort().forEach(key => {
|
|
141
|
+
sorted[key] = sortKeys(obj[key]);
|
|
142
|
+
});
|
|
143
|
+
return sorted;
|
|
144
|
+
}
|
|
75
145
|
|
|
76
|
-
|
|
77
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Format with sorted keys
|
|
148
|
+
* @param {string} jsonString - JSON string
|
|
149
|
+
* @param {number} [indent=2] - Indentation spaces
|
|
150
|
+
* @returns {{success: boolean, result?: string, error?: string}}
|
|
151
|
+
*/
|
|
152
|
+
function formatSorted(jsonString, indent = 2) {
|
|
78
153
|
try {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
} catch (
|
|
86
|
-
|
|
87
|
-
|
|
154
|
+
const parsed = JSON.parse(jsonString);
|
|
155
|
+
const sorted = sortKeys(parsed);
|
|
156
|
+
return {
|
|
157
|
+
success: true,
|
|
158
|
+
result: JSON.stringify(sorted, null, indent)
|
|
159
|
+
};
|
|
160
|
+
} catch (e) {
|
|
161
|
+
return {
|
|
162
|
+
success: false,
|
|
163
|
+
error: e.message
|
|
164
|
+
};
|
|
88
165
|
}
|
|
89
|
-
} else {
|
|
90
|
-
formatJSON(input, minify);
|
|
91
166
|
}
|
|
92
167
|
|
|
93
|
-
|
|
168
|
+
module.exports = {
|
|
169
|
+
format,
|
|
170
|
+
minify,
|
|
171
|
+
isValid,
|
|
172
|
+
pretty,
|
|
173
|
+
countKeys,
|
|
174
|
+
getSizeInfo,
|
|
175
|
+
sortKeys,
|
|
176
|
+
formatSorted
|
|
177
|
+
};
|
package/package.json
CHANGED
|
@@ -1,40 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devkits-json-formatter",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Format and
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Format, validate, and minify JSON. Syntax error detection with position info. Zero-dependency JSON utility for developers.",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
"scripts": {
|
|
11
|
-
"test": "node test.js"
|
|
12
|
-
},
|
|
6
|
+
"files": [
|
|
7
|
+
"index.js",
|
|
8
|
+
"README.md"
|
|
9
|
+
],
|
|
13
10
|
"keywords": [
|
|
14
11
|
"json",
|
|
15
|
-
"formatter",
|
|
16
|
-
"validator",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"developer-tools"
|
|
12
|
+
"json-formatter",
|
|
13
|
+
"json-validator",
|
|
14
|
+
"json-minifier",
|
|
15
|
+
"json-beautifier",
|
|
16
|
+
"json-linter",
|
|
17
|
+
"developer-tools",
|
|
18
|
+
"devkits"
|
|
21
19
|
],
|
|
22
|
-
"author": "DevKits
|
|
20
|
+
"author": "DevKits Auto <devkits-auto@protonmail.com>",
|
|
23
21
|
"license": "MIT",
|
|
24
|
-
"repository":
|
|
25
|
-
"type": "git",
|
|
26
|
-
"url": "https://github.com/devkits/tools"
|
|
27
|
-
},
|
|
28
|
-
"homepage": "https://devkits-tools.surge.sh",
|
|
22
|
+
"repository": "",
|
|
29
23
|
"bugs": {
|
|
30
|
-
"url": "https://github.com/devkits/
|
|
31
|
-
},
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">=14.0.0"
|
|
24
|
+
"url": "https://github.com/devkits/devkits/issues"
|
|
34
25
|
},
|
|
35
|
-
"
|
|
36
|
-
"index.js",
|
|
37
|
-
"README.md"
|
|
38
|
-
],
|
|
39
|
-
"dependencies": {}
|
|
26
|
+
"homepage": "https://devkits-tools.surge.sh"
|
|
40
27
|
}
|