devkits-json-formatter 1.0.6 → 1.0.7
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 +147 -32
- package/index.js +153 -69
- package/package.json +20 -33
package/README.md
CHANGED
|
@@ -1,52 +1,167 @@
|
|
|
1
|
-
# devkits
|
|
1
|
+
# @devkits/json-formatter
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://aiforeverthing.com)
|
|
4
|
+
[](https://aiforeverthing.com/pro.html)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Format, validate, and minify JSON. Syntax error detection with position info. Zero-dependency JSON utility for developers.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
npm install -g devkits-json-formatter
|
|
9
|
-
```
|
|
8
|
+
## 💰 Support DevKits
|
|
10
9
|
|
|
11
|
-
[
|
|
10
|
+
Love these tools? Support development via [Open Collective](https://opencollective.com/devkits)
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
- **$5/mo** - Supporter (priority support)
|
|
13
|
+
- **$9/mo** - Pro (early access to new tools)
|
|
14
|
+
- **$29** - Lifetime (all current + future Pro features)
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
---
|
|
17
|
+
## 💎 Upgrade to DevKits Pro
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
# From stdin
|
|
19
|
-
echo '{"name":"DevKits","tools":84}' | jsonfmt
|
|
19
|
+
Get access to **20+ premium tools** including SQL to Code, Data Faker, JWT Generator, and more — all for **$9 one-time**.
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
jsonfmt package.json
|
|
21
|
+
**[→ Unlock DevKits Pro](https://aiforeverthing.com/pro.html)**
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
> 💡 **Pay with Crypto:** BTC, ETH, USDT (TRC-20), SOL accepted. [View crypto addresses](https://aiforeverthing.com/assets/crypto-payment-addresses.md)
|
|
24
|
+
|
|
25
|
+
## 🧰 DevKits Pro Tools
|
|
26
|
+
|
|
27
|
+
This package is part of **DevKits** — 82+ free developer tools. The online JSON Formatter includes schema validation, tree view, and query/filter tools.
|
|
28
|
+
|
|
29
|
+
**→ [Format JSON with Tree View](https://aiforeverthing.com)**
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
## Installation
|
|
29
32
|
|
|
30
33
|
```bash
|
|
31
|
-
|
|
32
|
-
jsonfmt '{"test":true}' -m
|
|
34
|
+
npm install @devkits/json-formatter
|
|
33
35
|
```
|
|
34
36
|
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
const {
|
|
41
|
+
format,
|
|
42
|
+
minify,
|
|
43
|
+
isValid,
|
|
44
|
+
pretty,
|
|
45
|
+
countKeys,
|
|
46
|
+
getSizeInfo,
|
|
47
|
+
sortKeys,
|
|
48
|
+
formatSorted
|
|
49
|
+
} = require('@devkits/json-formatter');
|
|
50
|
+
|
|
51
|
+
const uglyJson = '{"name":"John","age":30,"city":"NYC"}';
|
|
52
|
+
|
|
53
|
+
// Format JSON with indentation
|
|
54
|
+
const result = format(uglyJson, { indent: 2 });
|
|
55
|
+
// {
|
|
56
|
+
// success: true,
|
|
57
|
+
// result: '{\n "name": "John",\n "age": 30,\n "city": "NYC"\n}'
|
|
58
|
+
// }
|
|
59
|
+
|
|
60
|
+
// Minify JSON
|
|
61
|
+
const min = minify(uglyJson);
|
|
62
|
+
// { success: true, result: '{"name":"John",...}', saved: 15 }
|
|
63
|
+
|
|
64
|
+
// Validate JSON
|
|
65
|
+
isValid('{"valid": true}');
|
|
66
|
+
// { valid: true }
|
|
67
|
+
|
|
68
|
+
isValid('{invalid}');
|
|
69
|
+
// { valid: false, error: 'Unexpected token...', position: {line: 1, column: 2} }
|
|
70
|
+
|
|
71
|
+
// Pretty print an object
|
|
72
|
+
pretty({ name: 'John', age: 30 });
|
|
73
|
+
// '{\n "name": "John",\n "age": 30\n}'
|
|
74
|
+
|
|
75
|
+
// Count keys recursively
|
|
76
|
+
const nested = { a: { b: { c: 1 } }, d: [1, 2, 3] };
|
|
77
|
+
countKeys(nested);
|
|
78
|
+
// 5
|
|
79
|
+
|
|
80
|
+
// Get size info
|
|
81
|
+
getSizeInfo(uglyJson);
|
|
82
|
+
// { original: 36, minified: 36, saved: 0, keys: 3 }
|
|
83
|
+
|
|
84
|
+
// Sort keys alphabetically
|
|
85
|
+
const unsorted = { z: 1, a: 2, m: 3 };
|
|
86
|
+
sortKeys(unsorted);
|
|
87
|
+
// { a: 2, m: 3, z: 1 }
|
|
88
|
+
|
|
89
|
+
// Format with sorted keys
|
|
90
|
+
formatSorted('{"z":1,"a":2}', 2);
|
|
91
|
+
// { success: true, result: '{\n "a": 2,\n "z": 1\n}' }
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## API
|
|
95
|
+
|
|
96
|
+
### `format(jsonString, options)`
|
|
97
|
+
Formats JSON with specified indentation (default: 2 spaces).
|
|
98
|
+
|
|
99
|
+
Returns `{success, result?, error?}`.
|
|
100
|
+
|
|
101
|
+
### `minify(jsonString)`
|
|
102
|
+
Removes all whitespace from JSON.
|
|
103
|
+
|
|
104
|
+
Returns `{success, result?, error?, saved?}`.
|
|
105
|
+
|
|
106
|
+
### `isValid(jsonString)`
|
|
107
|
+
Validates JSON syntax with optional error position.
|
|
108
|
+
|
|
109
|
+
Returns `{valid, error?, position?}`.
|
|
110
|
+
|
|
111
|
+
### `pretty(obj, indent)`
|
|
112
|
+
Pretty prints a JavaScript object as JSON string.
|
|
113
|
+
|
|
114
|
+
### `countKeys(obj)`
|
|
115
|
+
Counts all keys in an object recursively.
|
|
116
|
+
|
|
117
|
+
### `getSizeInfo(jsonString)`
|
|
118
|
+
Returns size statistics: original size, minified size, bytes saved, key count.
|
|
119
|
+
|
|
120
|
+
### `sortKeys(obj)`
|
|
121
|
+
Returns new object with keys sorted alphabetically (recursive).
|
|
122
|
+
|
|
123
|
+
### `formatSorted(jsonString, indent)`
|
|
124
|
+
Formats JSON with keys sorted alphabetically.
|
|
35
125
|
|
|
36
126
|
## See Also
|
|
37
127
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
128
|
+
### 🔧 More DevKits Tools
|
|
129
|
+
|
|
130
|
+
**Free Tools (82+):**
|
|
131
|
+
| Tool | Description |
|
|
132
|
+
|------|-------------|
|
|
133
|
+
| [base64-tool](https://www.npmjs.com/package/@devkits/base64-tool) | Base64 encode/decode |
|
|
134
|
+
| [chmod-calculator](https://www.npmjs.com/package/@devkits/chmod-calculator) | Unix permissions converter |
|
|
135
|
+
| [cron-parser](https://www.npmjs.com/package/@devkits/cron-parser) | Cron expression parser |
|
|
136
|
+
| [csv-json-converter](https://www.npmjs.com/package/@devkits/csv-json-converter) | CSV ↔ JSON converter |
|
|
137
|
+
| [diff-checker](https://www.npmjs.com/package/@devkits/diff-checker) | Text comparison (LCS) |
|
|
138
|
+
|
|
139
|
+
**→ [Browse All 82+ Free Tools](https://aiforeverthing.com)**
|
|
140
|
+
|
|
141
|
+
### 💎 DevKits Pro — $9 One-Time
|
|
142
|
+
|
|
143
|
+
Unlock 20+ premium tools with a single payment:
|
|
144
|
+
|
|
145
|
+
- [SQL to Code](https://aiforeverthing.com/pro.html#sql-to-code)
|
|
146
|
+
- [Data Faker](https://aiforeverthing.com/pro.html#data-faker)
|
|
147
|
+
- [JWT Generator](https://aiforeverthing.com/pro.html#jwt-generator)
|
|
148
|
+
- [Crypto Hash](https://aiforeverthing.com/pro.html#crypto-hash)
|
|
149
|
+
- [URL Parser](https://aiforeverthing.com/pro.html#url-parser)
|
|
150
|
+
- [Color Converter](https://aiforeverthing.com/pro.html#color-converter)
|
|
151
|
+
- [Timestamp Tool](https://aiforeverthing.com/pro.html#timestamp-tool)
|
|
152
|
+
- [Slug Generator](https://aiforeverthing.com/pro.html#slug-generator)
|
|
153
|
+
|
|
154
|
+
**[→ Unlock DevKits Pro for $9](https://aiforeverthing.com/pro.html)**
|
|
155
|
+
|
|
156
|
+
> 💡 **Pay with Crypto:** BTC, ETH, USDT (TRC-20), SOL accepted
|
|
157
|
+
|
|
158
|
+
### 🚀 Other Products from Us
|
|
159
|
+
|
|
160
|
+
| Product | Description |
|
|
161
|
+
|---------|-------------|
|
|
162
|
+
| [Invoicely](https://invoicely-app.surge.sh) | Free invoice generator for freelancers |
|
|
163
|
+
| [SnapOG](https://snapog.surge.sh) | Free OG image generator (20+ templates) |
|
|
49
164
|
|
|
50
165
|
## License
|
|
51
166
|
|
|
52
|
-
MIT
|
|
167
|
+
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,44 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devkits-json-formatter",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Format and
|
|
3
|
+
"version": "1.0.7",
|
|
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
|
-
"devkits",
|
|
15
11
|
"json",
|
|
16
|
-
"formatter",
|
|
17
|
-
"validator",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
12
|
+
"json-formatter",
|
|
13
|
+
"json-validator",
|
|
14
|
+
"json-minifier",
|
|
15
|
+
"json-beautifier",
|
|
16
|
+
"json-linter",
|
|
21
17
|
"developer-tools",
|
|
22
|
-
"
|
|
23
|
-
"browser tools",
|
|
24
|
-
"free tools"
|
|
18
|
+
"devkits"
|
|
25
19
|
],
|
|
26
|
-
"author": "DevKits
|
|
20
|
+
"author": "DevKits Auto <devkits-auto@protonmail.com>",
|
|
27
21
|
"license": "MIT",
|
|
28
|
-
"repository":
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "https://github.com/devkits/tools"
|
|
31
|
-
},
|
|
32
|
-
"homepage": "https://devkits-tools.surge.sh",
|
|
22
|
+
"repository": "",
|
|
33
23
|
"bugs": {
|
|
34
|
-
"url": "https://github.com/devkits/
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=14.0.0"
|
|
24
|
+
"url": "https://github.com/devkits/devkits/issues"
|
|
38
25
|
},
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
26
|
+
"homepage": "https://devkits-tools.surge.sh",
|
|
27
|
+
"funding": {
|
|
28
|
+
"type": "opencollective",
|
|
29
|
+
"url": "https://opencollective.com/devkits"
|
|
30
|
+
}
|
|
44
31
|
}
|