From 9aa09fbc9980e78fa0fed134ce48d99412b619a9 Mon Sep 17 00:00:00 2001 From: Ferdinand Prantl Date: Sun, 2 Jun 2019 12:22:18 +0200 Subject: [PATCH] feat: Add "mode" parameter to set flags for a typical formt type easier Recognize "json" (default), "cjson" and "json5". Parsing support for this feature was added by integrating the JJU parser (a4a606c333e443642ced99d466223607bce11461). --- .vscode/launch.json | 5 +++-- README.md | 42 ++++++++++++++++++++++++++++++++---------- lib/cli.js | 3 +++ lib/validator.js | 1 + package.json | 4 ++-- test/passes/json5.text | 4 ++++ 6 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 test/passes/json5.text diff --git a/.vscode/launch.json b/.vscode/launch.json index b366dab..ee9ff25 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,8 +7,9 @@ "name": "cli", "program": "${workspaceRoot}/lib/cli.js", "args": [ - "-C", - "test/passes/1.json" + "-M", + "json5", + "test/passes/json5.txt" ], "skipFiles": [ "/**/*.js" diff --git a/README.md b/README.md index 4cc8511..a1daaab 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![devDependency Status](https://david-dm.org/prantlf/jsonlint/dev-status.svg)](https://david-dm.org/prantlf/jsonlint#info=devDependencies) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) -A JSON parser and validator with a command-line client. A [pure JavaScript version](http://prantlf.github.com/jsonlint/) of the service provided at [jsonlint.com](http://jsonlint.com). +A [JSON]/[JSON5] parser and validator with a command-line client. A [pure JavaScript version] of the service provided at [jsonlint.com]. This is a fork of the original package with the following enhancements: @@ -15,9 +15,9 @@ This is a fork of the original package with the following enhancements: * Walks directories recursively (by Paul Vollmer). * Provides 100% compatible interface to the native `JSON.parse` method. * Optionally recognizes JavaScript-style comments and single quoted strings. -* Supports JSON Schema drafts 04, 06 and 07. -* Prefers the native JSON parser to gain the [best performance](./benchmarks#json-parser-comparison), while showing error messages of the same quality. -* Implements JavaScript modules using [UMD](https://github.com/umdjs/umd) to work everywhere. +* Supports [JSON Schema] drafts 04, 06 and 07. +* Prefers the native JSON parser to gain the [best performance], while showing error messages of the same quality. +* Implements JavaScript modules using [UMD] to work everywhere. * Depends on up-to-date npm modules with no installation warnings. * Small size - 17.6 kB minified, 6.1 kB gzipped. @@ -76,16 +76,18 @@ By default, `jsonlint` will either report a syntax error with details or pretty- -i, --in-place overwrite the input files -t, --indent [char] characters to use for indentation (default: " ") -c, --compact compact error display + -M, --mode set other parsing flags according to a format type -C, --comments recognize and ignore JavaScript-style comments -S, --single-quoted-strings support single quotes as string delimiters -V, --validate [file] JSON schema file to use for validation - -e, --environment [env] which specification of JSON Schema the validation - file uses + -e, --environment [env] which specification of JSON Schema + the validation file uses -q, --quiet do not print the parsed json to stdin -p, --pretty-print force pretty-printing even for invalid input -v, --version output the version number -h, --help output usage information + Parsing mode can be "cjson" or "json5" to enable other flags automatically. If no files or directories are specified, stdin will be parsed. Environments for JSON schema validation are "json-schema-draft-04", "json-schema-draft-06" or "json-schema-draft-07". If not specified, it will be auto-detected. @@ -125,8 +127,17 @@ The `parse` method offers more detailed [error information](#error-handling), th | Option | Description | | -------------------------- | --------------------------- | -| `ignoreComments` | ignores single-line and multi-line JavaScript-style comments during parsing as another "whitespace" | -| `allowSingleQuotedStrings` | accepts strings delimited by single-quotes too | +| `ignoreComments` | ignores single-line and multi-line JavaScript-style comments during parsing as another "whitespace" (boolean) | +| `allowSingleQuotedStrings` | accepts strings delimited by single-quotes too (boolean) | +| `mode` | sets multiple options according to the type of input data (string) | + +The `mode` parameter (string) sets parsing options to match a common format of input data: + +| Mode | Description | +| ------- | --------------------------- | +| `json` | complies to the pure standard [JSON] (default if not set) | +| `cjson` | JSON with comments (sets `ignoreComments`) | +| `json5` | complies to [JSON5] (sets `ignoreComments`, `allowSingleQuotedStrings` and other flags) | ### Schema Validation @@ -150,13 +161,13 @@ const validate = compile('string with JSON schema', { ### Performance -This is a part of an output from the [parser benchmark](./benchmarks#json-parser-comparison), when parsing a 4.2 KB formatted string ([package.json](./package.json)) with Node.js 10.15.3: +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: the built-in parser x 61,588 ops/sec ±0.75% (80 runs sampled) the pure jju parser x 11,396 ops/sec ±1.05% (86 runs sampled) the extended jju parser x 8,221 ops/sec ±0.99% (87 runs sampled) -A custom JSON parser is [a lot slower](./benchmarks/results/performance.md#results) than the built-in one. However, it is more important to have a [clear error reporting](./benchmarks/results/errorReportingQuality.md#results) 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 significantly the performance. +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 significantly the performance. ### Error Handling @@ -201,3 +212,14 @@ ${reason}`) Copyright (C) 2012-2019 Zachary Carter, Ferdinand Prantl Licensed under the MIT license. + +[pure JavaScript version]: http://prantlf.github.com/jsonlint/ +[jsonlint.com]: http://jsonlint.com +[JSON]: https://tools.ietf.org/html/rfc8259 +[JSON5]: https://spec.json5.org +[JSON Schema]: https://json-schema.org +[UMD]: https://github.com/umdjs/umd +[best performance]: ./benchmarks#json-parser-comparison +[parser benchmark]: ./benchmarks#json-parser-comparison +[a lot slower]: ./benchmarks/results/performance.md#results +[clear error reporting]: ./benchmarks/results/errorReportingQuality.md#results diff --git a/lib/cli.js b/lib/cli.js index c402b76..eae33f6 100755 --- a/lib/cli.js +++ b/lib/cli.js @@ -21,6 +21,7 @@ var options = require('commander') .option('-i, --in-place', 'overwrite the input files') .option('-t, --indent [char]', 'characters to use for indentation', ' ') .option('-c, --compact', 'compact error display') + .option('-M, --mode [mode]', 'set other parsing flags according to a format type', 'json') .option('-C, --comments', 'recognize and ignore JavaScript-style comments') .option('-S, --single-quoted-strings', 'support single quotes as string delimiters') .option('-V, --validate [file]', 'JSON schema file to use for validation') @@ -30,6 +31,7 @@ var options = require('commander') .version(pkg.version, '-v, --version') .on('--help', () => { console.log() + console.log('Parsing mode can be "cjson" or "json5" to enable other flags automatically.') console.log('If no files or directories are specified, stdin will be parsed. Environments') console.log('for JSON schema validation are "json-schema-draft-04", "json-schema-draft-06"') console.log('or "json-schema-draft-07". If not specified, it will be auto-detected.') @@ -50,6 +52,7 @@ function parse (source, file) { var parserOptions, parsed, formatted try { parserOptions = { + mode: options.mode, ignoreComments: options.comments, allowSingleQuotedStrings: options.singleQuotedStrings } diff --git a/lib/validator.js b/lib/validator.js index a26deee..66ca187 100644 --- a/lib/validator.js +++ b/lib/validator.js @@ -54,6 +54,7 @@ var validate try { schema = jsonlint.parse(schema, { + mode: options.mode, ignoreComments: options.ignoreComments, allowSingleQuotedStrings: options.allowSingleQuotedStrings }) diff --git a/package.json b/package.json index 5b131f6..d48a0b7 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ "prepare": "npm run lint && npm run build", "lint": "standard --fix -v", "build": "node scripts/bundle-jsonlint && uglifyjs -o web/jsonlint.min.js --source-map \"filename='jsonlint.js',url='jsonlint.min.js.map',includeSources=true\" lib/jsonlint.js && uglifyjs -o web/validator.min.js --source-map \"filename='validator.js',url='validator.min.js.map',includeSources=true\" lib/validator.js && uglifyjs -o web/formatter.min.js --source-map \"filename='formatter.js',url='formatter.min.js.map',includeSources=true\" lib/formatter.js && uglifyjs -o web/sorter.min.js --source-map \"filename='sorter.js',url='sorter.min.js.map',includeSources=true\" lib/sorter.js && node scripts/bundle-schema-drafts | uglifyjs -o web/schema-drafts.min.js --source-map \"filename='schema-drafts.js',url='schema-drafts.min.js.map',includeSources=true\" && uglifyjs -o web/ajv.min.js --source-map \"filename='ajv.js',url='ajv.min.js.map',includeSources=true\" node_modules/ajv/dist/ajv.bundle.js", - "test": "nyc --silent node test/parse1 && nyc --silent --no-clean node test/parse1 --native-parser && nyc --silent --no-clean node test/parse2 && nyc --silent --no-clean node test/parse3 && nyc --silent --no-clean node test/parse4 && nyc --silent --no-clean node test/parse5 && nyc --silent --no-clean node test/portable && nyc --silent --no-clean node lib/cli package.json test/recursive && nyc --silent --no-clean node lib/cli -sq test/passes/hasOwnProperty.json && nyc --silent --no-clean node lib/cli -s -e json-schema-draft-04 -V test/passes/3.schema.json test/passes/3.json && nyc --silent --no-clean node lib/cli -C test/passes/comments.txt && nyc --silent --no-clean node lib/cli -S test/passes/strings.txt && nyc --silent --no-clean node lib/cli -v && nyc --silent --no-clean node lib/cli -h && nyc --silent --no-clean node lib/cli -pc test/fails/10.json || nyc report", - "test:old": "node test/parse1 && node test/parse1 --native-parser && node test/parse2 && node test/parse3 && node test/parse4 && node test/parse5 && node test/portable && node lib/cli package.json test/recursive && node lib/cli -sq test/passes/hasOwnProperty.json && node lib/cli -s -e json-schema-draft-04 -V test/passes/3.schema.json test/passes/3.json && node lib/cli -C test/passes/comments.txt && node lib/cli -S test/passes/strings.txt && node lib/cli -v && node lib/cli -h", + "test": "nyc --silent node test/parse1 && nyc --silent --no-clean node test/parse1 --native-parser && nyc --silent --no-clean node test/parse2 && nyc --silent --no-clean node test/parse3 && nyc --silent --no-clean node test/parse4 && nyc --silent --no-clean node test/parse5 && nyc --silent --no-clean node test/portable && nyc --silent --no-clean node lib/cli package.json test/recursive && nyc --silent --no-clean node lib/cli -sq test/passes/hasOwnProperty.json && nyc --silent --no-clean node lib/cli -s -e json-schema-draft-04 -V test/passes/3.schema.json test/passes/3.json && nyc --silent --no-clean node lib/cli -C test/passes/comments.txt && nyc --silent --no-clean node lib/cli -S test/passes/strings.txt && nyc --silent --no-clean node lib/cli -M json5 test/passes/json5.text && nyc --silent --no-clean node lib/cli -v && nyc --silent --no-clean node lib/cli -h && nyc --silent --no-clean node lib/cli -pc test/fails/10.json || nyc report", + "test:old": "node test/parse1 && node test/parse1 --native-parser && node test/parse2 && node test/parse3 && node test/parse4 && node test/parse5 && node test/portable && node lib/cli package.json test/recursive && node lib/cli -sq test/passes/hasOwnProperty.json && node lib/cli -s -e json-schema-draft-04 -V test/passes/3.schema.json test/passes/3.json && node lib/cli -C test/passes/comments.txt && node lib/cli -S test/passes/strings.txt && node lib/cli -M json5 test/passes/json5.text && node lib/cli -v && node lib/cli -h", "coverage": "cat coverage/lcov.info | npx coveralls", "start": "python -m SimpleHTTPServer", "web": "npm run web:sync && npm run web:deploy", diff --git a/test/passes/json5.text b/test/passes/json5.text new file mode 100644 index 0000000..5a7eda3 --- /dev/null +++ b/test/passes/json5.text @@ -0,0 +1,4 @@ +{ + // String parameter + "key": 'value', +}