@prantlf/jsonlint 10.1.1 → 11.1.0
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/LICENSE +1 -1
- package/README.md +37 -20
- package/lib/cli.js +38 -26
- package/lib/formatter.js +12 -10
- package/lib/jsonlint.d.ts +3 -0
- package/lib/jsonlint.js +134 -121
- package/lib/printer.js +53 -26
- package/lib/schema-drafts.js +6 -3
- package/lib/sorter.js +6 -6
- package/lib/validator.js +31 -31
- package/package.json +31 -17
- package/web/ajv.min.js +3 -1
- package/web/ajv.min.js.map +1 -1
- package/web/formatter.min.js +1 -1
- package/web/formatter.min.js.map +1 -1
- package/web/jsonlint.html +333 -0
- package/web/jsonlint.min.js +1 -1
- package/web/jsonlint.min.js.map +1 -1
- package/web/printer.min.js +1 -1
- package/web/printer.min.js.map +1 -1
- package/web/schema-drafts.min.js +1 -1
- package/web/schema-drafts.min.js.map +1 -1
- package/web/sorter.min.js +1 -1
- package/web/sorter.min.js.map +1 -1
- package/web/validator.min.js +1 -1
- package/web/validator.min.js.map +1 -1
- package/CHANGELOG.md +0 -264
package/LICENSE
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2012-2018 Zachary Carter
|
|
4
|
-
Copyright (c) 2019
|
|
4
|
+
Copyright (c) 2019-2022 Ferdinand Prantl
|
|
5
5
|
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
# JSON Lint
|
|
2
2
|
|
|
3
|
-
[](https://david-dm.org/prantlf/jsonlint#info=devDependencies)
|
|
8
|
-
[](https://standardjs.com)
|
|
3
|
+
[
|
|
4
|
+

|
|
5
|
+
](https://www.npmjs.com/package/@prantlf/jsonlint)
|
|
6
|
+
[](https://codecov.io/gh/prantlf/jsonlint)
|
|
9
7
|
|
|
10
|
-
A [JSON]/[JSON5] parser and
|
|
8
|
+
A [JSON]/CJSON/[JSON5] parser, validator and pretty-printer with a command-line client. See it in action at https://prantlf.github.io/jsonlint/.
|
|
11
9
|
|
|
12
|
-
This is a fork of the original
|
|
10
|
+
This is a fork of the original project ([zaach/jsonlint](https://github.com/zaach/jsonlint)) with the following enhancements:
|
|
13
11
|
|
|
14
12
|
* Handles multiple files on the command line (by Greg Inman).
|
|
15
13
|
* Walks directories recursively (by Paul Vollmer).
|
|
16
14
|
* Provides 100% compatible interface to the native `JSON.parse` method.
|
|
17
|
-
* Optionally recognizes JavaScript-style comments and single quoted strings.
|
|
15
|
+
* Optionally recognizes JavaScript-style comments (CJSON) and single quoted strings (JSON5).
|
|
18
16
|
* Optionally ignores trailing commas and reports duplicate object keys as an error.
|
|
19
17
|
* Supports [JSON Schema] drafts 04, 06 and 07.
|
|
20
18
|
* Offers pretty-printing including comment-stripping and object keys without quotes (JSON5).
|
|
@@ -30,6 +28,7 @@ Integration to the favourite task loaders for JSON file validation is provided b
|
|
|
30
28
|
|
|
31
29
|
* [`Grunt`] - see [`@prantlf/grunt-jsonlint`]
|
|
32
30
|
* [`Gulp`] - see [`@prantlf/gulp-jsonlint`]
|
|
31
|
+
* [`Rollup`] - see [`rollup-plugin-jsonlint`]
|
|
33
32
|
|
|
34
33
|
## Synopsis
|
|
35
34
|
|
|
@@ -100,9 +99,15 @@ By default, `jsonlint` will either report a syntax error with details or pretty-
|
|
|
100
99
|
-p, --pretty-print prettify the input instead of stringifying
|
|
101
100
|
the parsed object
|
|
102
101
|
-P, --pretty-print-invalid force pretty-printing even for invalid input
|
|
102
|
+
-r, --trailing-newline ensure a line break at the end of the output
|
|
103
103
|
--prune-comments omit comments from the prettified output
|
|
104
104
|
--strip-object-keys strip quotes from object keys if possible
|
|
105
105
|
(JSON5)
|
|
106
|
+
--enforce-double-quotes surrounds all strings with double quotes
|
|
107
|
+
--enforce-single-quotes surrounds all strings with single quotes
|
|
108
|
+
(JSON5)
|
|
109
|
+
--trim-trailing-commas omit trailing commas from objects and arrays
|
|
110
|
+
(JSON5)
|
|
106
111
|
-v, --version output the version number
|
|
107
112
|
-h, --help output usage information
|
|
108
113
|
|
|
@@ -184,7 +189,7 @@ const validate = compile('string with JSON schema', {
|
|
|
184
189
|
|
|
185
190
|
### Pretty-Printing
|
|
186
191
|
|
|
187
|
-
You can parse a JSON string to an array of tokens and print it back to a string with some changes applied. It can be unification of whitespace or
|
|
192
|
+
You can parse a JSON string to an array of tokens and print it back to a string with some changes applied. It can be unification of whitespace, reformatting or stripping comments, for example. (Raw token values must be enabled when tokenizing the JSON input.)
|
|
188
193
|
|
|
189
194
|
```js
|
|
190
195
|
const { tokenize } = require('@prantlf/jsonlint')
|
|
@@ -201,7 +206,10 @@ The [`print`](#pretty-printing) method accepts an object `options` as the second
|
|
|
201
206
|
| --------------------------- | ------------------------------------------------------- |
|
|
202
207
|
| `indent` | count of spaces or the specific characters to be used as an indentation unit |
|
|
203
208
|
| `pruneComments` | will omit all tokens with comments |
|
|
204
|
-
| `stripObjectKeys`
|
|
209
|
+
| `stripObjectKeys` | will not print quotes around object keys which are JavaScript identifier names |
|
|
210
|
+
| `enforceDoubleQuotes` | will surround all strings with double quotes |
|
|
211
|
+
| `enforceSingleQuotes` | will surround all strings with single quotes |
|
|
212
|
+
| `trimTrailingCommas` | will omit all trailing commas after the last object entry or array item |
|
|
205
213
|
|
|
206
214
|
```js
|
|
207
215
|
// Just concatenate the tokens to produce the same output as was the input.
|
|
@@ -220,6 +228,12 @@ print(tokens, { indent: 2 })
|
|
|
220
228
|
print(tokens, { indent: ' ', pruneComments: true })
|
|
221
229
|
// Print to multiple lines with indentation enabled and JSON5 object keys.
|
|
222
230
|
print(tokens, { indent: '\t', stripObjectKeys: true })
|
|
231
|
+
// Print to multiple lines with indentation enabled, unify JSON5 formatting.
|
|
232
|
+
print(tokens, {
|
|
233
|
+
indent: ' ',
|
|
234
|
+
enforceDoubleQuotes: true,
|
|
235
|
+
trimTrailingCommas: true
|
|
236
|
+
})
|
|
223
237
|
```
|
|
224
238
|
|
|
225
239
|
### Tokenizing
|
|
@@ -228,7 +242,10 @@ The method `tokenize` has the same prototype as the method [`parse`](#module-int
|
|
|
228
242
|
|
|
229
243
|
```js
|
|
230
244
|
const { tokenize } = require('@prantlf/jsonlint')
|
|
231
|
-
const tokens = tokenize('{"flag":true /* default */}', {
|
|
245
|
+
const tokens = tokenize('{"flag":true /* default */}', {
|
|
246
|
+
ignoreComments: true,
|
|
247
|
+
rawTokens: true
|
|
248
|
+
}))
|
|
232
249
|
// Returns the following array:
|
|
233
250
|
// [
|
|
234
251
|
// { type: 'symbol', raw: '{', value: '{' },
|
|
@@ -253,15 +270,13 @@ If you want to retain comments or whitespace for pretty-printing, for example, s
|
|
|
253
270
|
|
|
254
271
|
### Performance
|
|
255
272
|
|
|
256
|
-
This is a part of an output from the [parser benchmark], when parsing a 4.2 KB formatted string ([package.json](./package.json)) with Node.js
|
|
273
|
+
This is a part of an output from the [parser benchmark], when parsing a 4.2 KB formatted string ([package.json](./package.json)) with Node.js 12.14.0:
|
|
257
274
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
the tokenizable jju parser x 8,832 ops/sec ±0.92% (89 runs sampled)
|
|
262
|
-
the tokenizing jju parser x 7,911 ops/sec ±1.05% (86 runs sampled)
|
|
275
|
+
jsonlint using native JSON.parse x 97,109 ops/sec ±0.81% (93 runs sampled)
|
|
276
|
+
jsonlint using hand-coded parser x 7,256 ops/sec ±0.54% (90 runs sampled)
|
|
277
|
+
jsonlint using tokenising parser x 6,387 ops/sec ±0.44% (88 runs sampled)
|
|
263
278
|
|
|
264
|
-
A custom JSON parser is [a lot slower] than the built-in one. However, it is more important to have a [clear error reporting] than the highest speed in scenarios like parsing configuration files.
|
|
279
|
+
A custom JSON parser is [a lot slower] than the built-in one. However, it is more important to have a [clear error reporting] than the highest speed in scenarios like parsing configuration files. (For better error-reporting, the speed can be preserved by using the native parser initially and re-parsing with another parser only in case of failure.) Features like comments or JSON5 are also helpful in configuration files. Tokens preserve the complete input and can be used for pretty-printing without losing the comments.
|
|
265
280
|
|
|
266
281
|
### Error Handling
|
|
267
282
|
|
|
@@ -303,7 +318,7 @@ ${reason}`)
|
|
|
303
318
|
|
|
304
319
|
## License
|
|
305
320
|
|
|
306
|
-
Copyright (C) 2012-
|
|
321
|
+
Copyright (C) 2012-2022 Zachary Carter, Ferdinand Prantl
|
|
307
322
|
|
|
308
323
|
Licensed under the [MIT License].
|
|
309
324
|
|
|
@@ -316,8 +331,10 @@ Licensed under the [MIT License].
|
|
|
316
331
|
[UMD]: https://github.com/umdjs/umd
|
|
317
332
|
[`Grunt`]: https://gruntjs.com/
|
|
318
333
|
[`Gulp`]: http://gulpjs.com/
|
|
334
|
+
[`Rollup`]: https://rollupjs.org/
|
|
319
335
|
[`@prantlf/grunt-jsonlint`]: https://www.npmjs.com/package/@prantlf/grunt-jsonlint
|
|
320
336
|
[`@prantlf/gulp-jsonlint`]: https://www.npmjs.com/package/@prantlf/gulp-jsonlint
|
|
337
|
+
[`rollup-plugin-jsonlint`]: https://www.npmjs.com/package/rollup-plugin-jsonlint
|
|
321
338
|
[7x faster than the custom parser]: ./benchmarks/results/performance.md#results
|
|
322
339
|
[parser benchmark]: ./benchmarks#json-parser-comparison
|
|
323
340
|
[a lot slower]: ./benchmarks/results/performance.md#results
|
package/lib/cli.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const parser = require('./jsonlint')
|
|
6
|
+
const formatter = require('./formatter')
|
|
7
|
+
const printer = require('./printer')
|
|
8
|
+
const sorter = require('./sorter')
|
|
9
|
+
const validator = require('./validator')
|
|
10
|
+
const pkg = require('../package')
|
|
11
11
|
|
|
12
12
|
function collectExtensions (extension) {
|
|
13
13
|
return extension.split(',')
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
const commander = require('commander')
|
|
17
17
|
.name('jsonlint')
|
|
18
18
|
.usage('[options] [<file or directory> ...]')
|
|
19
19
|
.description(pkg.description)
|
|
@@ -32,8 +32,12 @@ var options = require('commander')
|
|
|
32
32
|
.option('-q, --quiet', 'do not print the parsed json to stdin')
|
|
33
33
|
.option('-p, --pretty-print', 'prettify the input instead of stringifying the parsed object')
|
|
34
34
|
.option('-P, --pretty-print-invalid', 'force pretty-printing even for invalid input')
|
|
35
|
+
.option('-r, --trailing-newline', 'ensure a line break at the end of the output')
|
|
35
36
|
.option('--prune-comments', 'omit comments from the prettified output')
|
|
36
37
|
.option('--strip-object-keys', 'strip quotes from object keys if possible (JSON5)')
|
|
38
|
+
.option('--enforce-double-quotes', 'surrounds all strings with double quotes')
|
|
39
|
+
.option('--enforce-single-quotes', 'surrounds all strings with single quotes (JSON5)')
|
|
40
|
+
.option('--trim-trailing-commas', 'omit trailing commas from objects and arrays (JSON5)')
|
|
37
41
|
.version(pkg.version, '-v, --version')
|
|
38
42
|
.on('--help', () => {
|
|
39
43
|
console.log()
|
|
@@ -44,6 +48,8 @@ var options = require('commander')
|
|
|
44
48
|
})
|
|
45
49
|
.parse(process.argv)
|
|
46
50
|
|
|
51
|
+
const options = commander.opts()
|
|
52
|
+
|
|
47
53
|
function logNormalError (error, file) {
|
|
48
54
|
console.log('File:', file)
|
|
49
55
|
console.error(error.message)
|
|
@@ -55,7 +61,7 @@ function logCompactError (error, file) {
|
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
function parse (source, file) {
|
|
58
|
-
|
|
64
|
+
let parserOptions, parsed, formatted
|
|
59
65
|
try {
|
|
60
66
|
parserOptions = {
|
|
61
67
|
mode: options.mode,
|
|
@@ -65,13 +71,13 @@ function parse (source, file) {
|
|
|
65
71
|
allowDuplicateObjectKeys: options.duplicateKeys
|
|
66
72
|
}
|
|
67
73
|
if (options.validate) {
|
|
68
|
-
|
|
74
|
+
let validate
|
|
69
75
|
try {
|
|
70
|
-
|
|
76
|
+
const schema = fs.readFileSync(path.normalize(options.validate), 'utf8')
|
|
71
77
|
parserOptions.environment = options.environment
|
|
72
78
|
validate = validator.compile(schema, parserOptions)
|
|
73
79
|
} catch (error) {
|
|
74
|
-
|
|
80
|
+
const message = 'Loading the JSON schema failed: "' +
|
|
75
81
|
options.validate + '".\n' + error.message
|
|
76
82
|
throw new Error(message)
|
|
77
83
|
}
|
|
@@ -81,12 +87,15 @@ function parse (source, file) {
|
|
|
81
87
|
}
|
|
82
88
|
if (options.prettyPrint) {
|
|
83
89
|
parserOptions.rawTokens = true
|
|
84
|
-
|
|
90
|
+
const tokens = parser.tokenize(source, parserOptions)
|
|
85
91
|
// TODO: Support sorting tor the tokenized input too.
|
|
86
92
|
return printer.print(tokens, {
|
|
87
93
|
indent: options.indent,
|
|
88
94
|
pruneComments: options.pruneComments,
|
|
89
|
-
stripObjectKeys: options.stripObjectKeys
|
|
95
|
+
stripObjectKeys: options.stripObjectKeys,
|
|
96
|
+
enforceDoubleQuotes: options.enforceDoubleQuotes,
|
|
97
|
+
enforceSingleQuotes: options.enforceSingleQuotes,
|
|
98
|
+
trimTrailingCommas: options.trimTrailingCommas
|
|
90
99
|
})
|
|
91
100
|
}
|
|
92
101
|
if (options.sortKeys) {
|
|
@@ -126,8 +135,11 @@ function parse (source, file) {
|
|
|
126
135
|
|
|
127
136
|
function processFile (file) {
|
|
128
137
|
file = path.normalize(file)
|
|
129
|
-
|
|
138
|
+
let source = parse(fs.readFileSync(file, 'utf8'), file)
|
|
130
139
|
if (options.inPlace) {
|
|
140
|
+
if (options.trailingNewline) {
|
|
141
|
+
source += '\n'
|
|
142
|
+
}
|
|
131
143
|
fs.writeFileSync(file, source)
|
|
132
144
|
} else {
|
|
133
145
|
if (!options.quiet) {
|
|
@@ -137,23 +149,23 @@ function processFile (file) {
|
|
|
137
149
|
}
|
|
138
150
|
|
|
139
151
|
function processSources (src, checkExtension) {
|
|
140
|
-
|
|
152
|
+
const extensions = options.extensions.map(function (extension) {
|
|
141
153
|
return '.' + extension
|
|
142
154
|
})
|
|
143
|
-
|
|
155
|
+
let srcStat
|
|
144
156
|
try {
|
|
145
157
|
srcStat = fs.statSync(src)
|
|
146
158
|
if (srcStat.isFile()) {
|
|
147
159
|
if (checkExtension) {
|
|
148
|
-
|
|
160
|
+
const ext = path.extname(src)
|
|
149
161
|
if (extensions.indexOf(ext) < 0) {
|
|
150
162
|
return
|
|
151
163
|
}
|
|
152
164
|
}
|
|
153
165
|
processFile(src)
|
|
154
166
|
} else if (srcStat.isDirectory()) {
|
|
155
|
-
|
|
156
|
-
for (
|
|
167
|
+
const sources = fs.readdirSync(src)
|
|
168
|
+
for (let i = 0; i < sources.length; i++) {
|
|
157
169
|
processSources(path.join(src, sources[i]), true)
|
|
158
170
|
}
|
|
159
171
|
}
|
|
@@ -163,20 +175,20 @@ function processSources (src, checkExtension) {
|
|
|
163
175
|
}
|
|
164
176
|
|
|
165
177
|
function main () {
|
|
166
|
-
|
|
167
|
-
|
|
178
|
+
const files = commander.args
|
|
179
|
+
let source = ''
|
|
168
180
|
if (files.length) {
|
|
169
|
-
for (
|
|
181
|
+
for (let i = 0; i < files.length; i++) {
|
|
170
182
|
processSources(files[i], false)
|
|
171
183
|
}
|
|
172
184
|
} else {
|
|
173
|
-
|
|
185
|
+
const stdin = process.openStdin()
|
|
174
186
|
stdin.setEncoding('utf8')
|
|
175
187
|
stdin.on('data', function (chunk) {
|
|
176
188
|
source += chunk.toString('utf8')
|
|
177
189
|
})
|
|
178
190
|
stdin.on('end', function () {
|
|
179
|
-
|
|
191
|
+
const parsed = parse(source, '<stdin>')
|
|
180
192
|
if (!options.quiet) {
|
|
181
193
|
console.log(parsed)
|
|
182
194
|
}
|
package/lib/formatter.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
// eslint-disable-next-line no-unused-expressions
|
|
2
|
+
// eslint-disable-next-line no-unused-expressions, multiline-ternary
|
|
3
3
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports)
|
|
4
|
-
// eslint-disable-next-line no-undef
|
|
4
|
+
// eslint-disable-next-line no-undef, multiline-ternary
|
|
5
5
|
: typeof define === 'function' && define.amd ? define('jsonlint-formatter', ['exports'], factory)
|
|
6
6
|
// eslint-disable-next-line no-undef
|
|
7
7
|
: (global = global || self, factory(global.jsonlintFormatter = {}))
|
|
@@ -21,15 +21,17 @@
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function format (json, indent) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
let i = 0
|
|
25
|
+
let length = 0
|
|
26
|
+
const indentString = indent !== undefined
|
|
27
27
|
? typeof indent === 'number'
|
|
28
|
-
? new Array(indent + 1).join(' ')
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
? new Array(indent + 1).join(' ')
|
|
29
|
+
: indent
|
|
30
|
+
: ' '
|
|
31
|
+
let outputString = ''
|
|
32
|
+
let indentLevel = 0
|
|
33
|
+
let inString
|
|
34
|
+
let currentChar
|
|
33
35
|
|
|
34
36
|
for (i = 0, length = json.length; i < length; i += 1) {
|
|
35
37
|
currentChar = json.charAt(i)
|
package/lib/jsonlint.d.ts
CHANGED