@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  MIT License
2
2
 
3
3
  Copyright (c) 2012-2018 Zachary Carter
4
- Copyright (c) 2019 Ferdinand Prantl
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
- [![NPM version](https://badge.fury.io/js/%40prantlf%2Fjsonlint.svg)](https://badge.fury.io/js/%40prantlf%2Fjsonlint)
4
- [![Build Status](https://travis-ci.com/prantlf/jsonlint.svg?branch=master)](https://travis-ci.com/prantlf/jsonlint)
5
- [![codecov](https://codecov.io/gh/prantlf/jsonlint/branch/master/graph/badge.svg)](https://codecov.io/gh/prantlf/jsonlint)
6
- [![Dependency Status](https://david-dm.org/prantlf/jsonlint.svg)](https://david-dm.org/prantlf/jsonlint)
7
- [![devDependency Status](https://david-dm.org/prantlf/jsonlint/dev-status.svg)](https://david-dm.org/prantlf/jsonlint#info=devDependencies)
8
- [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
3
+ [![Latest version](https://img.shields.io/npm/v/@prantlf/jsonlint)
4
+ ![Dependency status](https://img.shields.io/librariesio/release/npm/@prantlf/jsonlint)
5
+ ](https://www.npmjs.com/package/@prantlf/jsonlint)
6
+ [![Code coverage](https://codecov.io/gh/prantlf/jsonlint/branch/master/graph/badge.svg)](https://codecov.io/gh/prantlf/jsonlint)
9
7
 
10
- A [JSON]/[JSON5] parser and validator with a command-line client. A [pure JavaScript version] of the service provided at [jsonlint.com].
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 package with the following enhancements:
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 tripping comments, for example. (Raw token values must be enabled when tokenizing the JSON input.)
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` | will not print quotes around object keys which are JavaScript identifier names |
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 */}', { ignoreComments: true }))
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 10.15.3:
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
- the built-in parser x 68,212 ops/sec ±0.86% (87 runs sampled)
259
- the pure jju parser x 10,234 ops/sec ±1.08% (89 runs sampled)
260
- the extended jju parser x 10,210 ops/sec ±1.26% (88 runs sampled)
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. Extending the parser with the support for comments and single-quoted strings does not affect the performance. Making the parser collect tokens and their locations decreases the performance a bit.
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-2019 Zachary Carter, Ferdinand Prantl
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
- var fs = require('fs')
4
- var path = require('path')
5
- var parser = require('./jsonlint')
6
- var formatter = require('./formatter')
7
- var printer = require('./printer')
8
- var sorter = require('./sorter')
9
- var validator = require('./validator')
10
- var pkg = require('../package')
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
- var options = require('commander')
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
- var parserOptions, parsed, formatted
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
- var validate
74
+ let validate
69
75
  try {
70
- var schema = fs.readFileSync(path.normalize(options.validate), 'utf8')
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
- var message = 'Loading the JSON schema failed: "' +
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
- var tokens = parser.tokenize(source, parserOptions)
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
- var source = parse(fs.readFileSync(file, 'utf8'), file)
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
- var extensions = options.extensions.map(function (extension) {
152
+ const extensions = options.extensions.map(function (extension) {
141
153
  return '.' + extension
142
154
  })
143
- var srcStat
155
+ let srcStat
144
156
  try {
145
157
  srcStat = fs.statSync(src)
146
158
  if (srcStat.isFile()) {
147
159
  if (checkExtension) {
148
- var ext = path.extname(src)
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
- var sources = fs.readdirSync(src)
156
- for (var i = 0; i < sources.length; i++) {
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
- var files = options.args
167
- var source = ''
178
+ const files = commander.args
179
+ let source = ''
168
180
  if (files.length) {
169
- for (var i = 0; i < files.length; i++) {
181
+ for (let i = 0; i < files.length; i++) {
170
182
  processSources(files[i], false)
171
183
  }
172
184
  } else {
173
- var stdin = process.openStdin()
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
- var parsed = parse(source, '<stdin>')
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
- var i = 0
25
- var length = 0
26
- var indentString = indent !== undefined
24
+ let i = 0
25
+ let length = 0
26
+ const indentString = indent !== undefined
27
27
  ? typeof indent === 'number'
28
- ? new Array(indent + 1).join(' ') : indent : ' '
29
- var outputString = ''
30
- var indentLevel = 0
31
- var inString
32
- var currentChar
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
@@ -90,6 +90,9 @@ declare module '@prantlf/jsonlint/lib/printer' {
90
90
  indent?: number | string
91
91
  pruneComments?: boolean
92
92
  stripObjectKeys?: boolean
93
+ enforceDoubleQuotes?: boolean
94
+ enforceSingleQuotes?: boolean
95
+ trimTrailingCommas?: boolean
93
96
  }
94
97
 
95
98
  /**