@prantlf/jsonlint 13.1.0 → 14.0.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/CHANGELOG.md +16 -0
- package/README.md +16 -10
- package/lib/cli.js +268 -119
- package/package.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
# [14.0.0](https://github.com/prantlf/jsonlint/compare/v13.1.0...v14.0.0) (2023-03-05)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Replace commander with hand-written command-line parser ([af0ea29](https://github.com/prantlf/jsonlint/commit/af0ea29c3f39ea713fc0bd72829678067a6c1fc0))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* Although you shouldn't notice any change on the behaviour of the command line, something unexpected might've changed. Something did change
|
|
12
|
+
- if you're annoyed by inserting "--" between the multi-value option and other
|
|
13
|
+
arguments, you don't have to do it any more. Multi-value options can be entered
|
|
14
|
+
either using the option prefix multiple times for each value, or using
|
|
15
|
+
the option prefix just once and separating the values by commas.
|
|
16
|
+
|
|
1
17
|
# [13.1.0](https://github.com/prantlf/jsonlint/compare/v13.0.1...v13.1.0) (2023-03-05)
|
|
2
18
|
|
|
3
19
|
|
package/README.md
CHANGED
|
@@ -121,33 +121,39 @@ Usage: `jsonlint [options] [--] [<file, directory, pattern> ...]`
|
|
|
121
121
|
-f, --config <file> read options from a custom configuration file
|
|
122
122
|
-F, --no-config disable searching for configuration files
|
|
123
123
|
-s, --sort-keys sort object keys (not when prettifying)
|
|
124
|
-
-E, --extensions <ext...> file extensions to process for directory walk
|
|
124
|
+
-E, --extensions <ext...> file extensions to process for directory walk
|
|
125
|
+
(default: json, JSON)
|
|
125
126
|
-i, --in-place overwrite the input files
|
|
126
127
|
-j, --diff print difference instead of writing the output
|
|
127
128
|
-k, --check check that the input is equal to the output
|
|
128
|
-
-t, --indent <num|char> number of spaces or specific characters to use
|
|
129
|
+
-t, --indent <num|char> number of spaces or specific characters to use
|
|
130
|
+
for indentation or a string with whitespace
|
|
129
131
|
-c, --compact compact error display
|
|
130
|
-
-M, --mode <mode> set other parsing flags according to
|
|
132
|
+
-M, --mode <mode> set other parsing flags according to the format
|
|
133
|
+
of the input data (default: json)
|
|
131
134
|
-B, --bom ignore the leading UTF-8 byte-order mark
|
|
132
135
|
-C, --comments recognize and ignore JavaScript-style comments
|
|
133
136
|
-S, --single-quoted-strings support single quotes as string delimiters
|
|
134
137
|
-T, --trailing-commas ignore trailing commas in objects and arrays
|
|
135
138
|
-D, --no-duplicate-keys report duplicate object keys as an error
|
|
136
|
-
-V, --validate <file...> JSON Schema file(s) to use for validation
|
|
137
|
-
-e, --environment <env> which
|
|
138
|
-
|
|
139
|
+
-V, --validate <file...> JSON Schema file(s) to use for validation
|
|
140
|
+
-e, --environment <env> which version of JSON Schema the validation
|
|
141
|
+
should use
|
|
142
|
+
-x, --context <num> line number used as the diff context
|
|
143
|
+
(default: 3)
|
|
139
144
|
-l, --log-files print only the parsed file names to stdout
|
|
140
145
|
-q, --quiet do not print the parsed json to stdout
|
|
141
146
|
-n, --continue continue with other files if an error occurs
|
|
142
|
-
-p, --pretty-print prettify the input instead of stringifying
|
|
147
|
+
-p, --pretty-print prettify the input instead of stringifying
|
|
148
|
+
the parsed object
|
|
143
149
|
-P, --pretty-print-invalid force pretty-printing even for invalid input
|
|
144
150
|
-r, --trailing-newline ensure a line break at the end of the output
|
|
145
151
|
-R, --no-trailing-newline ensure no line break at the end of the output
|
|
146
152
|
--prune-comments omit comments from the prettified output
|
|
147
|
-
--strip-object-keys strip quotes from object keys if possible
|
|
153
|
+
--strip-object-keys strip quotes from object keys if possible
|
|
148
154
|
--enforce-double-quotes surrounds all strings with double quotes
|
|
149
|
-
--enforce-single-quotes surrounds all strings with single quotes
|
|
150
|
-
--trim-trailing-commas omit trailing commas from objects and arrays
|
|
155
|
+
--enforce-single-quotes surrounds all strings with single quotes
|
|
156
|
+
--trim-trailing-commas omit trailing commas from objects and arrays
|
|
151
157
|
-v, --version output the version number
|
|
152
158
|
-h, --help display help for command
|
|
153
159
|
|
package/lib/cli.js
CHANGED
|
@@ -1,69 +1,219 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { readdirSync, readFileSync, statSync, writeFileSync } = require('fs')
|
|
4
|
-
const { extname, join
|
|
4
|
+
const { extname, join } = require('path')
|
|
5
5
|
const { isDynamicPattern, sync } = require('fast-glob')
|
|
6
6
|
const { parse, tokenize } = require('./jsonlint')
|
|
7
7
|
const { format } = require('./formatter')
|
|
8
8
|
const { print } = require('./printer')
|
|
9
9
|
const { sortObject } = require('./sorter')
|
|
10
10
|
const { compile } = require('./validator')
|
|
11
|
-
const { description, version } = require('../package')
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
function help() {
|
|
13
|
+
console.log(`${require('../package.json').description}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
15
|
+
Usage: jsonlint [options] [--] [<file, directory, pattern> ...]
|
|
16
|
+
|
|
17
|
+
Options:
|
|
18
|
+
-f, --config <file> read options from a custom configuration file
|
|
19
|
+
-F, --no-config disable searching for configuration files
|
|
20
|
+
-s, --sort-keys sort object keys (not when prettifying)
|
|
21
|
+
-E, --extensions <ext...> file extensions to process for directory walk
|
|
22
|
+
(default: json, JSON)
|
|
23
|
+
-i, --in-place overwrite the input files
|
|
24
|
+
-j, --diff print difference instead of writing the output
|
|
25
|
+
-k, --check check that the input is equal to the output
|
|
26
|
+
-t, --indent <num|char> number of spaces or specific characters to use
|
|
27
|
+
for indentation or a string with whitespace
|
|
28
|
+
-c, --compact compact error display
|
|
29
|
+
-M, --mode <mode> set other parsing flags according to the format
|
|
30
|
+
of the input data (default: json)
|
|
31
|
+
-B, --bom ignore the leading UTF-8 byte-order mark
|
|
32
|
+
-C, --comments recognize and ignore JavaScript-style comments
|
|
33
|
+
-S, --single-quoted-strings support single quotes as string delimiters
|
|
34
|
+
-T, --trailing-commas ignore trailing commas in objects and arrays
|
|
35
|
+
-D, --no-duplicate-keys report duplicate object keys as an error
|
|
36
|
+
-V, --validate <file...> JSON Schema file(s) to use for validation
|
|
37
|
+
-e, --environment <env> which version of JSON Schema the validation
|
|
38
|
+
should use
|
|
39
|
+
-x, --context <num> line number used as the diff context
|
|
40
|
+
(default: 3)
|
|
41
|
+
-l, --log-files print only the parsed file names to stdout
|
|
42
|
+
-q, --quiet do not print the parsed json to stdout
|
|
43
|
+
-n, --continue continue with other files if an error occurs
|
|
44
|
+
-p, --pretty-print prettify the input instead of stringifying
|
|
45
|
+
the parsed object
|
|
46
|
+
-P, --pretty-print-invalid force pretty-printing even for invalid input
|
|
47
|
+
-r, --trailing-newline ensure a line break at the end of the output
|
|
48
|
+
-R, --no-trailing-newline ensure no line break at the end of the output
|
|
49
|
+
--prune-comments omit comments from the prettified output
|
|
50
|
+
--strip-object-keys strip quotes from object keys if possible
|
|
51
|
+
--enforce-double-quotes surrounds all strings with double quotes
|
|
52
|
+
--enforce-single-quotes surrounds all strings with single quotes
|
|
53
|
+
--trim-trailing-commas omit trailing commas from objects and arrays
|
|
54
|
+
-v, --version output the version number
|
|
55
|
+
-h, --help display help for command
|
|
56
|
+
|
|
57
|
+
Examples:
|
|
58
|
+
$ jsonlint myfile.json
|
|
59
|
+
$ jsonlint --in-place --pretty-print mydir
|
|
60
|
+
$ jsonlint --comments --trailing-commas --no-duplicate-keys \\
|
|
61
|
+
--log-files --compact --continue '**/*.json' '!**/node_modules'`)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const { argv } = process
|
|
65
|
+
let params = { extensions: [], validate: [] }
|
|
66
|
+
const args = []
|
|
67
|
+
|
|
68
|
+
function fail(message) {
|
|
69
|
+
console.error(message)
|
|
70
|
+
process.exit(1)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for (let i = 2, l = argv.length; i < l; ++i) {
|
|
74
|
+
const arg = argv[i]
|
|
75
|
+
const match = /^(-|--)(no-)?([a-zA-Z][-a-zA-Z]*)(?:=(.*))?$/.exec(arg)
|
|
76
|
+
if (match) {
|
|
77
|
+
const parseArg = (arg, flag) => {
|
|
78
|
+
switch (arg) {
|
|
79
|
+
case 'f': case 'config':
|
|
80
|
+
params.config = flag ? match[4] || argv[++i] : false
|
|
81
|
+
return
|
|
82
|
+
case 'F':
|
|
83
|
+
params.config = false
|
|
84
|
+
return
|
|
85
|
+
case 's': case 'sort-keys':
|
|
86
|
+
params.sortKeys = flag
|
|
87
|
+
return
|
|
88
|
+
case 'E': case 'extensions':
|
|
89
|
+
arg = match[4] || argv[++i]
|
|
90
|
+
params.extensions.push(...arg.split(','))
|
|
91
|
+
return
|
|
92
|
+
case 'i': case 'in-place':
|
|
93
|
+
params.inPlace = flag
|
|
94
|
+
return
|
|
95
|
+
case 'j': case 'diff':
|
|
96
|
+
params.diff = flag
|
|
97
|
+
return
|
|
98
|
+
case 'k': case 'check':
|
|
99
|
+
params.check = flag
|
|
100
|
+
return
|
|
101
|
+
case 't': case 'indent':
|
|
102
|
+
arg = match[4] || argv[++i]
|
|
103
|
+
if (arg.trim().length > 0 && !isNaN(+arg)) arg = +arg
|
|
104
|
+
params.indent = arg
|
|
105
|
+
return
|
|
106
|
+
case 'c': case 'compact':
|
|
107
|
+
params.compact = flag
|
|
108
|
+
return
|
|
109
|
+
case 'M': case 'mode':
|
|
110
|
+
arg = match[4] || argv[++i]
|
|
111
|
+
if (arg !== 'json' && arg !== 'cjson' && arg !== 'json5') {
|
|
112
|
+
throw new Error(`invalid parsing mode: "${arg}"`)
|
|
113
|
+
}
|
|
114
|
+
params.mode = arg
|
|
115
|
+
return
|
|
116
|
+
case 'B': case 'bom':
|
|
117
|
+
params.bom = flag
|
|
118
|
+
return
|
|
119
|
+
case 'C': case 'comments':
|
|
120
|
+
params.comments = flag
|
|
121
|
+
return
|
|
122
|
+
case 'S': case 'single-quoted-strings':
|
|
123
|
+
params.singleQuotedStrings = flag
|
|
124
|
+
return
|
|
125
|
+
case 'T': case 'trailing-commas':
|
|
126
|
+
params.trailingCommas = flag
|
|
127
|
+
return
|
|
128
|
+
case 'duplicate-keys':
|
|
129
|
+
params.duplicateKeys = flag
|
|
130
|
+
return
|
|
131
|
+
case 'D':
|
|
132
|
+
params.duplicateKeys = false
|
|
133
|
+
return
|
|
134
|
+
case 'V': case 'validate':
|
|
135
|
+
arg = match[4] || argv[++i]
|
|
136
|
+
params.validate.push(...arg.split(','))
|
|
137
|
+
return
|
|
138
|
+
case 'e': case 'environment':
|
|
139
|
+
arg = match[4] || argv[++i]
|
|
140
|
+
if (arg !== 'json-schema-draft-04' && arg !== 'draft-04' &&
|
|
141
|
+
arg !== 'json-schema-draft-06' && arg !== 'draft-06' &&
|
|
142
|
+
arg !== 'json-schema-draft-07' && arg !== 'draft-07' &&
|
|
143
|
+
arg !== 'json-schema-draft-2019-09' && arg !== 'draft-2019-09' &&
|
|
144
|
+
arg !== 'json-schema-draft-2020-12' && arg !== 'draft-2020-12' &&
|
|
145
|
+
arg !== 'json-type-definition' && arg !== 'jtd' && arg !== 'rfc8927') {
|
|
146
|
+
throw new Error(`invalid validation environment "${arg}"`)
|
|
147
|
+
}
|
|
148
|
+
params.environment = arg
|
|
149
|
+
return
|
|
150
|
+
case 'x': case 'context':
|
|
151
|
+
arg = match[4] || argv[++i]
|
|
152
|
+
if (isNaN(+arg)) {
|
|
153
|
+
throw new Error(`invalid diff context: "${arg}"`)
|
|
154
|
+
}
|
|
155
|
+
params.indent = +arg
|
|
156
|
+
return
|
|
157
|
+
case 'l': case 'log-files':
|
|
158
|
+
params.logFiles = flag
|
|
159
|
+
return
|
|
160
|
+
case 'q': case 'quiet':
|
|
161
|
+
params.quiet = flag
|
|
162
|
+
return
|
|
163
|
+
case 'n': case 'continue':
|
|
164
|
+
params.continue = flag
|
|
165
|
+
return
|
|
166
|
+
case 'p': case 'pretty-print':
|
|
167
|
+
params.prettyPrint = flag
|
|
168
|
+
return
|
|
169
|
+
case 'P': case 'pretty-print-invalid':
|
|
170
|
+
params.prettyPrintInvalid = flag
|
|
171
|
+
return
|
|
172
|
+
case 'r': case 'trailing-newline':
|
|
173
|
+
params.trailingNewline = flag
|
|
174
|
+
return
|
|
175
|
+
case 'R':
|
|
176
|
+
params.trailingNewline = false
|
|
177
|
+
return
|
|
178
|
+
case 'prune-comments':
|
|
179
|
+
params.pruneComments = flag
|
|
180
|
+
return
|
|
181
|
+
case 'strip-object-keys':
|
|
182
|
+
params.stripObjectKeys = flag
|
|
183
|
+
return
|
|
184
|
+
case 'enforce-double-quotes':
|
|
185
|
+
params.enforceDoubleQuotes = flag
|
|
186
|
+
return
|
|
187
|
+
case 'enforce-single-quotes':
|
|
188
|
+
params.enforceSingleQuotes = flag
|
|
189
|
+
return
|
|
190
|
+
case 'trim-trailing-commas':
|
|
191
|
+
params.trimTrailingCommas = flag
|
|
192
|
+
return
|
|
193
|
+
case 'v': case 'version':
|
|
194
|
+
console.log(require('../package.json').version)
|
|
195
|
+
process.exit(0)
|
|
196
|
+
break
|
|
197
|
+
case 'h': case 'help':
|
|
198
|
+
help()
|
|
199
|
+
process.exit(0)
|
|
200
|
+
}
|
|
201
|
+
fail(`unknown option: "${arg}"`)
|
|
202
|
+
}
|
|
203
|
+
if (match[1] === '-') {
|
|
204
|
+
const flags = match[3].split('')
|
|
205
|
+
for (const flag of flags) parseArg(flag, true)
|
|
206
|
+
} else {
|
|
207
|
+
parseArg(match[3], match[2] !== 'no-')
|
|
208
|
+
}
|
|
209
|
+
continue
|
|
210
|
+
}
|
|
211
|
+
if (arg === '--') {
|
|
212
|
+
args.push(...argv.slice(i + 1, l))
|
|
213
|
+
break
|
|
214
|
+
}
|
|
215
|
+
args.push(arg)
|
|
216
|
+
}
|
|
67
217
|
|
|
68
218
|
const paramNames = {
|
|
69
219
|
'trailing-commas': 'trailingCommas',
|
|
@@ -82,19 +232,20 @@ const paramNames = {
|
|
|
82
232
|
'trailing-newline': 'trailingNewline'
|
|
83
233
|
}
|
|
84
234
|
|
|
85
|
-
|
|
86
|
-
let options
|
|
87
|
-
if (params.config === false) {
|
|
88
|
-
options = params
|
|
89
|
-
} else {
|
|
235
|
+
if (params.config !== false) {
|
|
90
236
|
const { cosmiconfigSync } = require('cosmiconfig')
|
|
91
237
|
const configurator = cosmiconfigSync('jsonlint')
|
|
92
238
|
const { config = {} } = (params.config && configurator.load(params.config)) ||
|
|
93
239
|
configurator.search() || {}
|
|
94
|
-
|
|
240
|
+
params = mergeOptions({}, convertConfig(config), params)
|
|
95
241
|
}
|
|
96
242
|
|
|
97
|
-
|
|
243
|
+
let extensions = params.extensions.map(extension => `.${extension}`)
|
|
244
|
+
if (!extensions.length) extensions = ['.json', '.JSON']
|
|
245
|
+
if (!params.mode) params.mode = 'json'
|
|
246
|
+
if (params.indent == null) params.indent = 2
|
|
247
|
+
if (params.context == null) params.context = 3
|
|
248
|
+
|
|
98
249
|
let reported
|
|
99
250
|
|
|
100
251
|
function convertConfig (config) {
|
|
@@ -109,7 +260,7 @@ function convertConfig (config) {
|
|
|
109
260
|
function mergeOptions (target, ...sources) {
|
|
110
261
|
for (const source of sources) {
|
|
111
262
|
for (const key in source) {
|
|
112
|
-
if (target[key] == null) {
|
|
263
|
+
if (target[key] == null || Array.isArray(target[key]) && !target[key].length === 0) {
|
|
113
264
|
target[key] = source[key]
|
|
114
265
|
}
|
|
115
266
|
}
|
|
@@ -140,22 +291,22 @@ function processContents (source, file) {
|
|
|
140
291
|
let parserOptions, parsed, formatted
|
|
141
292
|
try {
|
|
142
293
|
parserOptions = {
|
|
143
|
-
mode:
|
|
144
|
-
ignoreBOM:
|
|
145
|
-
ignoreComments:
|
|
146
|
-
ignoreTrailingCommas:
|
|
147
|
-
allowSingleQuotedStrings:
|
|
148
|
-
allowDuplicateObjectKeys:
|
|
294
|
+
mode: params.mode,
|
|
295
|
+
ignoreBOM: params.bom,
|
|
296
|
+
ignoreComments: params.comments,
|
|
297
|
+
ignoreTrailingCommas: params.trailingCommas,
|
|
298
|
+
allowSingleQuotedStrings: params.singleQuotedStrings,
|
|
299
|
+
allowDuplicateObjectKeys: params.duplicateKeys
|
|
149
300
|
}
|
|
150
|
-
if (
|
|
151
|
-
const schemas =
|
|
301
|
+
if (params.validate.length) {
|
|
302
|
+
const schemas = params.validate.map((file, index) => {
|
|
152
303
|
try {
|
|
153
304
|
return readFileSync(file, 'utf8')
|
|
154
305
|
} catch (error) {
|
|
155
306
|
throw new Error(`Loading the JSON Schema #${index + 1} failed: "${file}".\n${error.message}`)
|
|
156
307
|
}
|
|
157
308
|
})
|
|
158
|
-
parserOptions.environment =
|
|
309
|
+
parserOptions.environment = params.environment
|
|
159
310
|
try {
|
|
160
311
|
validate = compile(schemas, parserOptions)
|
|
161
312
|
} catch (error) {
|
|
@@ -165,36 +316,36 @@ function processContents (source, file) {
|
|
|
165
316
|
} else {
|
|
166
317
|
parsed = parse(source, parserOptions)
|
|
167
318
|
}
|
|
168
|
-
if (
|
|
319
|
+
if (params.prettyPrint) {
|
|
169
320
|
parserOptions.rawTokens = true
|
|
170
321
|
const tokens = tokenize(source, parserOptions)
|
|
171
322
|
// TODO: Support sorting tor the tokenized input too.
|
|
172
323
|
return print(tokens, {
|
|
173
|
-
indent:
|
|
174
|
-
pruneComments:
|
|
175
|
-
stripObjectKeys:
|
|
176
|
-
enforceDoubleQuotes:
|
|
177
|
-
enforceSingleQuotes:
|
|
178
|
-
trimTrailingCommas:
|
|
324
|
+
indent: params.indent,
|
|
325
|
+
pruneComments: params.pruneComments,
|
|
326
|
+
stripObjectKeys: params.stripObjectKeys,
|
|
327
|
+
enforceDoubleQuotes: params.enforceDoubleQuotes,
|
|
328
|
+
enforceSingleQuotes: params.enforceSingleQuotes,
|
|
329
|
+
trimTrailingCommas: params.trimTrailingCommas
|
|
179
330
|
})
|
|
180
331
|
}
|
|
181
|
-
if (
|
|
332
|
+
if (params.sortKeys) {
|
|
182
333
|
parsed = sortObject(parsed)
|
|
183
334
|
}
|
|
184
|
-
return JSON.stringify(parsed, null,
|
|
335
|
+
return JSON.stringify(parsed, null, params.indent)
|
|
185
336
|
} catch (e) {
|
|
186
|
-
if (
|
|
337
|
+
if (params.prettyPrintInvalid) {
|
|
187
338
|
/* From https://github.com/umbrae/jsonlintdotcom:
|
|
188
339
|
* If we failed to validate, run our manual formatter and then re-validate so that we
|
|
189
340
|
* can get a better line number. On a successful validate, we don't want to run our
|
|
190
341
|
* manual formatter because the automatic one is faster and probably more reliable.
|
|
191
342
|
*/
|
|
192
343
|
try {
|
|
193
|
-
formatted = format(source,
|
|
344
|
+
formatted = format(source, params.indent)
|
|
194
345
|
// Re-parse so exception output gets better line numbers
|
|
195
346
|
parsed = parse(formatted)
|
|
196
347
|
} catch (e) {
|
|
197
|
-
if (
|
|
348
|
+
if (params.compact) {
|
|
198
349
|
logCompactError(e, file)
|
|
199
350
|
} else {
|
|
200
351
|
logNormalError(e, file)
|
|
@@ -203,13 +354,13 @@ function processContents (source, file) {
|
|
|
203
354
|
console.log(formatted)
|
|
204
355
|
}
|
|
205
356
|
} else {
|
|
206
|
-
if (
|
|
357
|
+
if (params.compact) {
|
|
207
358
|
logCompactError(e, file)
|
|
208
359
|
} else {
|
|
209
360
|
logNormalError(e, file)
|
|
210
361
|
}
|
|
211
362
|
}
|
|
212
|
-
if (
|
|
363
|
+
if (params.continue) {
|
|
213
364
|
process.exitCode = 1
|
|
214
365
|
} else {
|
|
215
366
|
process.exit(1)
|
|
@@ -220,8 +371,8 @@ function processContents (source, file) {
|
|
|
220
371
|
function ensureLineBreak (parsed, source) {
|
|
221
372
|
const lines = source.split(/\r?\n/)
|
|
222
373
|
const newLine = !lines[lines.length - 1]
|
|
223
|
-
if (
|
|
224
|
-
(
|
|
374
|
+
if (params.trailingNewline === true ||
|
|
375
|
+
(params.trailingNewline !== false && newLine)) {
|
|
225
376
|
parsed += '\n'
|
|
226
377
|
}
|
|
227
378
|
return parsed
|
|
@@ -229,31 +380,31 @@ function ensureLineBreak (parsed, source) {
|
|
|
229
380
|
|
|
230
381
|
function checkContents (file, source, parsed) {
|
|
231
382
|
const { createTwoFilesPatch, structuredPatch } = require('diff')
|
|
232
|
-
const structured = structuredPatch(`${file}.orig`, file, source, parsed, '', '', { context:
|
|
383
|
+
const structured = structuredPatch(`${file}.orig`, file, source, parsed, '', '', { context: params.context })
|
|
233
384
|
const length = structured.hunks && structured.hunks.length
|
|
234
385
|
if (length > 0) {
|
|
235
386
|
const hunk = length === 1 ? 'hunk differs' : 'hunks differ'
|
|
236
387
|
const message = `${length} ${hunk}`
|
|
237
|
-
if (
|
|
388
|
+
if (params.compact) {
|
|
238
389
|
console.error(`${file}: ${message}`)
|
|
239
390
|
} else {
|
|
240
391
|
separateBlocks()
|
|
241
392
|
console.info('File:', file)
|
|
242
393
|
console.error(message)
|
|
243
394
|
}
|
|
244
|
-
if (!
|
|
245
|
-
const diff = createTwoFilesPatch(`${file}.orig`, file, source, parsed, '', '', { context:
|
|
395
|
+
if (!params.quiet) {
|
|
396
|
+
const diff = createTwoFilesPatch(`${file}.orig`, file, source, parsed, '', '', { context: params.context })
|
|
246
397
|
console.log(diff)
|
|
247
398
|
}
|
|
248
|
-
if (
|
|
399
|
+
if (params.continue) {
|
|
249
400
|
process.exitCode = 1
|
|
250
401
|
} else {
|
|
251
402
|
process.exit(1)
|
|
252
403
|
}
|
|
253
404
|
} else {
|
|
254
|
-
if (
|
|
405
|
+
if (params.compact) {
|
|
255
406
|
console.info(`${file}: no difference`)
|
|
256
|
-
} else if (
|
|
407
|
+
} else if (params.logFiles) {
|
|
257
408
|
console.info(file)
|
|
258
409
|
}
|
|
259
410
|
}
|
|
@@ -261,13 +412,13 @@ function checkContents (file, source, parsed) {
|
|
|
261
412
|
|
|
262
413
|
function diffContents (file, source, parsed) {
|
|
263
414
|
const { createTwoFilesPatch, structuredPatch } = require('diff')
|
|
264
|
-
const compact =
|
|
415
|
+
const compact = params.quiet || params.compact
|
|
265
416
|
let diff, length
|
|
266
417
|
if (compact) {
|
|
267
|
-
diff = structuredPatch(`${file}.orig`, file, source, parsed, '', '', { context:
|
|
418
|
+
diff = structuredPatch(`${file}.orig`, file, source, parsed, '', '', { context: params.context })
|
|
268
419
|
length = diff.hunks && diff.hunks.length
|
|
269
420
|
} else {
|
|
270
|
-
diff = createTwoFilesPatch(`${file}.orig`, file, source, parsed, '', '', { context:
|
|
421
|
+
diff = createTwoFilesPatch(`${file}.orig`, file, source, parsed, '', '', { context: params.context })
|
|
271
422
|
length = diff.split(/\r?\n/).length - 4
|
|
272
423
|
}
|
|
273
424
|
if (length > 0) {
|
|
@@ -280,32 +431,31 @@ function diffContents (file, source, parsed) {
|
|
|
280
431
|
console.log(diff)
|
|
281
432
|
}
|
|
282
433
|
} else {
|
|
283
|
-
if (
|
|
434
|
+
if (params.compact) {
|
|
284
435
|
console.info(`${file}: no difference`)
|
|
285
|
-
} else if (
|
|
436
|
+
} else if (params.logFiles) {
|
|
286
437
|
console.info(file)
|
|
287
438
|
}
|
|
288
439
|
}
|
|
289
440
|
}
|
|
290
441
|
|
|
291
442
|
function processFile (file) {
|
|
292
|
-
|
|
293
|
-
if (options.logFiles && !(options.compact || options.check || options.diff)) {
|
|
443
|
+
if (params.logFiles && !(params.compact || params.check || params.diff)) {
|
|
294
444
|
console.info(file)
|
|
295
445
|
}
|
|
296
446
|
const source = readFileSync(file, 'utf8')
|
|
297
447
|
const parsed = processContents(source, file)
|
|
298
|
-
if (
|
|
299
|
-
if (
|
|
448
|
+
if (params.inPlace) {
|
|
449
|
+
if (params.logFiles && params.compact) {
|
|
300
450
|
console.info(file)
|
|
301
451
|
}
|
|
302
452
|
writeFileSync(file, ensureLineBreak(parsed, source))
|
|
303
|
-
} else if (
|
|
453
|
+
} else if (params.check) {
|
|
304
454
|
checkContents(file, source, ensureLineBreak(parsed, source))
|
|
305
|
-
} else if (
|
|
455
|
+
} else if (params.diff) {
|
|
306
456
|
diffContents(file, source, ensureLineBreak(parsed, source))
|
|
307
457
|
} else {
|
|
308
|
-
if (!(
|
|
458
|
+
if (!(params.quiet || params.logFiles)) {
|
|
309
459
|
console.log(parsed)
|
|
310
460
|
}
|
|
311
461
|
}
|
|
@@ -349,16 +499,15 @@ function processPatterns (patterns) {
|
|
|
349
499
|
}
|
|
350
500
|
|
|
351
501
|
function main () {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
files = options.patterns || []
|
|
502
|
+
if (!args.length) {
|
|
503
|
+
args = params.patterns || []
|
|
355
504
|
}
|
|
356
|
-
if (
|
|
357
|
-
const dynamic =
|
|
505
|
+
if (args.length) {
|
|
506
|
+
const dynamic = args.some(file => isDynamicPattern(file))
|
|
358
507
|
if (dynamic) {
|
|
359
|
-
processPatterns(
|
|
508
|
+
processPatterns(args)
|
|
360
509
|
} else {
|
|
361
|
-
for (const file of
|
|
510
|
+
for (const file of args) {
|
|
362
511
|
processSource(file, false)
|
|
363
512
|
}
|
|
364
513
|
}
|
|
@@ -371,19 +520,19 @@ function main () {
|
|
|
371
520
|
})
|
|
372
521
|
stdin.on('end', () => {
|
|
373
522
|
const file = '<stdin>'
|
|
374
|
-
if (
|
|
523
|
+
if (params.logFiles && !(params.compact || params.check || params.diff)) {
|
|
375
524
|
console.info(file)
|
|
376
525
|
}
|
|
377
526
|
const parsed = processContents(source, file)
|
|
378
|
-
if (
|
|
527
|
+
if (params.check) {
|
|
379
528
|
checkContents(file, source, ensureLineBreak(parsed, source))
|
|
380
|
-
} else if (
|
|
529
|
+
} else if (params.diff) {
|
|
381
530
|
diffContents(file, source, ensureLineBreak(parsed, source))
|
|
382
531
|
} else {
|
|
383
|
-
if (
|
|
532
|
+
if (params.logFiles && params.compact) {
|
|
384
533
|
console.info(file)
|
|
385
534
|
}
|
|
386
|
-
if (!(
|
|
535
|
+
if (!(params.quiet || params.logFiles)) {
|
|
387
536
|
console.log(parsed)
|
|
388
537
|
}
|
|
389
538
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prantlf/jsonlint",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "JSON/CJSON/JSON5 parser, syntax and schema validator and pretty-printer.",
|
|
5
5
|
"author": "Ferdinand Prantl <prantlf@gmail.com> (http://prantl.tk)",
|
|
6
6
|
"contributors": [
|
|
@@ -75,7 +75,6 @@
|
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"ajv": "8.12.0",
|
|
77
77
|
"ajv-draft-04": "1.0.0",
|
|
78
|
-
"commander": "10.0.0",
|
|
79
78
|
"cosmiconfig": "8.1.0",
|
|
80
79
|
"diff": "5.1.0",
|
|
81
80
|
"fast-glob": "3.2.12"
|