@prantlf/jsonlint 14.0.3 → 15.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/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
1
  MIT License
2
2
 
3
3
  Copyright (c) 2012-2018 Zachary Carter
4
- Copyright (c) 2019-2023 Ferdinand Prantl
4
+ Copyright (c) 2019-2024 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
@@ -21,7 +21,7 @@ This is a fork of the original project ([zaach/jsonlint](https://github.com/zaac
21
21
  * Offers pretty-printing including comment-stripping and object keys without quotes (JSON5).
22
22
  * Prefers the native JSON parser if possible to run [10x faster than the custom parser].
23
23
  * Reports errors with rich additional information. From the JSON Schema validation too.
24
- * Consumes configuration from both command line and [configuration files](configuration).
24
+ * Consumes configuration from both command line and [configuration files](#configuration).
25
25
  * Implements JavaScript modules using [UMD] to work in Node.js, in a browser, everywhere.
26
26
  * Depends on up-to-date npm modules with no installation warnings.
27
27
  * Small size - 18.4 kB minified, 6.45 kB gzipped, 5.05 kB brotlied.
@@ -120,7 +120,15 @@ Usage: `jsonlint [options] [--] [<file, directory, pattern> ...]`
120
120
 
121
121
  -f, --config <file> read options from a custom configuration file
122
122
  -F, --no-config disable searching for configuration files
123
+ --ignore-proto-key ignore occurrences of "__proto__" object key
124
+ --ignore-prototype-keys ignore all keys from "Object.prototype"
123
125
  -s, --sort-keys sort object keys (not when prettifying)
126
+ --sort-keys-ignore-case sort object keys ignoring the letter case
127
+ --sort-keys-locale <id> locale identifier to sort object keys with
128
+ (or "default" for the system default)
129
+ --sort-keys-case-first <id> order if only letter case is different
130
+ ("upper", "lower" and "false" are allowed)
131
+ --sort-keys-numeric sort by numbers recognised in object keys
124
132
  -E, --extensions <ext...> file extensions to process for directory walk
125
133
  (default: json, JSON)
126
134
  -i, --in-place overwrite the input files
@@ -154,6 +162,7 @@ Usage: `jsonlint [options] [--] [<file, directory, pattern> ...]`
154
162
  --enforce-double-quotes surrounds all strings with double quotes
155
163
  --enforce-single-quotes surrounds all strings with single quotes
156
164
  --trim-trailing-commas omit trailing commas from objects and arrays
165
+ --succeed-with-no-files succeed (exit code 0) if no files were found
157
166
  -v, --version output the version number
158
167
  -h, --help display help for command
159
168
 
@@ -192,7 +201,13 @@ The configuration is an object with the following properties, described above, w
192
201
  | Parameter | Alias |
193
202
  | --------- | ----- |
194
203
  | patterns | |
204
+ | ignore-proto-key | ignoreProtoKey |
205
+ | ignore-prototype-keys | ignorePrototypeKeys |
195
206
  | sort-keys | sortKeys |
207
+ | sort-keys-ignore-case | sortKeysIgnoreCase |
208
+ | sort-keys-locale | sortKeysLocale |
209
+ | sort-keys-case-first | sortKeysCaseFirst |
210
+ | sort-keys-numeric | sortKeysNumeric |
196
211
  | extensions | |
197
212
  | in-place | inPlace |
198
213
  | diff | |
@@ -263,6 +278,8 @@ The `parse` method offers more detailed [error information](#error-handling), th
263
278
  | `ignoreTrailingCommas` | ignores trailing commas in objects and arrays (boolean) |
264
279
  | `allowSingleQuotedStrings` | accepts strings delimited by single-quotes too (boolean) |
265
280
  | `allowDuplicateObjectKeys` | allows reporting duplicate object keys as an error (boolean) |
281
+ | `ignoreProtoKey` | ignore occurrences of the `__proto__` object key (boolean) |
282
+ | `ignorePrototypeKeys` | ignore all keys from `Object.prototype` (boolean) |
266
283
  | `mode` | sets multiple options according to the type of input data (string) |
267
284
  | `reviver` | converts object and array values (function) |
268
285
 
@@ -428,7 +445,7 @@ ${reason}`)
428
445
 
429
446
  ## License
430
447
 
431
- Copyright (C) 2012-2023 Zachary Carter, Ferdinand Prantl
448
+ Copyright (C) 2012-2024 Zachary Carter, Ferdinand Prantl
432
449
 
433
450
  Licensed under the [MIT License].
434
451
 
package/lib/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { readdirSync, readFileSync, statSync, writeFileSync } = require('fs')
4
- const { extname, join } = require('path')
3
+ const { readdirSync, readFileSync, statSync, writeFileSync } = require('node:fs')
4
+ const { extname, join } = require('node:path')
5
5
  const { isDynamicPattern, sync } = require('fast-glob')
6
6
  const { parse, tokenize } = require('./jsonlint')
7
7
  const { format } = require('./formatter')
@@ -17,7 +17,15 @@ Usage: jsonlint [options] [--] [<file, directory, pattern> ...]
17
17
  Options:
18
18
  -f, --config <file> read options from a custom configuration file
19
19
  -F, --no-config disable searching for configuration files
20
+ --ignore-proto-key ignore occurrences of "__proto__" object key
21
+ --ignore-prototype-keys ignore all keys from "Object.prototype"
20
22
  -s, --sort-keys sort object keys (not when prettifying)
23
+ --sort-keys-ignore-case sort object keys ignoring the letter case
24
+ --sort-keys-locale <id> locale identifier to sort object keys with
25
+ (or "default" for the system default)
26
+ --sort-keys-case-first <id> order if only letter case is different
27
+ ("upper", "lower" and "false" are allowed)
28
+ --sort-keys-numeric sort by numbers recognised in object keys
21
29
  -E, --extensions <ext...> file extensions to process for directory walk
22
30
  (default: json, JSON)
23
31
  -i, --in-place overwrite the input files
@@ -51,6 +59,7 @@ Options:
51
59
  --enforce-double-quotes surrounds all strings with double quotes
52
60
  --enforce-single-quotes surrounds all strings with single quotes
53
61
  --trim-trailing-commas omit trailing commas from objects and arrays
62
+ --succeed-with-no-files succeed (exit code 0) if no files were found
54
63
  -v, --version output the version number
55
64
  -h, --help display help for command
56
65
 
@@ -82,9 +91,27 @@ for (let i = 2, l = argv.length; i < l; ++i) {
82
91
  case 'F':
83
92
  params.config = false
84
93
  return
94
+ case 'ignore-proto-key':
95
+ params.ignoreProtoKey = flag
96
+ return
97
+ case 'ignore-prototype-keys':
98
+ params.ignorePrototypeKeys = flag
99
+ return
85
100
  case 's': case 'sort-keys':
86
101
  params.sortKeys = flag
87
102
  return
103
+ case 'sort-keys-ignore-case':
104
+ params.sortKeysIgnoreCase = flag
105
+ return
106
+ case 'sort-keys-locale':
107
+ params.sortKeysLocale = match[4] || argv[++i]
108
+ return
109
+ case 'sort-keys-case-first':
110
+ params.sortKeysCaseFirst = match[4] || argv[++i]
111
+ return
112
+ case 'sort-keys-numeric':
113
+ params.sortKeysNumeric = flag
114
+ return
88
115
  case 'E': case 'extensions':
89
116
  arg = match[4] || argv[++i]
90
117
  params.extensions.push(...arg.split(','))
@@ -100,7 +127,7 @@ for (let i = 2, l = argv.length; i < l; ++i) {
100
127
  return
101
128
  case 't': case 'indent':
102
129
  arg = match[4] || argv[++i]
103
- if (arg.trim().length > 0 && !isNaN(+arg)) arg = +arg
130
+ if (arg.trim().length > 0 && !Number.isNaN(+arg)) arg = +arg
104
131
  params.indent = arg
105
132
  return
106
133
  case 'c': case 'compact':
@@ -149,7 +176,7 @@ for (let i = 2, l = argv.length; i < l; ++i) {
149
176
  return
150
177
  case 'x': case 'context':
151
178
  arg = match[4] || argv[++i]
152
- if (isNaN(+arg)) {
179
+ if (Number.isNaN(+arg)) {
153
180
  throw new Error(`invalid diff context: "${arg}"`)
154
181
  }
155
182
  params.indent = +arg
@@ -190,6 +217,9 @@ for (let i = 2, l = argv.length; i < l; ++i) {
190
217
  case 'trim-trailing-commas':
191
218
  params.trimTrailingCommas = flag
192
219
  return
220
+ case 'succeed-with-no-files':
221
+ params.succeedWithNoFiles = flag
222
+ return
193
223
  case 'v': case 'version':
194
224
  console.log(require('../package.json').version)
195
225
  process.exit(0)
@@ -216,6 +246,8 @@ for (let i = 2, l = argv.length; i < l; ++i) {
216
246
  }
217
247
 
218
248
  const paramNames = {
249
+ 'ignore-proto-key': 'ignoreProtoKey',
250
+ 'ignore-prototype-keys': 'ignorePrototypeKeys',
219
251
  'trailing-commas': 'trailingCommas',
220
252
  'single-quoted-strings': 'singleQuotedStrings',
221
253
  'duplicate-keys': 'duplicateKeys',
@@ -226,6 +258,10 @@ const paramNames = {
226
258
  'enforce-single-quotes': 'enforceSingleQuotes',
227
259
  'trim-trailing-commas': 'trimTrailingCommas',
228
260
  'sort-keys': 'sortKeys',
261
+ 'sort-keys-ignore-case': 'sortKeysIgnoreCase',
262
+ 'sort-keys-locale': 'sortKeysLocale',
263
+ 'sort-keys-case-first': 'sortKeysCaseFirst',
264
+ 'sort-keys-numeric': 'sortKeysNumeric',
229
265
  'pretty-print-invalid': 'prettyPrintInvalid',
230
266
  'log-files': 'logFiles',
231
267
  'in-place': 'inPlace',
@@ -283,20 +319,23 @@ function logNormalError (error, file) {
283
319
  }
284
320
 
285
321
  function logCompactError (error, file) {
286
- console.error(file + ': line ' + error.location.start.line +
287
- ', col ' + error.location.start.column + ', ' + error.reason + '.')
322
+ console.error(`${file}: line ${error.location.start.line}, col ${error.location.start.column}, ${error.reason}.`)
288
323
  }
289
324
 
290
325
  function processContents (source, file) {
291
- let parserOptions, parsed, formatted
326
+ let parserOptions
327
+ let parsed
328
+ let formatted
292
329
  try {
293
330
  parserOptions = {
294
331
  mode: params.mode,
295
332
  ignoreBOM: params.bom,
296
333
  ignoreComments: params.comments,
297
- ignoreTrailingCommas: params.trailingCommas,
334
+ ignoreTrailingCommas: params.trailingCommas || params.trimTrailingCommas,
298
335
  allowSingleQuotedStrings: params.singleQuotedStrings,
299
- allowDuplicateObjectKeys: params.duplicateKeys
336
+ allowDuplicateObjectKeys: params.duplicateKeys,
337
+ ignoreProtoKey: params.ignoreProtoKey,
338
+ ignorePrototypeKeys: params.ignorePrototypeKeys
300
339
  }
301
340
  if (params.validate.length) {
302
341
  const schemas = params.validate.map((file, index) => {
@@ -329,8 +368,29 @@ function processContents (source, file) {
329
368
  trimTrailingCommas: params.trimTrailingCommas
330
369
  })
331
370
  }
371
+ const sortOptions = {}
372
+ let sort
332
373
  if (params.sortKeys) {
333
- parsed = sortObject(parsed)
374
+ sort = true
375
+ }
376
+ if (params.sortKeysIgnoreCase) {
377
+ sortOptions.ignoreCase = true
378
+ sort = true
379
+ }
380
+ if (params.sortKeysLocale) {
381
+ sortOptions.locale = params.sortKeysLocale
382
+ sort = true
383
+ }
384
+ if (params.sortKeysCaseFirst) {
385
+ sortOptions.caseFirst = params.sortKeysCaseFirst
386
+ sort = true
387
+ }
388
+ if (params.sortKeysNumeric) {
389
+ sortOptions.numeric = true
390
+ sort = true
391
+ }
392
+ if (sort) {
393
+ parsed = sortObject(parsed, sortOptions)
334
394
  }
335
395
  return JSON.stringify(parsed, null, params.indent)
336
396
  } catch (e) {
@@ -381,7 +441,7 @@ function ensureLineBreak (parsed, source) {
381
441
  function checkContents (file, source, parsed) {
382
442
  const { createTwoFilesPatch, structuredPatch } = require('diff')
383
443
  const structured = structuredPatch(`${file}.orig`, file, source, parsed, '', '', { context: params.context })
384
- const length = structured.hunks && structured.hunks.length
444
+ const length = structured.hunks?.length
385
445
  if (length > 0) {
386
446
  const hunk = length === 1 ? 'hunk differs' : 'hunks differ'
387
447
  const message = `${length} ${hunk}`
@@ -413,10 +473,11 @@ function checkContents (file, source, parsed) {
413
473
  function diffContents (file, source, parsed) {
414
474
  const { createTwoFilesPatch, structuredPatch } = require('diff')
415
475
  const compact = params.quiet || params.compact
416
- let diff, length
476
+ let diff
477
+ let length
417
478
  if (compact) {
418
479
  diff = structuredPatch(`${file}.orig`, file, source, parsed, '', '', { context: params.context })
419
- length = diff.hunks && diff.hunks.length
480
+ length = diff.hunks?.length
420
481
  } else {
421
482
  diff = createTwoFilesPatch(`${file}.orig`, file, source, parsed, '', '', { context: params.context })
422
483
  length = diff.split(/\r?\n/).length - 4
@@ -487,7 +548,7 @@ function processPatterns (patterns) {
487
548
  const files = sync(patterns, { onlyFiles: true })
488
549
  if (!files.length) {
489
550
  console.error('no files found')
490
- process.exit(1)
551
+ process.exit(params.succeedWithNoFiles ? 0 : 1)
491
552
  }
492
553
  for (const file of files) {
493
554
  try {
package/lib/formatter.js CHANGED
@@ -36,7 +36,7 @@
36
36
  case '{':
37
37
  case '[':
38
38
  if (!inString) {
39
- outputString += currentChar + '\n' + repeat(indentString, indentLevel + 1)
39
+ outputString += `${currentChar}\n${repeat(indentString, indentLevel + 1)}`
40
40
  indentLevel += 1
41
41
  } else {
42
42
  outputString += currentChar
@@ -46,14 +46,14 @@
46
46
  case ']':
47
47
  if (!inString) {
48
48
  indentLevel -= 1
49
- outputString += '\n' + repeat(indentString, indentLevel) + currentChar
49
+ outputString += `\n${repeat(indentString, indentLevel)}${currentChar}`
50
50
  } else {
51
51
  outputString += currentChar
52
52
  }
53
53
  break
54
54
  case ',':
55
55
  if (!inString) {
56
- outputString += ',\n' + repeat(indentString, indentLevel)
56
+ outputString += `,\n${repeat(indentString, indentLevel)}`
57
57
  } else {
58
58
  outputString += currentChar
59
59
  }