From eef0999e6c47bb7779789a8884dd95cc03effc58 Mon Sep 17 00:00:00 2001 From: George Pickering <29524044+geopic@users.noreply.github.com> Date: Sun, 31 Jan 2021 18:47:42 +0000 Subject: [PATCH 01/40] feat: add types declaration file with entry in package.json --- lib/index.d.ts | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 77 insertions(+) create mode 100644 lib/index.d.ts diff --git a/lib/index.d.ts b/lib/index.d.ts new file mode 100644 index 00000000..c2b002af --- /dev/null +++ b/lib/index.d.ts @@ -0,0 +1,76 @@ +declare type StringifyOptions = Partial<{ + /** + * A function that alters the behavior of the stringification process, or an + * array of String and Number objects that serve as a whitelist for + * selecting/filtering the properties of the value object to be included in + * the JSON5 string. If this value is null or not provided, all properties + * of the object are included in the resulting JSON5 string. + */ + replacer: ((this: any, key: string, value: any) => any) | (string | number)[]; + + /** + * A String or Number object that's used to insert white space into the + * output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this + * number is capped at 10 (if it is greater, the value is just 10). Values + * less than 1 indicate that no space should be used. If this is a String, + * the string (or the first 10 characters of the string, if it's longer than + * that) is used as white space. If this parameter is not provided (or is + * null), no white space is used. If white space is used, trailing commas + * will be used in objects and arrays. + */ + space: string | number; + + /** + * A String representing the quote character to use when serializing strings. + */ + quote: string; +}> + +/** + * Parses a JSON5 string, constructing the JavaScript value or object described + * by the string. An optional reviver function can be provided to perform a + * transformation on the resulting object before it is returned. + * @param text The string to parse as JSON5. + * @param reviver If a function, this prescribes how the value originally + * produced by parsing is transformed, before being returned. + */ +export function parse(text: string, reviver?: (this: any, key: string, value: any) => any): any; + +/** + * Converts a JavaScript value to a JSON5 string, optionally replacing values + * if a replacer function is specified, or optionally including only the + * specified properties if a replacer array is specified. + * @param value The value to convert to a JSON5 string. + * @param replacer A function that alters the behavior of the stringification + * process, or an array of String and Number objects that serve as a whitelist + * for selecting/filtering the properties of the value object to be included in + * the JSON5 string. If this value is null or not provided, all properties of + * the object are included in the resulting JSON5 string. + * @param space A String or Number object that's used to insert white space + * into the output JSON5 string for readability purposes. If this is a Number, + * it indicates the number of space characters to use as white space; this + * number is capped at 10 (if it is greater, the value is just 10). Values less + * than 1 indicate that no space should be used. If this is a String, the + * string (or the first 10 characters of the string, if it's longer than that) + * is used as white space. If this parameter is not provided (or is null), no + * white space is used. If white space is used, trailing commas will be used in + * objects and arrays. + */ +export function stringify(value: any, replacer?: ((this: any, key: string, value: any) => any) | (string | number)[], space?: string | number): string; + +/** + * Converts a JavaScript value to a JSON5 string, optionally replacing values + * if a replacer function is specified, or optionally including only the + * specified properties if a replacer array is specified. + * @param value The value to convert to a JSON5 string. + * @param options An object with the following properties: + * + * `replacer`: Same as the `replacer` parameter. + * + * `space`: Same as the `space` parameter. + * + * `quote`: A String representing the quote character to use when serializing + * strings. + */ +export function stringify(value: any, options?: StringifyOptions): string; diff --git a/package.json b/package.json index 9c5b82ea..3b3b79a5 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "module": "dist/index.mjs", "bin": "lib/cli.js", "browser": "dist/index.js", + "types": "lib/index.d.ts", "files": [ "lib/", "dist/" From 3dd26ac0bdec7db3a0ae54a6f22ebb7c197ce924 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Wed, 27 Jan 2021 13:45:57 -0600 Subject: [PATCH 02/40] feat: add TypeScript delcarations for module files --- CHANGELOG.md | 10 ++++++ lib/index.d.ts | 78 ++-------------------------------------- lib/parse.d.ts | 15 ++++++++ lib/stringify.d.ts | 89 ++++++++++++++++++++++++++++++++++++++++++++++ lib/unicode.d.ts | 3 ++ lib/util.d.ts | 5 +++ package.json5 | 1 + 7 files changed, 126 insertions(+), 75 deletions(-) create mode 100644 lib/parse.d.ts create mode 100644 lib/stringify.d.ts create mode 100644 lib/unicode.d.ts create mode 100644 lib/util.d.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e6d09c9..538e9a5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +### Unreleased [[code][c-unreleased], [diff][d-unreleased]] + +[c-unreleased]: https://github.com/json5/json5/tree/master +[d-unreleased]: https://github.com/json5/json5/compare/v2.1.3...HEAD + +- New: Accurate and documented TypeScript declarations are now included. There + is no need to install `@types/json5`. ([#236], [#244]) + ### v2.1.3 [[code][c2.1.3], [diff][d2.1.3]] [c2.1.3]: https://github.com/json5/json5/tree/v2.1.3 @@ -342,3 +350,5 @@ parser for the regular JSON format. [#196]: https://github.com/json5/json5/issues/196 [#208]: https://github.com/json5/json5/issues/208 [#210]: https://github.com/json5/json5/issues/210 +[#236]: https://github.com/json5/json5/issues/236 +[#244]: https://github.com/json5/json5/issues/244 diff --git a/lib/index.d.ts b/lib/index.d.ts index c2b002af..1c45bca5 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -1,76 +1,4 @@ -declare type StringifyOptions = Partial<{ - /** - * A function that alters the behavior of the stringification process, or an - * array of String and Number objects that serve as a whitelist for - * selecting/filtering the properties of the value object to be included in - * the JSON5 string. If this value is null or not provided, all properties - * of the object are included in the resulting JSON5 string. - */ - replacer: ((this: any, key: string, value: any) => any) | (string | number)[]; +import parse = require('./parse') +import stringify = require('./stringify') - /** - * A String or Number object that's used to insert white space into the - * output JSON5 string for readability purposes. If this is a Number, it - * indicates the number of space characters to use as white space; this - * number is capped at 10 (if it is greater, the value is just 10). Values - * less than 1 indicate that no space should be used. If this is a String, - * the string (or the first 10 characters of the string, if it's longer than - * that) is used as white space. If this parameter is not provided (or is - * null), no white space is used. If white space is used, trailing commas - * will be used in objects and arrays. - */ - space: string | number; - - /** - * A String representing the quote character to use when serializing strings. - */ - quote: string; -}> - -/** - * Parses a JSON5 string, constructing the JavaScript value or object described - * by the string. An optional reviver function can be provided to perform a - * transformation on the resulting object before it is returned. - * @param text The string to parse as JSON5. - * @param reviver If a function, this prescribes how the value originally - * produced by parsing is transformed, before being returned. - */ -export function parse(text: string, reviver?: (this: any, key: string, value: any) => any): any; - -/** - * Converts a JavaScript value to a JSON5 string, optionally replacing values - * if a replacer function is specified, or optionally including only the - * specified properties if a replacer array is specified. - * @param value The value to convert to a JSON5 string. - * @param replacer A function that alters the behavior of the stringification - * process, or an array of String and Number objects that serve as a whitelist - * for selecting/filtering the properties of the value object to be included in - * the JSON5 string. If this value is null or not provided, all properties of - * the object are included in the resulting JSON5 string. - * @param space A String or Number object that's used to insert white space - * into the output JSON5 string for readability purposes. If this is a Number, - * it indicates the number of space characters to use as white space; this - * number is capped at 10 (if it is greater, the value is just 10). Values less - * than 1 indicate that no space should be used. If this is a String, the - * string (or the first 10 characters of the string, if it's longer than that) - * is used as white space. If this parameter is not provided (or is null), no - * white space is used. If white space is used, trailing commas will be used in - * objects and arrays. - */ -export function stringify(value: any, replacer?: ((this: any, key: string, value: any) => any) | (string | number)[], space?: string | number): string; - -/** - * Converts a JavaScript value to a JSON5 string, optionally replacing values - * if a replacer function is specified, or optionally including only the - * specified properties if a replacer array is specified. - * @param value The value to convert to a JSON5 string. - * @param options An object with the following properties: - * - * `replacer`: Same as the `replacer` parameter. - * - * `space`: Same as the `space` parameter. - * - * `quote`: A String representing the quote character to use when serializing - * strings. - */ -export function stringify(value: any, options?: StringifyOptions): string; +export {parse, stringify} diff --git a/lib/parse.d.ts b/lib/parse.d.ts new file mode 100644 index 00000000..8c8d883a --- /dev/null +++ b/lib/parse.d.ts @@ -0,0 +1,15 @@ +/** + * Parses a JSON5 string, constructing the JavaScript value or object described + * by the string. + * @template T The type of the return value. + * @param text The string to parse as JSON5. + * @param reviver A function that prescribes how the value originally produced + * by parsing is transformed before being returned. + * @returns The JavaScript value converted from the JSON5 string. + */ +declare function parse( + text: string, + reviver?: ((this: any, key: string, value: any) => any) | null, +): T + +export = parse diff --git a/lib/stringify.d.ts b/lib/stringify.d.ts new file mode 100644 index 00000000..3c348389 --- /dev/null +++ b/lib/stringify.d.ts @@ -0,0 +1,89 @@ +declare type StringifyOptions = { + /** + * A function that alters the behavior of the stringification process, or an + * array of String and Number objects that serve as a allowlist for + * selecting/filtering the properties of the value object to be included in + * the JSON5 string. If this value is null or not provided, all properties + * of the object are included in the resulting JSON5 string. + */ + replacer?: + | ((this: any, key: string, value: any) => any) + | (string | number)[] + | null + + /** + * A String or Number object that's used to insert white space into the + * output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this + * number is capped at 10 (if it is greater, the value is just 10). Values + * less than 1 indicate that no space should be used. If this is a String, + * the string (or the first 10 characters of the string, if it's longer than + * that) is used as white space. If this parameter is not provided (or is + * null), no white space is used. If white space is used, trailing commas + * will be used in objects and arrays. + */ + space?: string | number | null + + /** + * A String representing the quote character to use when serializing + * strings. + */ + quote?: string | null +} + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param replacer A function that alters the behavior of the stringification + * process. If this value is null or not provided, all properties of the object + * are included in the resulting JSON5 string. + * @param space A String or Number object that's used to insert white space into + * the output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this number + * is capped at 10 (if it is greater, the value is just 10). Values less than 1 + * indicate that no space should be used. If this is a String, the string (or + * the first 10 characters of the string, if it's longer than that) is used as + * white space. If this parameter is not provided (or is null), no white space + * is used. If white space is used, trailing commas will be used in objects and + * arrays. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify( + value: any, + replacer?: ((this: any, key: string, value: any) => any) | null, + space?: string | number | null, +): string + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param replacer An array of String and Number objects that serve as a + * allowlist for selecting/filtering the properties of the value object to be + * included in the JSON5 string. If this value is null or not provided, all + * properties of the object are included in the resulting JSON5 string. + * @param space A String or Number object that's used to insert white space into + * the output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this number + * is capped at 10 (if it is greater, the value is just 10). Values less than 1 + * indicate that no space should be used. If this is a String, the string (or + * the first 10 characters of the string, if it's longer than that) is used as + * white space. If this parameter is not provided (or is null), no white space + * is used. If white space is used, trailing commas will be used in objects and + * arrays. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify( + value: any, + replacer: (string | number)[], + space?: string | number | null, +): string + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param options An object specifying options. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify(value: any, options: StringifyOptions): string + +export = stringify diff --git a/lib/unicode.d.ts b/lib/unicode.d.ts new file mode 100644 index 00000000..610f8057 --- /dev/null +++ b/lib/unicode.d.ts @@ -0,0 +1,3 @@ +export declare const Space_Separator: RegExp +export declare const ID_Start: RegExp +export declare const ID_Continue: RegExp diff --git a/lib/util.d.ts b/lib/util.d.ts new file mode 100644 index 00000000..a940cead --- /dev/null +++ b/lib/util.d.ts @@ -0,0 +1,5 @@ +export declare function isSpaceSeparator(c?: string): boolean +export declare function isIdStartChar(c?: string): boolean +export declare function isIdContinueChar(c?: string): boolean +export declare function isDigit(c?: string): boolean +export declare function isHexDigit(c?: string): boolean diff --git a/package.json5 b/package.json5 index f3fc10bd..f890d644 100644 --- a/package.json5 +++ b/package.json5 @@ -7,6 +7,7 @@ module: 'dist/index.mjs', bin: 'lib/cli.js', browser: 'dist/index.js', + types: 'lib/index.d.ts', files: [ 'lib/', 'dist/', From 4d0560c1b16d827f46339dc7cf2ea05500298b5f Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sun, 31 Jan 2021 19:18:01 -0600 Subject: [PATCH 03/40] docs: add missing links to CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 538e9a5e..86ec7b20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -350,5 +350,8 @@ parser for the regular JSON format. [#196]: https://github.com/json5/json5/issues/196 [#208]: https://github.com/json5/json5/issues/208 [#210]: https://github.com/json5/json5/issues/210 +[#222]: https://github.com/json5/json5/issues/222 +[#228]: https://github.com/json5/json5/issues/228 +[#229]: https://github.com/json5/json5/issues/229 [#236]: https://github.com/json5/json5/issues/236 [#244]: https://github.com/json5/json5/issues/244 From 39ad97c006ae8c961cd2e5910bb032bce8ac2264 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sun, 31 Jan 2021 19:48:27 -0600 Subject: [PATCH 04/40] docs: update Travis CI badge --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4f803270..6049d02c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # JSON5 – JSON for Humans -[![Build Status](https://travis-ci.org/json5/json5.svg)][Build Status] +[![Build Status](https://travis-ci.com/json5/json5.svg)][Build Status] [![Coverage Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage Status] @@ -12,7 +12,7 @@ some productions from [ECMAScript 5.1]. This JavaScript library is the official reference implementation for JSON5 parsing and serialization libraries. -[Build Status]: https://travis-ci.org/json5/json5 +[Build Status]: https://travis-ci.com/json5/json5 [Coverage Status]: https://coveralls.io/github/json5/json5 From a14feb050fddd5ced20596355a2531273b986b09 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sun, 31 Jan 2021 19:52:45 -0600 Subject: [PATCH 05/40] docs: update CHANGELOG for v2.2.0 --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86ec7b20..5b9aa0d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ ### Unreleased [[code][c-unreleased], [diff][d-unreleased]] [c-unreleased]: https://github.com/json5/json5/tree/master -[d-unreleased]: https://github.com/json5/json5/compare/v2.1.3...HEAD +[d-unreleased]: https://github.com/json5/json5/compare/v2.2.0...HEAD + +### v2.2.0 [[code][c2.2.0], [diff][d2.2.0]] + +[c2.2.0]: https://github.com/json5/json5/tree/v2.2.0 +[d2.2.0]: https://github.com/json5/json5/compare/v2.1.3...v2.2.0 - New: Accurate and documented TypeScript declarations are now included. There is no need to install `@types/json5`. ([#236], [#244]) From 4cf57da675f55c619f959132eb58a5683ca4a9c7 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sun, 31 Jan 2021 19:53:09 -0600 Subject: [PATCH 06/40] 2.2.0 --- package-lock.json | 2 +- package.json | 2 +- package.json5 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 92d5e881..56c0f4de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "json5", - "version": "2.1.3", + "version": "2.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3b3b79a5..31c43e5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "json5", - "version": "2.1.3", + "version": "2.2.0", "description": "JSON for humans.", "main": "lib/index.js", "module": "dist/index.mjs", diff --git a/package.json5 b/package.json5 index f890d644..afcfbe26 100644 --- a/package.json5 +++ b/package.json5 @@ -1,7 +1,7 @@ // This is a generated file. Do not edit. { name: 'json5', - version: '2.1.3', + version: '2.2.0', description: 'JSON for humans.', main: 'lib/index.js', module: 'dist/index.mjs', From 7466552d79e1f97a602e96882e4ce344a944f0cc Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Mon, 21 Mar 2022 11:00:34 -0500 Subject: [PATCH 07/40] fix: remove minimist --- CHANGELOG.md | 3 + lib/cli.js | 90 +++++++++++++++++++++--------- package-lock.json | 3 +- package.json | 3 - test/cli.js | 139 +++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 201 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b9aa0d2..cb0e0096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ### Unreleased [[code][c-unreleased], [diff][d-unreleased]] +- Fix: Remove dependence on minimist to patch CVE-2021-44906. ([#266]) + [c-unreleased]: https://github.com/json5/json5/tree/master [d-unreleased]: https://github.com/json5/json5/compare/v2.2.0...HEAD @@ -360,3 +362,4 @@ parser for the regular JSON format. [#229]: https://github.com/json5/json5/issues/229 [#236]: https://github.com/json5/json5/issues/236 [#244]: https://github.com/json5/json5/issues/244 +[#266]: https://github.com/json5/json5/issues/266 diff --git a/lib/cli.js b/lib/cli.js index de852f15..93cb8092 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -2,37 +2,17 @@ const fs = require('fs') const path = require('path') -const minimist = require('minimist') const pkg = require('../package.json') const JSON5 = require('./') -const argv = minimist(process.argv.slice(2), { - alias: { - 'convert': 'c', - 'space': 's', - 'validate': 'v', - 'out-file': 'o', - 'version': 'V', - 'help': 'h', - }, - boolean: [ - 'convert', - 'validate', - 'version', - 'help', - ], - string: [ - 'space', - 'out-file', - ], -}) +const argv = parseArgs() if (argv.version) { version() } else if (argv.help) { usage() } else { - const inFilename = argv._[0] + const inFilename = argv.defaults[0] let readStream if (inFilename) { @@ -65,7 +45,7 @@ if (argv.version) { // --convert is for backward compatibility with v0.5.1. If // specified with and not --out-file, then a file with // the same name but with a .json extension will be written. - if (argv.convert && inFilename && !argv.o) { + if (argv.convert && inFilename && !argv.outFile) { const parsedFilename = path.parse(inFilename) const outFilename = path.format( Object.assign( @@ -75,8 +55,8 @@ if (argv.version) { ) writeStream = fs.createWriteStream(outFilename) - } else if (argv.o) { - writeStream = fs.createWriteStream(argv.o) + } else if (argv.outFile) { + writeStream = fs.createWriteStream(argv.outFile) } else { writeStream = process.stdout } @@ -90,6 +70,66 @@ if (argv.version) { }) } +function parseArgs () { + let convert + let space + let validate + let outFile + let version + let help + const defaults = [] + + const args = process.argv.slice(2) + for (let i = 0; i < args.length; i++) { + const arg = args[i] + switch (arg) { + case '--convert': + case '-c': + convert = true + break + + case '--space': + case '-s': + space = args[++i] + break + + case '--validate': + case '-v': + validate = true + break + + case '--out-file': + case '-o': + outFile = args[++i] + break + + case '--version': + case '-V': + version = true + break + + case '--help': + case '-h': + help = true + break + + default: + defaults.push(arg) + break + } + } + + return { + convert, + space, + validate, + outFile, + version, + help, + defaults, + } +} + function version () { console.log(pkg.version) } diff --git a/package-lock.json b/package-lock.json index 56c0f4de..972a303d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2184,7 +2184,8 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "minipass": { "version": "2.3.5", diff --git a/package.json b/package.json index 31c43e5f..f33153b1 100644 --- a/package.json +++ b/package.json @@ -48,9 +48,6 @@ "url": "https://github.com/json5/json5/issues" }, "homepage": "http://json5.org/", - "dependencies": { - "minimist": "^1.2.5" - }, "devDependencies": { "core-js": "^2.6.5", "eslint": "^5.15.3", diff --git a/test/cli.js b/test/cli.js index 8ddef73a..c52dd926 100644 --- a/test/cli.js +++ b/test/cli.js @@ -43,7 +43,7 @@ tap.test('CLI', t => { }) }) - t.test('indents output with the number of spaces specified', t => { + t.test('indents output with the number of spaces specified with -s', t => { const proc = child.spawn( process.execPath, [ @@ -65,7 +65,29 @@ tap.test('CLI', t => { }) }) - t.test('indents output with tabs when specified', t => { + t.test('indents output with the number of spaces specified with --space', t => { + const proc = child.spawn( + process.execPath, + [ + cliPath, + path.resolve(__dirname, 'test.json5'), + '--space', + '4', + ] + ) + + let output = '' + proc.stdout.on('data', data => { + output += data + }) + + proc.stdout.on('end', () => { + assert.strictEqual(output, '{\n "a": 1,\n "b": 2\n}') + t.end() + }) + }) + + t.test('indents output with tabs when specified with -s', t => { const proc = child.spawn( process.execPath, [ @@ -87,7 +109,7 @@ tap.test('CLI', t => { }) }) - t.test('outputs to the specified file', t => { + t.test('outputs to the specified file with -o', t => { const proc = child.spawn( process.execPath, [ @@ -116,7 +138,36 @@ tap.test('CLI', t => { }) }) - t.test('validates valid JSON5 files', t => { + t.test('outputs to the specified file with --out-file', t => { + const proc = child.spawn( + process.execPath, + [ + cliPath, + path.resolve(__dirname, 'test.json5'), + '--out-file', + path.resolve(__dirname, 'output.json'), + ] + ) + + proc.on('exit', () => { + assert.strictEqual( + fs.readFileSync( + path.resolve(__dirname, 'output.json'), + 'utf8' + ), + '{"a":1,"b":2}' + ) + t.end() + }) + + t.tearDown(() => { + try { + fs.unlinkSync(path.resolve(__dirname, 'output.json')) + } catch (err) {} + }) + }) + + t.test('validates valid JSON5 files with -v', t => { const proc = child.spawn( process.execPath, [ @@ -132,7 +183,23 @@ tap.test('CLI', t => { }) }) - t.test('validates invalid JSON5 files', t => { + t.test('validates valid JSON5 files with --validate', t => { + const proc = child.spawn( + process.execPath, + [ + cliPath, + path.resolve(__dirname, 'test.json5'), + '--validate', + ] + ) + + proc.on('exit', code => { + assert.strictEqual(code, 0) + t.end() + }) + }) + + t.test('validates invalid JSON5 files with -v', t => { const proc = child.spawn( process.execPath, [ @@ -157,7 +224,7 @@ tap.test('CLI', t => { }) }) - t.test('outputs the version number when specified', t => { + t.test('outputs the version number when specified with -V', t => { const proc = child.spawn(process.execPath, [cliPath, '-V']) let output = '' @@ -171,7 +238,21 @@ tap.test('CLI', t => { }) }) - t.test('outputs usage information when specified', t => { + t.test('outputs the version number when specified with --version', t => { + const proc = child.spawn(process.execPath, [cliPath, '--version']) + + let output = '' + proc.stdout.on('data', data => { + output += data + }) + + proc.stdout.on('end', () => { + assert.strictEqual(output, pkg.version + '\n') + t.end() + }) + }) + + t.test('outputs usage information when specified with -h', t => { const proc = child.spawn(process.execPath, [cliPath, '-h']) let output = '' @@ -185,7 +266,21 @@ tap.test('CLI', t => { }) }) - t.test('is backward compatible with v0.5.1', t => { + t.test('outputs usage information when specified with --help', t => { + const proc = child.spawn(process.execPath, [cliPath, '--help']) + + let output = '' + proc.stdout.on('data', data => { + output += data + }) + + proc.stdout.on('end', () => { + assert(/Usage/.test(output)) + t.end() + }) + }) + + t.test('is backward compatible with v0.5.1 with -c', t => { const proc = child.spawn( process.execPath, [ @@ -213,5 +308,33 @@ tap.test('CLI', t => { }) }) + t.test('is backward compatible with v0.5.1 with --convert', t => { + const proc = child.spawn( + process.execPath, + [ + cliPath, + '--convert', + path.resolve(__dirname, 'test.json5'), + ] + ) + + proc.on('exit', () => { + assert.strictEqual( + fs.readFileSync( + path.resolve(__dirname, 'test.json'), + 'utf8' + ), + '{"a":1,"b":2}' + ) + t.end() + }) + + t.tearDown(() => { + try { + fs.unlinkSync(path.resolve(__dirname, 'test.json')) + } catch (err) {} + }) + }) + t.end() }) From 905e17ae04f3bc6b6293b27a30034373ac6e2347 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Mon, 21 Mar 2022 11:28:11 -0500 Subject: [PATCH 08/40] docs: update CHANGELOG for v2.2.1 --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb0e0096..06688a3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,15 @@ ### Unreleased [[code][c-unreleased], [diff][d-unreleased]] -- Fix: Remove dependence on minimist to patch CVE-2021-44906. ([#266]) - [c-unreleased]: https://github.com/json5/json5/tree/master [d-unreleased]: https://github.com/json5/json5/compare/v2.2.0...HEAD +### v2.2.1 [[code][c2.2.1], [diff][d2.2.1]] + +[c2.2.1]: https://github.com/json5/json5/tree/v2.2.1 +[d2.2.1]: https://github.com/json5/json5/compare/v2.2.0...v2.2.1 + +- Fix: Removed dependence on minimist to patch CVE-2021-44906. ([#266]) + ### v2.2.0 [[code][c2.2.0], [diff][d2.2.0]] [c2.2.0]: https://github.com/json5/json5/tree/v2.2.0 From 502da86f8e8e2168e301dc5157919935082d0f7b Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Mon, 21 Mar 2022 11:30:35 -0500 Subject: [PATCH 09/40] 2.2.1 --- package-lock.json | 2 +- package.json | 2 +- package.json5 | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 972a303d..c4e0207d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "json5", - "version": "2.2.0", + "version": "2.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f33153b1..ec68d1c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "json5", - "version": "2.2.0", + "version": "2.2.1", "description": "JSON for humans.", "main": "lib/index.js", "module": "dist/index.mjs", diff --git a/package.json5 b/package.json5 index afcfbe26..2bbfb413 100644 --- a/package.json5 +++ b/package.json5 @@ -1,7 +1,7 @@ // This is a generated file. Do not edit. { name: 'json5', - version: '2.2.0', + version: '2.2.1', description: 'JSON for humans.', main: 'lib/index.js', module: 'dist/index.mjs', @@ -49,9 +49,6 @@ url: 'https://github.com/json5/json5/issues', }, homepage: 'http://json5.org/', - dependencies: { - minimist: '^1.2.5', - }, devDependencies: { 'core-js': '^2.6.5', eslint: '^5.15.3', From 5cd538046f8f3a2c94ed295a5ed9c8de30c9e2e6 Mon Sep 17 00:00:00 2001 From: rhysd Date: Sat, 4 Jun 2022 13:08:37 +0900 Subject: [PATCH 10/40] ci: add GitHub Actions workflow --- .github/workflows/ci.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..feb4212a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: CI +on: [push, pull_request] + +jobs: + test: + strategy: + matrix: + node: ['14', '16', '18'] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '${{ matrix.node }}' + cache: npm + - run: npm install + - run: npm test + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 'lts/*' + cache: npm + - run: npm install + - run: npm run lint From b9bc45a7c4c23fce0c651408649dde41e2d547d5 Mon Sep 17 00:00:00 2001 From: rhysd Date: Sat, 4 Jun 2022 13:14:29 +0900 Subject: [PATCH 11/40] ci: replace Travis CI badge with GitHub Actions badge --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6049d02c..7472e0d8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ # JSON5 – JSON for Humans -[![Build Status](https://travis-ci.com/json5/json5.svg)][Build Status] -[![Coverage -Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage -Status] +[![Build Status](https://github.com/json5/json5/actions/workflows/ci.yml/badge.svg)][Build Status] +[![Coverage Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage Status] The JSON5 Data Interchange Format (JSON5) is a superset of [JSON] that aims to alleviate some of the limitations of JSON by expanding its syntax to include @@ -12,7 +10,7 @@ some productions from [ECMAScript 5.1]. This JavaScript library is the official reference implementation for JSON5 parsing and serialization libraries. -[Build Status]: https://travis-ci.com/json5/json5 +[Build Status]: https://github.com/json5/json5/actions/workflows/ci.yml [Coverage Status]: https://coveralls.io/github/json5/json5 From dab49b47a5697b8ba97778b05d8af95cdb800dd2 Mon Sep 17 00:00:00 2001 From: rhysd Date: Sat, 4 Jun 2022 13:16:31 +0900 Subject: [PATCH 12/40] ci: remove .travis.yml --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7716b7b5..00000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: node_js -node_js: - - "11" - - "10" - - "8" - - "6" From 1f4cbd3368d5167898eca0f5ab3a5b5d146cd2bc Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Tue, 14 Jun 2022 11:03:41 -0700 Subject: [PATCH 13/40] Revert "Replace Travis CI with GitHub Actions" --- .github/workflows/ci.yml | 27 --------------------------- .travis.yml | 6 ++++++ README.md | 8 +++++--- 3 files changed, 11 insertions(+), 30 deletions(-) delete mode 100644 .github/workflows/ci.yml create mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index feb4212a..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: CI -on: [push, pull_request] - -jobs: - test: - strategy: - matrix: - node: ['14', '16', '18'] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: '${{ matrix.node }}' - cache: npm - - run: npm install - - run: npm test - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 'lts/*' - cache: npm - - run: npm install - - run: npm run lint diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..7716b7b5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "11" + - "10" + - "8" + - "6" diff --git a/README.md b/README.md index 7472e0d8..6049d02c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # JSON5 – JSON for Humans -[![Build Status](https://github.com/json5/json5/actions/workflows/ci.yml/badge.svg)][Build Status] -[![Coverage Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage Status] +[![Build Status](https://travis-ci.com/json5/json5.svg)][Build Status] +[![Coverage +Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage +Status] The JSON5 Data Interchange Format (JSON5) is a superset of [JSON] that aims to alleviate some of the limitations of JSON by expanding its syntax to include @@ -10,7 +12,7 @@ some productions from [ECMAScript 5.1]. This JavaScript library is the official reference implementation for JSON5 parsing and serialization libraries. -[Build Status]: https://github.com/json5/json5/actions/workflows/ci.yml +[Build Status]: https://travis-ci.com/json5/json5 [Coverage Status]: https://coveralls.io/github/json5/json5 From 78c3502c3a5ddbb296cde78218f22efcac6abe2a Mon Sep 17 00:00:00 2001 From: Lei Chen Date: Mon, 13 Jun 2022 13:48:28 +0800 Subject: [PATCH 14/40] chore: fix broken travis-ci status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6049d02c..c51fb1cc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # JSON5 – JSON for Humans -[![Build Status](https://travis-ci.com/json5/json5.svg)][Build Status] +[![Build Status](https://api.travis-ci.com/json5/json5.svg?branch=master)][Build Status] [![Coverage Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage Status] From 11cc33f2bb0d207f97a378636af33071378fa841 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Tue, 14 Jun 2022 11:33:52 -0700 Subject: [PATCH 15/40] ci: remove Node.js v6 from Travis due to npm bug --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7716b7b5..931847ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,3 @@ node_js: - "11" - "10" - "8" - - "6" From 8b4c65b3e75735de8cb7555aa8a1194ade4269c0 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Tue, 14 Jun 2022 11:49:46 -0700 Subject: [PATCH 16/40] docs: update Travis CI badge and link --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c51fb1cc..e33bc260 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # JSON5 – JSON for Humans -[![Build Status](https://api.travis-ci.com/json5/json5.svg?branch=master)][Build Status] -[![Coverage +[![Build Status](https://app.travis-ci.com/json5/json5.svg?branch=master)][Build +Status] [![Coverage Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage Status] @@ -12,7 +12,7 @@ some productions from [ECMAScript 5.1]. This JavaScript library is the official reference implementation for JSON5 parsing and serialization libraries. -[Build Status]: https://travis-ci.com/json5/json5 +[Build Status]: https://app.travis-ci.com/json5/json5 [Coverage Status]: https://coveralls.io/github/json5/json5 From a71e39392cc20c488197eaed538fe29d477850c1 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Tue, 14 Jun 2022 12:12:23 -0700 Subject: [PATCH 17/40] docs: rename master branch to main --- CHANGELOG.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06688a3f..b1eab331 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ### Unreleased [[code][c-unreleased], [diff][d-unreleased]] -[c-unreleased]: https://github.com/json5/json5/tree/master +[c-unreleased]: https://github.com/json5/json5/tree/main [d-unreleased]: https://github.com/json5/json5/compare/v2.2.0...HEAD ### v2.2.1 [[code][c2.2.1], [diff][d2.2.1]] diff --git a/README.md b/README.md index e33bc260..5ffb92e9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # JSON5 – JSON for Humans -[![Build Status](https://app.travis-ci.com/json5/json5.svg?branch=master)][Build +[![Build Status](https://app.travis-ci.com/json5/json5.svg?branch=main)][Build Status] [![Coverage Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage Status] From fa6abe6b38b4986d8cc8fb2f693a43a1fad391f2 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Tue, 14 Jun 2022 20:02:18 -0700 Subject: [PATCH 18/40] build: use npm-run-all --- package-lock.json | 432 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- package.json5 | 3 +- 3 files changed, 436 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index c4e0207d..7d16fe78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -563,6 +563,16 @@ "unset-value": "^1.0.0" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", @@ -801,6 +811,16 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -894,6 +914,48 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1542,12 +1604,51 @@ "integrity": "sha1-gHa7MF6OajzO7ikgdl8zDRkPNAw=", "dev": true }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -1620,12 +1721,42 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -1771,6 +1902,17 @@ } } }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -1797,12 +1939,37 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -1823,6 +1990,15 @@ } } }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -1860,6 +2036,12 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -1880,6 +2062,15 @@ } } }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -1895,12 +2086,58 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -1980,6 +2217,12 @@ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -2130,6 +2373,12 @@ "object-visit": "^1.0.0" } }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -2311,6 +2560,73 @@ "validate-npm-package-license": "^3.0.1" } }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "dependencies": { + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + } + } + }, "nyc": { "version": "13.3.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz", @@ -3382,6 +3698,18 @@ } } }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -3391,6 +3719,18 @@ "isobject": "^3.0.0" } }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -3569,6 +3909,12 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -3695,6 +4041,17 @@ "safe-regex": "^1.1.0" } }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -3978,6 +4335,23 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "shell-quote": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -4282,6 +4656,39 @@ "strip-ansi": "^4.0.0" } }, + "string.prototype.padend": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz", + "integrity": "sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -4655,6 +5062,18 @@ "integrity": "sha512-jjOcCZvpkl2+z7JFn0yBOoLQyLoIkNZAs/fYJkUG6VKy6zLPHJGfQJYFHzibB6GJaF/8QrcECtlQ5cpvRHSMEA==", "dev": true }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, "unicode-10.0.0": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/unicode-10.0.0/-/unicode-10.0.0-0.7.5.tgz", @@ -4861,6 +5280,19 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", diff --git a/package.json b/package.json index ec68d1c5..e7860129 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "lint": "eslint --fix .", "prepublishOnly": "npm run production", "preversion": "npm run production", - "production": "npm run lint && npm test && npm run build", + "production": "run-s lint test build", "test": "tap -Rspec --100 test", "version": "npm run build-package && git add package.json5" }, @@ -56,6 +56,7 @@ "eslint-plugin-node": "^8.0.1", "eslint-plugin-promise": "^4.0.1", "eslint-plugin-standard": "^4.0.0", + "npm-run-all": "^4.1.5", "regenerate": "^1.4.0", "rollup": "^0.64.1", "rollup-plugin-buble": "^0.19.6", diff --git a/package.json5 b/package.json5 index 2bbfb413..8b74d2cf 100644 --- a/package.json5 +++ b/package.json5 @@ -23,7 +23,7 @@ lint: 'eslint --fix .', prepublishOnly: 'npm run production', preversion: 'npm run production', - production: 'npm run lint && npm test && npm run build', + production: 'run-s lint test build', test: 'tap -Rspec --100 test', version: 'npm run build-package && git add package.json5', }, @@ -57,6 +57,7 @@ 'eslint-plugin-node': '^8.0.1', 'eslint-plugin-promise': '^4.0.1', 'eslint-plugin-standard': '^4.0.0', + 'npm-run-all': '^4.1.5', regenerate: '^1.4.0', rollup: '^0.64.1', 'rollup-plugin-buble': '^0.19.6', From ccfd4106f7d6af888b584cdaa4c7185258bf4347 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Tue, 14 Jun 2022 20:11:35 -0700 Subject: [PATCH 19/40] build: lint before testing --- package.json | 6 ++++-- package.json5 | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e7860129..41a3f68f 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,12 @@ "build-unicode": "node build/unicode.js", "coverage": "tap --coverage-report html test", "lint": "eslint --fix .", + "lint-report": "eslint .", "prepublishOnly": "npm run production", "preversion": "npm run production", - "production": "run-s lint test build", - "test": "tap -Rspec --100 test", + "production": "run-s test build", + "tap": "tap -Rspec --100 test", + "test": "run-s lint-report tap", "version": "npm run build-package && git add package.json5" }, "repository": { diff --git a/package.json5 b/package.json5 index 8b74d2cf..4d11841e 100644 --- a/package.json5 +++ b/package.json5 @@ -21,10 +21,12 @@ 'build-unicode': 'node build/unicode.js', coverage: 'tap --coverage-report html test', lint: 'eslint --fix .', + 'lint-report': 'eslint .', prepublishOnly: 'npm run production', preversion: 'npm run production', - production: 'run-s lint test build', - test: 'tap -Rspec --100 test', + production: 'run-s test build', + tap: 'tap -Rspec --100 test', + test: 'run-s lint-report tap', version: 'npm run build-package && git add package.json5', }, repository: { From 5a2740f6f1be202684e232a0c3cea7e4dcb59452 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sat, 18 Jun 2022 17:25:29 -0600 Subject: [PATCH 20/40] docs: update incorrect link in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1eab331..a20fa52c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ### Unreleased [[code][c-unreleased], [diff][d-unreleased]] [c-unreleased]: https://github.com/json5/json5/tree/main -[d-unreleased]: https://github.com/json5/json5/compare/v2.2.0...HEAD +[d-unreleased]: https://github.com/json5/json5/compare/v2.2.1...HEAD ### v2.2.1 [[code][c2.2.1], [diff][d2.2.1]] From 49521084a5731ee57dce1dedf86052c7f6d48f42 Mon Sep 17 00:00:00 2001 From: Vas Sudanagunta Date: Tue, 7 Dec 2021 19:57:33 -0800 Subject: [PATCH 21/40] Add ESM usage to README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5ffb92e9..f1a28d9d 100644 --- a/README.md +++ b/README.md @@ -78,10 +78,16 @@ specification](https://json5.github.io/json5-spec/). npm install json5 ``` +CJS: ```js const JSON5 = require('json5') ``` +ESM: +```js +import JSON5 from 'json5' +``` + ### Browsers ```html From abbd1276cf439e1689e57acdc4dc1b7f6f076459 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Mon, 8 Aug 2022 21:22:40 -0500 Subject: [PATCH 22/40] docs: update headers for CJS and modules usage --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f1a28d9d..dec00e6f 100644 --- a/README.md +++ b/README.md @@ -78,12 +78,12 @@ specification](https://json5.github.io/json5-spec/). npm install json5 ``` -CJS: +### CommonJS ```js const JSON5 = require('json5') ``` -ESM: +### Modules ```js import JSON5 from 'json5' ``` From a84bca4be7188c8b4eb414b2ad9f8f10d1e25587 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Mon, 8 Aug 2022 21:27:34 -0500 Subject: [PATCH 23/40] docs: update Installation and Usage header --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dec00e6f..dfb36bff 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ No \\n's!", For a detailed explanation of the JSON5 format, please read the [official specification](https://json5.github.io/json5-spec/). -## Installation +## Installation and Usage ### Node.js ```sh npm install json5 From 577c85616282820f4e02e9f370a991b9a0a4c900 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Mon, 8 Aug 2022 21:27:55 -0500 Subject: [PATCH 24/40] docs: update browser usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dfb36bff..040b848f 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ import JSON5 from 'json5' ### Browsers ```html - + ``` This will create a global `JSON5` variable. From 43042bd2931af43927a9c3952ec52b82deda01b8 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Thu, 11 Aug 2022 19:00:19 -0500 Subject: [PATCH 25/40] docs: update package descript to match branding --- package.json | 2 +- package.json5 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 41a3f68f..70e5f669 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "json5", "version": "2.2.1", - "description": "JSON for humans.", + "description": "JSON for Humans", "main": "lib/index.js", "module": "dist/index.mjs", "bin": "lib/cli.js", diff --git a/package.json5 b/package.json5 index 4d11841e..027a098a 100644 --- a/package.json5 +++ b/package.json5 @@ -2,7 +2,7 @@ { name: 'json5', version: '2.2.1', - description: 'JSON for humans.', + description: 'JSON for Humans', main: 'lib/index.js', module: 'dist/index.mjs', bin: 'lib/cli.js', From 4798b9dbde850c8e84e59ac58ba2894ef184434d Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Thu, 11 Aug 2022 19:11:20 -0500 Subject: [PATCH 26/40] docs: update installation and usage for modules --- README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 040b848f..8fa3edb4 100644 --- a/README.md +++ b/README.md @@ -78,22 +78,29 @@ specification](https://json5.github.io/json5-spec/). npm install json5 ``` -### CommonJS +#### CommonJS ```js const JSON5 = require('json5') ``` -### Modules +#### Modules ```js import JSON5 from 'json5' ``` ### Browsers +#### UMD ```html + ``` -This will create a global `JSON5` variable. +#### Modules +```html + +``` ## API The JSON5 API is compatible with the [JSON API]. From 6d426865cec0ba7e20d4a98341e61cf26176b8fb Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Thu, 11 Aug 2022 11:28:56 -0500 Subject: [PATCH 27/40] test: remove mocha syntax from tests --- test/.eslintrc.json | 5 - test/errors.js | 809 ++++++++++++++++++++------------------------ test/parse.js | 2 - test/require.js | 15 +- test/stringify.js | 590 ++++++++++++++++++++------------ 5 files changed, 747 insertions(+), 674 deletions(-) delete mode 100644 test/.eslintrc.json diff --git a/test/.eslintrc.json b/test/.eslintrc.json deleted file mode 100644 index 4668ae79..00000000 --- a/test/.eslintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "env": { - "mocha": true - } -} diff --git a/test/errors.js b/test/errors.js index 1d1657c6..50f590cf 100644 --- a/test/errors.js +++ b/test/errors.js @@ -1,444 +1,377 @@ -const assert = require('assert') const JSON5 = require('../lib') -require('tap').mochaGlobals() - -describe('JSON5', () => { - describe('#parse()', () => { - describe('errors', () => { - it('throws on empty documents', () => { - assert.throws(() => { - JSON5.parse('') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 1 - )) - }) - - it('throws on documents with only comments', () => { - assert.throws(() => { - JSON5.parse('//a') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 4 - )) - }) - - it('throws on incomplete single line comments', () => { - assert.throws(() => { - JSON5.parse('/a') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'a'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 2 - )) - }) - - it('throws on unterminated multiline comments', () => { - assert.throws(() => { - JSON5.parse('/*') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on unterminated multiline comment closings', () => { - assert.throws(() => { - JSON5.parse('/**') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 4 - )) - }) - - it('throws on invalid characters in values', () => { - assert.throws(() => { - JSON5.parse('a') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'a'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 1 - )) - }) - - it('throws on invalid characters in identifier start escapes', () => { - assert.throws(() => { - JSON5.parse('{\\a:1}') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'a'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on invalid identifier start characters', () => { - assert.throws(() => { - JSON5.parse('{\\u0021:1}') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid identifier character/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 2 - )) - }) - - it('throws on invalid characters in identifier continue escapes', () => { - assert.throws(() => { - JSON5.parse('{a\\a:1}') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'a'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 4 - )) - }) - - it('throws on invalid identifier continue characters', () => { - assert.throws(() => { - JSON5.parse('{a\\u0021:1}') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid identifier character/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on invalid characters following a sign', () => { - assert.throws(() => { - JSON5.parse('-a') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'a'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 2 - )) - }) - - it('throws on invalid characters following a leading decimal point', () => { - assert.throws(() => { - JSON5.parse('.a') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'a'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 2 - )) - }) - - it('throws on invalid characters following an exponent indicator', () => { - assert.throws(() => { - JSON5.parse('1ea') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'a'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on invalid characters following an exponent sign', () => { - assert.throws(() => { - JSON5.parse('1e-a') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'a'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 4 - )) - }) - - it('throws on invalid characters following a hexadecimal indicator', () => { - assert.throws(() => { - JSON5.parse('0xg') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'g'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on invalid new lines in strings', () => { - assert.throws(() => { - JSON5.parse('"\n"') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '\\n'/.test(err.message) && - err.lineNumber === 2 && - err.columnNumber === 0 - )) - }) - - it('throws on unterminated strings', () => { - assert.throws(() => { - JSON5.parse('"') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 2 - )) - }) - - it('throws on invalid identifier start characters in property names', () => { - assert.throws(() => { - JSON5.parse('{!:1}') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '!'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 2 - )) - }) - - it('throws on invalid characters following a property name', () => { - assert.throws(() => { - JSON5.parse('{a!1}') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '!'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on invalid characters following a property value', () => { - assert.throws(() => { - JSON5.parse('{a:1!}') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '!'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 5 - )) - }) - - it('throws on invalid characters following an array value', () => { - assert.throws(() => { - JSON5.parse('[1!]') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '!'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on invalid characters in literals', () => { - assert.throws(() => { - JSON5.parse('tru!') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '!'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 4 - )) - }) - - it('throws on unterminated escapes', () => { - assert.throws(() => { - JSON5.parse('"\\') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on invalid first digits in hexadecimal escapes', () => { - assert.throws(() => { - JSON5.parse('"\\xg"') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'g'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 4 - )) - }) - - it('throws on invalid second digits in hexadecimal escapes', () => { - assert.throws(() => { - JSON5.parse('"\\x0g"') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'g'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 5 - )) - }) - - it('throws on invalid unicode escapes', () => { - assert.throws(() => { - JSON5.parse('"\\u000g"') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character 'g'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 7 - )) - }) - - it('throws on escaped digits other than 0', () => { - for (let i = 1; i <= 9; i++) { - assert.throws(() => { - JSON5.parse(`'\\${i}'`) +const t = require('tap') + +t.test('JSON5', t => { + t.test('#parse()', t => { + t.test('errors', t => { + t.throws( + () => { JSON5.parse('') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 1, + }, + 'throws on empty documents' + ) + + t.throws( + () => { JSON5.parse('//a') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 4, + }, + 'throws on documents with only comments' + ) + + t.throws( + () => { JSON5.parse('/a') }, + { + message: /^JSON5: invalid character 'a'/, + lineNumber: 1, + columnNumber: 2, + }, + 'throws on incomplete single line comments' + ) + + t.throws( + () => { JSON5.parse('/*') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on unterminated multiline comments' + ) + + t.throws( + () => { JSON5.parse('/**') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 4, + }, + 'throws on unterminated multiline comment closings' + ) + + t.throws( + () => { JSON5.parse('a') }, + { + message: /^JSON5: invalid character 'a'/, + lineNumber: 1, + columnNumber: 1, + }, + 'throws on invalid characters in values' + ) + + t.throws( + () => { JSON5.parse('{\\a:1}') }, + { + message: /^JSON5: invalid character 'a'/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on invalid characters in identifier start escapes' + ) + + t.throws( + () => { JSON5.parse('{\\u0021:1}') }, + { + message: /^JSON5: invalid identifier character/, + lineNumber: 1, + columnNumber: 2, + }, + 'throws on invalid identifier start characters' + ) + + t.throws( + () => { JSON5.parse('{a\\a:1}') }, + { + message: /^JSON5: invalid character 'a'/, + lineNumber: 1, + columnNumber: 4, + }, + 'throws on invalid characters in identifier continue escapes' + ) + + t.throws( + () => { JSON5.parse('{a\\u0021:1}') }, + { + message: /^JSON5: invalid identifier character/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on invalid identifier continue characters' + ) + + t.throws( + () => { JSON5.parse('-a') }, + { + message: /^JSON5: invalid character 'a'/, + lineNumber: 1, + columnNumber: 2, + }, + 'throws on invalid characters following a sign' + ) + + t.throws( + () => { JSON5.parse('.a') }, + { + message: /^JSON5: invalid character 'a'/, + lineNumber: 1, + columnNumber: 2, + }, + 'throws on invalid characters following a leading decimal point' + ) + + t.throws( + () => { JSON5.parse('1ea') }, + { + message: /^JSON5: invalid character 'a'/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on invalid characters following an exponent indicator' + ) + + t.throws( + () => { JSON5.parse('1e-a') }, + { + message: /^JSON5: invalid character 'a'/, + lineNumber: 1, + columnNumber: 4, + }, + 'throws on invalid characters following an exponent sign' + ) + + t.throws( + () => { JSON5.parse('0xg') }, + { + message: /^JSON5: invalid character 'g'/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on invalid characters following a hexadecimal indicator' + ) + + t.throws( + () => { JSON5.parse('"\n"') }, + { + message: /^JSON5: invalid character '\\n'/, + lineNumber: 2, + columnNumber: 0, + }, + 'throws on invalid new lines in strings' + ) + + t.throws( + () => { JSON5.parse('"') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 2, + }, + 'throws on unterminated strings' + ) + + t.throws( + () => { JSON5.parse('{!:1}') }, + { + message: /^JSON5: invalid character '!'/, + lineNumber: 1, + columnNumber: 2, + }, + 'throws on invalid identifier start characters in property names' + ) + + t.throws( + () => { JSON5.parse('{a!1}') }, + { + message: /^JSON5: invalid character '!'/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on invalid characters following a property name' + ) + + t.throws( + () => { JSON5.parse('{a:1!}') }, + { + message: /^JSON5: invalid character '!'/, + lineNumber: 1, + columnNumber: 5, + }, + 'throws on invalid characters following a property value' + ) + + t.throws( + () => { JSON5.parse('[1!]') }, + { + message: /^JSON5: invalid character '!'/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on invalid characters following an array value' + ) + + t.throws( + () => { JSON5.parse('tru!') }, + { + message: /^JSON5: invalid character '!'/, + lineNumber: 1, + columnNumber: 4, + }, + 'throws on invalid characters in literals' + ) + + t.throws( + () => { JSON5.parse('"\\') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on unterminated escapes' + ) + + t.throws( + () => { JSON5.parse('"\\xg"') }, + { + message: /^JSON5: invalid character 'g'/, + lineNumber: 1, + columnNumber: 4, + }, + 'throws on invalid first digits in hexadecimal escapes' + ) + + t.throws( + () => { JSON5.parse('"\\x0g"') }, + { + message: /^JSON5: invalid character 'g'/, + lineNumber: 1, + columnNumber: 5, + }, + 'throws on invalid second digits in hexadecimal escapes' + ) + + t.throws( + () => { JSON5.parse('"\\u000g"') }, + { + message: /^JSON5: invalid character 'g'/, + lineNumber: 1, + columnNumber: 7, + }, + 'throws on invalid unicode escapes' + ) + + for (let i = 1; i <= 9; i++) { + t.throws( + () => { JSON5.parse(`'\\${i}'`) }, + { + message: /^JSON5: invalid character '\d'/, + lineNumber: 1, + columnNumber: 3, }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '\d'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - } - }) - - it('throws on octal escapes', () => { - assert.throws(() => { - JSON5.parse("'\\01'") - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '1'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 4 - )) - }) - - it('throws on multiple values', () => { - assert.throws(() => { - JSON5.parse('1 2') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '2'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws with control characters escaped in the message', () => { - assert.throws(() => { - JSON5.parse('\x01') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid character '\\x01'/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 1 - )) - }) - - it('throws on unclosed objects before property names', () => { - assert.throws(() => { - JSON5.parse('{') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 2 - )) - }) - - it('throws on unclosed objects after property names', () => { - assert.throws(() => { - JSON5.parse('{a') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) - - it('throws on unclosed objects before property values', () => { - assert.throws(() => { - JSON5.parse('{a:') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 4 - )) - }) - - it('throws on unclosed objects after property values', () => { - assert.throws(() => { - JSON5.parse('{a:1') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 5 - )) - }) - - it('throws on unclosed arrays before values', () => { - assert.throws(() => { - JSON5.parse('[') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 2 - )) - }) - - it('throws on unclosed arrays after values', () => { - assert.throws(() => { - JSON5.parse('[1') - }, - err => ( - err instanceof SyntaxError && - /^JSON5: invalid end of input/.test(err.message) && - err.lineNumber === 1 && - err.columnNumber === 3 - )) - }) + `throws on escaped digit ${i}` + ) + } + + t.throws( + () => { JSON5.parse("'\\01'") }, + { + message: /^JSON5: invalid character '1'/, + lineNumber: 1, + columnNumber: 4, + }, + 'throws on octal escapes' + ) + + t.throws( + () => { JSON5.parse('1 2') }, + { + message: /^JSON5: invalid character '2'/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on multiple values' + ) + + t.throws( + () => { JSON5.parse('\x01') }, + { + message: /^JSON5: invalid character '\\x01'/, + lineNumber: 1, + columnNumber: 1, + }, + 'throws with control characters escaped in the message' + ) + + t.throws( + () => { JSON5.parse('{') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 2, + }, + 'throws on unclosed objects before property names' + ) + + t.throws( + () => { JSON5.parse('{a') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on unclosed objects after property names' + ) + + t.throws( + () => { JSON5.parse('{a:') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 4, + }, + 'throws on unclosed objects before property values' + ) + + t.throws( + () => { JSON5.parse('{a:1') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 5, + }, + 'throws on unclosed objects after property values' + ) + + t.throws( + () => { JSON5.parse('[') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 2, + }, + 'throws on unclosed arrays before values' + ) + + t.throws( + () => { JSON5.parse('[1') }, + { + message: /^JSON5: invalid end of input/, + lineNumber: 1, + columnNumber: 3, + }, + 'throws on unclosed arrays after values' + ) + + t.end() }) + + t.end() }) + + t.end() }) diff --git a/test/parse.js b/test/parse.js index 59fbdd15..570e72bf 100644 --- a/test/parse.js +++ b/test/parse.js @@ -2,8 +2,6 @@ const assert = require('assert') const sinon = require('sinon') const JSON5 = require('../lib') -require('tap').mochaGlobals() - const t = require('tap') t.test('parse(text)', t => { diff --git a/test/require.js b/test/require.js index b30f74c7..86b9b470 100644 --- a/test/require.js +++ b/test/require.js @@ -1,24 +1,29 @@ const assert = require('assert') const sinon = require('sinon') -require('tap').mochaGlobals() +const t = require('tap') -describe('require(*.json5)', () => { - it('parses a JSON5 document', () => { +t.test('require(*.json5)', t => { + t.test('parses a JSON5 document', t => { require('../lib/register') assert.deepStrictEqual({a: 1, b: 2}, require('./test.json5')) + t.end() }) - it('is backward compatible with v0.5.1, but gives a deprecation warning', () => { + t.test('is backward compatible with v0.5.1, but gives a deprecation warning', t => { const mock = sinon.mock(console) mock.expects('warn').once().withExactArgs("'json5/require' is deprecated. Please use 'json5/register' instead.") require('../lib/require') assert.deepStrictEqual({a: 1, b: 2}, require('./test.json5')) mock.verify() + t.end() }) - it('throws on invalid JSON5', () => { + t.test('throws on invalid JSON5', t => { require('../lib/register') assert.throws(() => { require('./invalid.json5') }, SyntaxError) + t.end() }) + + t.end() }) diff --git a/test/stringify.js b/test/stringify.js index a0c494f0..e256a314 100644 --- a/test/stringify.js +++ b/test/stringify.js @@ -1,340 +1,482 @@ const assert = require('assert') const JSON5 = require('../lib') -require('tap').mochaGlobals() - -describe('JSON5', () => { - describe('#stringify', () => { - describe('objects', () => { - it('stringifies empty objects', () => { - assert.strictEqual(JSON5.stringify({}), '{}') - }) - - it('stringifies unquoted property names', () => { - assert.strictEqual(JSON5.stringify({a: 1}), '{a:1}') - }) - - it('stringifies single quoted string property names', () => { - assert.strictEqual(JSON5.stringify({'a-b': 1}), "{'a-b':1}") - }) - - it('stringifies double quoted string property names', () => { - assert.strictEqual(JSON5.stringify({"a'": 1}), `{"a'":1}`) - }) +const t = require('tap') + +t.test('JSON5', t => { + t.test('#stringify', t => { + t.test('objects', t => { + t.strictSame( + JSON5.stringify({}), + '{}', + 'stringifies empty objects' + ) - it('stringifies empty string property names', () => { - assert.strictEqual(JSON5.stringify({'': 1}), "{'':1}") - }) + t.strictSame( + JSON5.stringify({a: 1}), + '{a:1}', + 'stringifies unquoted property names' + ) - it('stringifies special character property names', () => { - assert.strictEqual(JSON5.stringify({$_: 1, _$: 2, 'a\u200C': 3}), '{$_:1,_$:2,a\u200C:3}') - }) + t.strictSame( + JSON5.stringify({'a-b': 1}), + "{'a-b':1}", + 'stringifies single quoted string property names' + ) - it('stringifies unicode property names', () => { - assert.strictEqual(JSON5.stringify({'ùńîċõďë': 9}), '{ùńîċõďë:9}') - }) + t.strictSame( + JSON5.stringify({"a'": 1}), + `{"a'":1}`, + 'stringifies double quoted string property names' + ) - it('stringifies escaped property names', () => { - assert.strictEqual(JSON5.stringify({'\\\b\f\n\r\t\v\0\x01': 1}), "{'\\\\\\b\\f\\n\\r\\t\\v\\0\\x01':1}") - }) + t.strictSame( + JSON5.stringify({'': 1}), + "{'':1}", + 'stringifies empty string property names' + ) - it('stringifies escaped null character property names', () => { - assert.strictEqual(JSON5.stringify({'\0\x001': 1}), "{'\\0\\x001':1}") - }) + t.strictSame( + JSON5.stringify({$_: 1, _$: 2, 'a\u200C': 3}), + '{$_:1,_$:2,a\u200C:3}', + 'stringifies special character property names' + ) - it('stringifies multiple properties', () => { - assert.strictEqual(JSON5.stringify({abc: 1, def: 2}), '{abc:1,def:2}') - }) + t.strictSame( + JSON5.stringify({'ùńîċõďë': 9}), + '{ùńîċõďë:9}', + 'stringifies unicode property names' + ) - it('stringifies nested objects', () => { - assert.strictEqual(JSON5.stringify({a: {b: 2}}), '{a:{b:2}}') - }) - }) + t.strictSame( + JSON5.stringify({'\\\b\f\n\r\t\v\0\x01': 1}), + "{'\\\\\\b\\f\\n\\r\\t\\v\\0\\x01':1}", + 'stringifies escaped property names' + ) - describe('arrays', () => { - it('stringifies empty arrays', () => { - assert.strictEqual(JSON5.stringify([]), '[]') - }) + t.strictSame( + JSON5.stringify({'\0\x001': 1}), + "{'\\0\\x001':1}", + 'stringifies escaped null character property names' + ) - it('stringifies array values', () => { - assert.strictEqual(JSON5.stringify([1]), '[1]') - }) + t.strictSame( + JSON5.stringify({abc: 1, def: 2}), + '{abc:1,def:2}', + 'stringifies multiple properties' + ) - it('stringifies multiple array values', () => { - assert.strictEqual(JSON5.stringify([1, 2]), '[1,2]') - }) + t.strictSame( + JSON5.stringify({a: {b: 2}}), + '{a:{b:2}}', + 'stringifies nested objects' + ) - it('stringifies nested arrays', () => { - assert.strictEqual(JSON5.stringify([1, [2, 3]]), '[1,[2,3]]') - }) + t.end() }) - it('stringifies nulls', () => { - assert.strictEqual(JSON5.stringify(null), 'null') - }) + t.test('arrays', t => { + t.strictSame( + JSON5.stringify([]), + '[]', + 'stringifies empty arrays' + ) - it('returns undefined for functions', () => { - assert.strictEqual(JSON5.stringify(() => {}), undefined) - }) + t.strictSame( + JSON5.stringify([1]), + '[1]', + 'stringifies array values' + ) - it('ignores function properties', () => { - assert.strictEqual(JSON5.stringify({a () {}}), '{}') - }) + t.strictSame( + JSON5.stringify([1, 2]), + '[1,2]', + 'stringifies multiple array values' + ) - it('returns null for functions in arrays', () => { - assert.strictEqual(JSON5.stringify([() => {}]), '[null]') - }) + t.strictSame( + JSON5.stringify([1, [2, 3]]), + '[1,[2,3]]', + 'stringifies nested arrays' + ) - describe('Booleans', () => { - it('stringifies true', () => { - assert.strictEqual(JSON5.stringify(true), 'true') - }) + t.end() + }) + + t.strictSame( + JSON5.stringify(null), + 'null', + 'stringifies nulls' + ) + + t.strictSame( + JSON5.stringify(() => {}), + undefined, + 'returns undefined for functions' + ) + + t.strictSame( + JSON5.stringify({a () {}}), + '{}', + 'ignores function properties' + ) + + t.strictSame( + JSON5.stringify([() => {}]), + '[null]', + 'returns null for functions in arrays' + ) + + t.test('Booleans', t => { + t.strictSame( + JSON5.stringify(true), + 'true', + 'stringifies true' + ) - it('stringifies false', () => { - assert.strictEqual(JSON5.stringify(false), 'false') - }) + t.strictSame( + JSON5.stringify(false), + 'false', + 'stringifies false' + ) - it('stringifies true Boolean objects', () => { + t.strictSame( // eslint-disable-next-line no-new-wrappers - assert.strictEqual(JSON5.stringify(new Boolean(true)), 'true') - }) + JSON5.stringify(new Boolean(true)), + 'true', + 'stringifies true Boolean objects' + ) - it('stringifies false Boolean objects', () => { + t.strictSame( // eslint-disable-next-line no-new-wrappers - assert.strictEqual(JSON5.stringify(new Boolean(false)), 'false') - }) + JSON5.stringify(new Boolean(false)), + 'false', + 'stringifies false Boolean objects' + ) + + t.end() }) - describe('numbers', () => { - it('stringifies numbers', () => { - assert.strictEqual(JSON5.stringify(-1.2), '-1.2') - }) + t.test('numbers', t => { + t.strictSame( + JSON5.stringify(-1.2), + '-1.2', + 'stringifies numbers' + ) - it('stringifies non-finite numbers', () => { - assert.strictEqual(JSON5.stringify([Infinity, -Infinity, NaN]), '[Infinity,-Infinity,NaN]') - }) + t.strictSame( + JSON5.stringify([Infinity, -Infinity, NaN]), + '[Infinity,-Infinity,NaN]', + 'stringifies non-finite numbers' + ) - it('stringifies Number objects', () => { + t.strictSame( // eslint-disable-next-line no-new-wrappers - assert.strictEqual(JSON5.stringify(new Number(-1.2)), '-1.2') - }) + JSON5.stringify(new Number(-1.2)), + '-1.2', + 'stringifies Number objects' + ) + + t.end() }) - describe('strings', () => { - it('stringifies single quoted strings', () => { - assert.strictEqual(JSON5.stringify('abc'), "'abc'") - }) + t.test('strings', t => { + t.strictSame( + JSON5.stringify('abc'), + "'abc'", + 'stringifies single quoted strings' + ) - it('stringifies double quoted strings', () => { - assert.strictEqual(JSON5.stringify("abc'"), `"abc'"`) - }) + t.strictSame( + JSON5.stringify("abc'"), + `"abc'"`, + 'stringifies double quoted strings' + ) - it('stringifies escaped characters', () => { - assert.strictEqual(JSON5.stringify('\\\b\f\n\r\t\v\0\x0f'), "'\\\\\\b\\f\\n\\r\\t\\v\\0\\x0f'") - }) + t.strictSame( + JSON5.stringify('\\\b\f\n\r\t\v\0\x0f'), + "'\\\\\\b\\f\\n\\r\\t\\v\\0\\x0f'", + 'stringifies escaped characters' + ) - it('stringifies escaped null characters', () => { - assert.strictEqual(JSON5.stringify('\0\x001'), "'\\0\\x001'") - }) + t.strictSame( + JSON5.stringify('\0\x001'), + "'\\0\\x001'", + 'stringifies escaped null characters' + ) - it('stringifies escaped single quotes', () => { - assert.strictEqual(JSON5.stringify(`'"`), `'\\'"'`) - }) + t.strictSame( + JSON5.stringify(`'"`), + `'\\'"'`, + 'stringifies escaped single quotes' + ) - it('stringifies escaped double quotes', () => { - assert.strictEqual(JSON5.stringify(`''"`), `"''\\""`) - }) + t.strictSame( + JSON5.stringify(`''"`), + `"''\\""`, + 'stringifies escaped double quotes' + ) - it('stringifies escaped line and paragraph separators', () => { - assert.strictEqual(JSON5.stringify('\u2028\u2029'), "'\\u2028\\u2029'") - }) + t.strictSame( + JSON5.stringify('\u2028\u2029'), + "'\\u2028\\u2029'", + 'stringifies escaped line and paragraph separators' + ) - it('stringifies String objects', () => { + t.strictSame( // eslint-disable-next-line no-new-wrappers - assert.strictEqual(JSON5.stringify(new String('abc')), "'abc'") - }) - }) + JSON5.stringify(new String('abc')), + "'abc'", + 'stringifies String objects' + ) - it('stringifies using built-in toJSON methods', () => { - assert.strictEqual(JSON5.stringify(new Date('2016-01-01T00:00:00.000Z')), "'2016-01-01T00:00:00.000Z'") + t.end() }) - it('stringifies using user defined toJSON methods', () => { + t.strictSame( + JSON5.stringify(new Date('2016-01-01T00:00:00.000Z')), + "'2016-01-01T00:00:00.000Z'", + 'stringifies using built-in toJSON methods' + ) + + t.test('stringifies using user defined toJSON methods', t => { function C () {} Object.assign(C.prototype, {toJSON () { return {a: 1, b: 2} }}) assert.strictEqual(JSON5.stringify(new C()), '{a:1,b:2}') + t.end() }) - it('stringifies using user defined toJSON(key) methods', () => { + t.test('stringifies using user defined toJSON(key) methods', t => { function C () {} Object.assign(C.prototype, {toJSON (key) { return (key === 'a') ? 1 : 2 }}) assert.strictEqual(JSON5.stringify({a: new C(), b: new C()}), '{a:1,b:2}') + t.end() }) - it('stringifies using toJSON5 methods', () => { + t.test('stringifies using toJSON5 methods', t => { function C () {} Object.assign(C.prototype, {toJSON5 () { return {a: 1, b: 2} }}) assert.strictEqual(JSON5.stringify(new C()), '{a:1,b:2}') + t.end() }) - it('stringifies using toJSON5(key) methods', () => { + t.test('stringifies using toJSON5(key) methods', t => { function C () {} Object.assign(C.prototype, {toJSON5 (key) { return (key === 'a') ? 1 : 2 }}) assert.strictEqual(JSON5.stringify({a: new C(), b: new C()}), '{a:1,b:2}') + t.end() }) - it('calls toJSON5 instead of toJSON if both are defined', () => { + t.test('calls toJSON5 instead of toJSON if both are defined', t => { function C () {} Object.assign(C.prototype, { toJSON () { return {a: 1, b: 2} }, toJSON5 () { return {a: 2, b: 2} }, }) assert.strictEqual(JSON5.stringify(new C()), '{a:2,b:2}') + t.end() }) - it('throws on circular objects', () => { + t.test('throws on circular objects', t => { let a = {} a.a = a assert.throws(() => { JSON5.stringify(a) }, TypeError, 'Converting circular structure to JSON5') + t.end() }) - it('throws on circular arrays', () => { + t.test('throws on circular arrays', t => { let a = [] a[0] = a assert.throws(() => { JSON5.stringify(a) }, TypeError, 'Converting circular structure to JSON5') - }) - }) - - describe('#stringify(value, null, space)', () => { - it('does not indent when no value is provided', () => { - assert.strictEqual(JSON5.stringify([1]), '[1]') - }) - - it('does not indent when 0 is provided', () => { - assert.strictEqual(JSON5.stringify([1], null, 0), '[1]') - }) - - it('does not indent when an empty string is provided', () => { - assert.strictEqual(JSON5.stringify([1], null, ''), '[1]') - }) - - it('indents n spaces when a number is provided', () => { - assert.strictEqual(JSON5.stringify([1], null, 2), '[\n 1,\n]') - }) - - it('does not indent more than 10 spaces when a number is provided', () => { - assert.strictEqual(JSON5.stringify([1], null, 11), '[\n 1,\n]') - }) - - it('indents with the string provided', () => { - assert.strictEqual(JSON5.stringify([1], null, '\t'), '[\n\t1,\n]') - }) - - it('does not indent more than 10 characters of the string provided', () => { - assert.strictEqual(JSON5.stringify([1], null, ' '), '[\n 1,\n]') - }) - - it('indents in arrays', () => { - assert.strictEqual(JSON5.stringify([1], null, 2), '[\n 1,\n]') - }) - - it('indents in nested arrays', () => { - assert.strictEqual(JSON5.stringify([1, [2], 3], null, 2), '[\n 1,\n [\n 2,\n ],\n 3,\n]') + t.end() }) - it('indents in objects', () => { - assert.strictEqual(JSON5.stringify({a: 1}, null, 2), '{\n a: 1,\n}') - }) - - it('indents in nested objects', () => { - assert.strictEqual(JSON5.stringify({a: {b: 2}}, null, 2), '{\n a: {\n b: 2,\n },\n}') - }) + t.end() + }) - it('accepts Number objects', () => { + t.test('#stringify(value, null, space)', t => { + t.strictSame( + JSON5.stringify([1]), + '[1]', + 'does not indent when no value is provided' + ) + + t.strictSame( + JSON5.stringify([1], null, 0), + '[1]', + 'does not indent when 0 is provided' + ) + + t.strictSame( + JSON5.stringify([1], null, ''), + '[1]', + 'does not indent when an empty string is provided' + ) + + t.strictSame( + JSON5.stringify([1], null, 2), + '[\n 1,\n]', + 'indents n spaces when a number is provided' + ) + + t.strictSame( + JSON5.stringify([1], null, 11), + '[\n 1,\n]', + 'does not indent more than 10 spaces when a number is provided' + ) + + t.strictSame( + JSON5.stringify([1], null, '\t'), + '[\n\t1,\n]', + 'indents with the string provided' + ) + + t.strictSame( + JSON5.stringify([1], null, ' '), + '[\n 1,\n]', + 'does not indent more than 10 characters of the string provided' + ) + + t.strictSame( + JSON5.stringify([1], null, 2), + '[\n 1,\n]', + 'indents in arrays' + ) + + t.strictSame( + JSON5.stringify([1, [2], 3], null, 2), + '[\n 1,\n [\n 2,\n ],\n 3,\n]', + 'indents in nested arrays' + ) + + t.strictSame( + JSON5.stringify({a: 1}, null, 2), + '{\n a: 1,\n}', + 'indents in objects' + ) + + t.strictSame( + JSON5.stringify({a: {b: 2}}, null, 2), + '{\n a: {\n b: 2,\n },\n}', + 'indents in nested objects' + ) + + t.strictSame( // eslint-disable-next-line no-new-wrappers - assert.strictEqual(JSON5.stringify([1], null, new Number(2)), '[\n 1,\n]') - }) + JSON5.stringify([1], null, new Number(2)), + '[\n 1,\n]', + 'accepts Number objects' + ) - it('accepts String objects', () => { + t.strictSame( // eslint-disable-next-line no-new-wrappers - assert.strictEqual(JSON5.stringify([1], null, new String('\t')), '[\n\t1,\n]') - }) + JSON5.stringify([1], null, new String('\t')), + '[\n\t1,\n]', + 'accepts String objects' + ) + + t.end() }) - describe('#stringify(value, replacer)', () => { - it('filters keys when an array is provided', () => { - assert.strictEqual(JSON5.stringify({a: 1, b: 2, 3: 3}, ['a', 3]), "{a:1,'3':3}") - }) + t.test('#stringify(value, replacer)', t => { + t.strictSame( + JSON5.stringify({a: 1, b: 2, 3: 3}, ['a', 3]), + "{a:1,'3':3}", + 'filters keys when an array is provided' + ) - it('only filters string and number keys when an array is provided', () => { - assert.strictEqual(JSON5.stringify({a: 1, b: 2, 3: 3, false: 4}, ['a', 3, false]), "{a:1,'3':3}") - }) + t.strictSame( + JSON5.stringify({a: 1, b: 2, 3: 3, false: 4}, ['a', 3, false]), + "{a:1,'3':3}", + 'only filters string and number keys when an array is provided' + ) - it('accepts String and Number objects when an array is provided', () => { + t.strictSame( // eslint-disable-next-line no-new-wrappers - assert.strictEqual(JSON5.stringify({a: 1, b: 2, 3: 3}, [new String('a'), new Number(3)]), "{a:1,'3':3}") - }) - - it('replaces values when a function is provided', () => { - assert.strictEqual( - JSON5.stringify({a: 1, b: 2}, (key, value) => (key === 'a') ? 2 : value), - '{a:2,b:2}' - ) - }) - - it('sets `this` to the parent value', () => { - assert.strictEqual( - JSON5.stringify({a: {b: 1}}, function (k, v) { return (k === 'b' && this.b) ? 2 : v }), - '{a:{b:2}}' - ) - }) - - it('is called after toJSON', () => { + JSON5.stringify({a: 1, b: 2, 3: 3}, [new String('a'), new Number(3)]), + "{a:1,'3':3}", + 'accepts String and Number objects when an array is provided' + ) + + t.strictSame( + JSON5.stringify({a: 1, b: 2}, (key, value) => (key === 'a') ? 2 : value), + '{a:2,b:2}', + 'replaces values when a function is provided' + ) + + t.strictSame( + JSON5.stringify({a: {b: 1}}, function (k, v) { return (k === 'b' && this.b) ? 2 : v }), + '{a:{b:2}}', + 'sets `this` to the parent value' + ) + + t.test('is called after toJSON', t => { function C () {} Object.assign(C.prototype, {toJSON () { return {a: 1, b: 2} }}) assert.strictEqual( JSON5.stringify(new C(), (key, value) => (key === 'a') ? 2 : value), '{a:2,b:2}' ) + t.end() }) - it('is called after toJSON5', () => { + t.test('is called after toJSON5', t => { function C () {} Object.assign(C.prototype, {toJSON5 () { return {a: 1, b: 2} }}) assert.strictEqual( JSON5.stringify(new C(), (key, value) => (key === 'a') ? 2 : value), '{a:2,b:2}' ) + t.end() }) - it('does not affect space when calls are nested', () => { - assert.strictEqual( - JSON5.stringify({a: 1}, (key, value) => { + t.strictSame( + JSON5.stringify( + {a: 1}, + (key, value) => { JSON5.stringify({}, null, 4) return value - }, 2), - '{\n a: 1,\n}' - ) - }) + }, + 2 + ), + '{\n a: 1,\n}', + 'does not affect space when calls are nested' + ) + + t.end() }) - describe('#stringify(value, options)', () => { - it('accepts replacer as an option', () => { - assert.strictEqual(JSON5.stringify({a: 1, b: 2, 3: 3}, {replacer: ['a', 3]}), "{a:1,'3':3}") - }) + t.test('#stringify(value, options)', t => { + t.strictSame( + JSON5.stringify({a: 1, b: 2, 3: 3}, {replacer: ['a', 3]}), + "{a:1,'3':3}", + 'accepts replacer as an option' + ) - it('accepts space as an option', () => { - assert.strictEqual(JSON5.stringify([1], {space: 2}), '[\n 1,\n]') - }) + t.strictSame( + JSON5.stringify([1], {space: 2}), + '[\n 1,\n]', + 'accepts space as an option' + ) + + t.end() }) - describe('#stringify(value, {quote})', () => { - it('uses double quotes if provided', () => { - assert.strictEqual(JSON5.stringify({'a"': '1"'}, {quote: '"'}), '{"a\\"":"1\\""}') - }) + t.test('#stringify(value, {quote})', t => { + t.strictSame( + JSON5.stringify({'a"': '1"'}, {quote: '"'}), + '{"a\\"":"1\\""}', + 'uses double quotes if provided' + ) - it('uses single quotes if provided', () => { - assert.strictEqual(JSON5.stringify({"a'": "1'"}, {quote: "'"}), "{'a\\'':'1\\''}") - }) + t.strictSame( + JSON5.stringify({"a'": "1'"}, {quote: "'"}), + "{'a\\'':'1\\''}", + 'uses single quotes if provided' + ) + + t.end() }) + + t.end() }) From 2aab4dd2a7c212dd4af7b91f29aa315c20251b92 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Fri, 12 Aug 2022 01:42:50 -0500 Subject: [PATCH 28/40] test: require tap as t in cli tests --- test/cli.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/cli.js b/test/cli.js index c52dd926..3d1ca827 100644 --- a/test/cli.js +++ b/test/cli.js @@ -2,12 +2,13 @@ const assert = require('assert') const child = require('child_process') const fs = require('fs') const path = require('path') -const tap = require('tap') const pkg = require('../package.json') const cliPath = path.resolve(__dirname, '../lib/cli.js') -tap.test('CLI', t => { +const t = require('tap') + +t.test('CLI', t => { t.test('converts JSON5 to JSON from stdin to stdout', t => { const proc = child.spawn(process.execPath, [cliPath]) let output = '' From 910ce25914ed366a39a610b17bcd581b5da02d32 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Tue, 6 Sep 2022 11:13:22 -0700 Subject: [PATCH 29/40] docs: fix spelling of Aseem --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fa3edb4..c23663d8 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,7 @@ JSON5, please submit an issue to this repository. MIT. See [LICENSE.md](./LICENSE.md) for details. ## Credits -[Assem Kishore](https://github.com/aseemk) founded this project. +[Aseem Kishore](https://github.com/aseemk) founded this project. [Michael Bolin](http://bolinfest.com/) independently arrived at and published some of these same ideas with awesome explanations and detail. Recommended From d720b4fe4ad800b726da6b0f43c8454c4310fe8d Mon Sep 17 00:00:00 2001 From: Aseem Kishore Date: Sat, 1 Oct 2022 09:43:31 -0700 Subject: [PATCH 30/40] Improve readme (e.g. explain JSON5 better!) (#291) * Explain JSON5 better. Proactively emphasize that this is for config file type use cases, not machine-to-machine communication (the #1 misunderstanding or objection to JSON5). * Market/sell it better. The stats and company/project names are exciting! =) * Link to blog post. This doesn't need to be front-and-center though; just added it to my name in the credits. * Emphasize ES5 compatibility. Just put a stake in the ground here and preempt feature requests we'll never accept. --- README.md | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index c23663d8..ebd0d42f 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,33 @@ Status] [![Coverage Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage Status] -The JSON5 Data Interchange Format (JSON5) is a superset of [JSON] that aims to -alleviate some of the limitations of JSON by expanding its syntax to include -some productions from [ECMAScript 5.1]. - -This JavaScript library is the official reference implementation for JSON5 -parsing and serialization libraries. +JSON5 is an extension to the popular [JSON] file format that aims to be +easier to **write and maintain _by hand_ (e.g. for config files)**. +It is _not intended_ to be used for machine-to-machine communication. +(Keep using JSON or other file formats for that. 🙂) + +JSON5 was started in 2012, and as of 2022, now gets **[>65M downloads/week](https://www.npmjs.com/package/json5)**, +ranks in the **[top 0.1%](https://gist.github.com/anvaka/8e8fa57c7ee1350e3491)** of the most depended-upon packages on npm, +and has been adopted by major projects like +**[Chromium](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5;drc=5de823b36e68fd99009a29281b17bc3a1d6b329c), +[Next.js](https://github.com/vercel/next.js/blob/b88f20c90bf4659b8ad5cb2a27956005eac2c7e8/packages/next/lib/find-config.ts#L43-L46), +[Babel](https://babeljs.io/docs/en/config-files#supported-file-extensions), +[Retool](https://community.retool.com/t/i-am-attempting-to-append-several-text-fields-to-a-google-sheet-but-receiving-a-json5-invalid-character-error/7626), +[WebStorm](https://www.jetbrains.com/help/webstorm/json.html), +and [more](https://github.com/json5/json5/wiki/In-the-Wild)**. +It's also natively supported on **[Apple platforms](https://developer.apple.com/documentation/foundation/jsondecoder/3766916-allowsjson5)** +like **MacOS** and **iOS**. + +Formally, the **[JSON5 Data Interchange Format](https://spec.json5.org/)** is a superset of JSON +(so valid JSON files will always be valid JSON5 files) +that expands its syntax to include some productions from [ECMAScript 5.1] (ES5). +It's also a strict _subset_ of ES5, so valid JSON5 files will always be valid ES5. + +This JavaScript library is a reference implementation for JSON5 parsing and serialization, +and is directly used in many of the popular projects mentioned above +(where e.g. extreme performance isn't necessary for config file use cases), +but others have created [many other libraries](https://github.com/json5/json5/wiki/In-the-Wild) +across many other platforms. [Build Status]: https://app.travis-ci.com/json5/json5 @@ -208,18 +229,23 @@ run lint` before submitting pull requests. Please use an editor that supports [EditorConfig](http://editorconfig.org/). ### Issues -To report bugs or request features regarding the JSON5 data format, please -submit an issue to the [official specification -repository](https://github.com/json5/json5-spec). +To report bugs or request features regarding the JSON5 **data format**, +please submit an issue to the official +**[_specification_ repository](https://github.com/json5/json5-spec)**. + +Note that we will never add any features that make JSON5 incompatible with ES5; +that compatibility is a fundamental premise of JSON5. -To report bugs or request features regarding the JavaScript implementation of -JSON5, please submit an issue to this repository. +To report bugs or request features regarding this **JavaScript implementation** +of JSON5, please submit an issue to **_this_ repository**. ## License MIT. See [LICENSE.md](./LICENSE.md) for details. ## Credits [Aseem Kishore](https://github.com/aseemk) founded this project. +He wrote a [blog post](https://aseemk.substack.com/p/ignore-the-f-ing-haters-json5) +about the journey and lessons learned 10 years in. [Michael Bolin](http://bolinfest.com/) independently arrived at and published some of these same ideas with awesome explanations and detail. Recommended From 97286f8bd542c89dcee096bc05dd28ed2dfc1e16 Mon Sep 17 00:00:00 2001 From: Aseem Kishore Date: Sat, 1 Oct 2022 09:50:35 -0700 Subject: [PATCH 31/40] Improve example in readme Call out that this is intentionally a kitchen-sink example, and link to a nice real-world example too (Chromium/Blink config file). --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ebd0d42f..3bf718c0 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,9 @@ been extended to JSON5. [IEEE 754]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933 -## Short Example +## Example +Kitchen-sink example: + ```js { // comments @@ -89,6 +91,9 @@ No \\n's!", } ``` +A more real-world example is [this config file](https://github.com/chromium/chromium/blob/feb3c9f670515edf9a88f185301cbd7794ee3e52/third_party/blink/renderer/platform/runtime_enabled_features.json5) +from the Chromium/Blink project. + ## Specification For a detailed explanation of the JSON5 format, please read the [official specification](https://json5.github.io/json5-spec/). From edde30abd8b22facf2c06c72586b9f6edf12700d Mon Sep 17 00:00:00 2001 From: Aseem Kishore Date: Sat, 1 Oct 2022 10:04:53 -0700 Subject: [PATCH 32/40] Readme: slight tweak to intro --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bf718c0..d8ed2314 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ It's also a strict _subset_ of ES5, so valid JSON5 files will always be valid ES This JavaScript library is a reference implementation for JSON5 parsing and serialization, and is directly used in many of the popular projects mentioned above -(where e.g. extreme performance isn't necessary for config file use cases), +(where e.g. extreme performance isn't necessary), but others have created [many other libraries](https://github.com/json5/json5/wiki/In-the-Wild) across many other platforms. From 7774c1097993bc3ce9f0ac4b722a32bf7d6871c8 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Thu, 15 Dec 2022 21:16:27 -0600 Subject: [PATCH 33/40] fix: add __proto__ to objects and arrays --- CHANGELOG.md | 4 ++++ lib/parse.js | 41 ++++++++++++++++++++++++++++++++++------- test/parse.js | 7 +++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a20fa52c..7ab8a954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ [c-unreleased]: https://github.com/json5/json5/tree/main [d-unreleased]: https://github.com/json5/json5/compare/v2.2.1...HEAD +- Fix: Properties with the name `__proto__` are added to objects and arrays. + ([#199]) + ### v2.2.1 [[code][c2.2.1], [diff][d2.2.1]] [c2.2.1]: https://github.com/json5/json5/tree/v2.2.1 @@ -360,6 +363,7 @@ parser for the regular JSON format. [#182]: https://github.com/json5/json5/issues/182 [#187]: https://github.com/json5/json5/issues/187 [#196]: https://github.com/json5/json5/issues/196 +[#199]: https://github.com/json5/json5/issues/199 [#208]: https://github.com/json5/json5/issues/208 [#210]: https://github.com/json5/json5/issues/210 [#222]: https://github.com/json5/json5/issues/222 diff --git a/lib/parse.js b/lib/parse.js index c01646fc..da2078a6 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -42,12 +42,34 @@ module.exports = function parse (text, reviver) { function internalize (holder, name, reviver) { const value = holder[name] if (value != null && typeof value === 'object') { - for (const key in value) { - const replacement = internalize(value, key, reviver) - if (replacement === undefined) { - delete value[key] - } else { - value[key] = replacement + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + const key = String(i) + const replacement = internalize(value, key, reviver) + if (replacement === undefined) { + delete value[key] + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + } else { + for (const key in value) { + const replacement = internalize(value, key, reviver) + if (replacement === undefined) { + delete value[key] + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }) + } } } } @@ -973,7 +995,12 @@ function push () { if (Array.isArray(parent)) { parent.push(value) } else { - parent[key] = value + Object.defineProperty(parent, key, { + value, + writable: true, + enumerable: true, + configurable: true, + }) } } diff --git a/test/parse.js b/test/parse.js index 570e72bf..e305767e 100644 --- a/test/parse.js +++ b/test/parse.js @@ -48,6 +48,13 @@ t.test('parse(text)', t => { 'parses escaped property names' ) + t.strictSame( + // eslint-disable-next-line no-proto + JSON5.parse('{"__proto__":1}').__proto__, + 1, + 'preserves __proto__ property names' + ) + t.strictSame( JSON5.parse('{abc:1,def:2}'), {abc: 1, def: 2}, From 10cc7ca9169b59c5e0f5afc03dbd870cd06bcc46 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Fri, 16 Dec 2022 00:35:44 -0600 Subject: [PATCH 34/40] docs: update CHANGELOG for v2.2.2 --- CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab8a954..c4be29a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,16 @@ ### Unreleased [[code][c-unreleased], [diff][d-unreleased]] [c-unreleased]: https://github.com/json5/json5/tree/main -[d-unreleased]: https://github.com/json5/json5/compare/v2.2.1...HEAD +[d-unreleased]: https://github.com/json5/json5/compare/v2.2.2...HEAD + +### v2.2.2 [[code][c2.2.2], [diff][d2.2.2]] + +[c2.2.2]: https://github.com/json5/json5/tree/v2.2.2 +[d2.2.2]: https://github.com/json5/json5/compare/v2.2.1...v2.2.2 - Fix: Properties with the name `__proto__` are added to objects and arrays. - ([#199]) + ([#199]) This also fixes a prototype pollution vulnerability reported by + Jonathan Gregson! ([#295]). ### v2.2.1 [[code][c2.2.1], [diff][d2.2.1]] @@ -372,3 +378,4 @@ parser for the regular JSON format. [#236]: https://github.com/json5/json5/issues/236 [#244]: https://github.com/json5/json5/issues/244 [#266]: https://github.com/json5/json5/issues/266 +[#295]: https://github.com/json5/json5/issues/295 From 14f8cb186e8abdfaccf6527171da7b1224374650 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Fri, 16 Dec 2022 00:37:07 -0600 Subject: [PATCH 35/40] 2.2.2 --- package-lock.json | 2 +- package.json | 2 +- package.json5 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d16fe78..2f4affa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "json5", - "version": "2.2.1", + "version": "2.2.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 70e5f669..38dfe875 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "json5", - "version": "2.2.1", + "version": "2.2.2", "description": "JSON for Humans", "main": "lib/index.js", "module": "dist/index.mjs", diff --git a/package.json5 b/package.json5 index 027a098a..91464ab5 100644 --- a/package.json5 +++ b/package.json5 @@ -1,7 +1,7 @@ // This is a generated file. Do not edit. { name: 'json5', - version: '2.2.1', + version: '2.2.2', description: 'JSON for Humans', main: 'lib/index.js', module: 'dist/index.mjs', From 6a91a05fffeda16ff6b3b5008b6b340d42d31ec0 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sat, 17 Dec 2022 19:23:55 -0600 Subject: [PATCH 36/40] docs(template): bug -> bug report --- .github/issue_template.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/issue_template.md b/.github/issue_template.md index 3fd3598c..6eef661a 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,6 +1,6 @@ -If you are submitting a bug because you are receiving an error or because this -project is incompatible with the [official JSON5 -specification][spec], please continue. +If you are submitting a bug report because you are receiving an error or because +this project is incompatible with the [official JSON5 specification][spec], +please continue. If you are submitting a feature request or code improvement that is compatible with the [official JSON5 specification][spec], please continue. From f0fd9e194dde282caff114a110f4fac635f3a62c Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sat, 17 Dec 2022 19:24:39 -0600 Subject: [PATCH 37/40] docs: publish a security policy --- .github/issue_template.md | 4 ++++ .github/pull_request_template.md | 4 ++++ README.md | 4 ++++ SECURITY.md | 36 ++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 SECURITY.md diff --git a/.github/issue_template.md b/.github/issue_template.md index 6eef661a..de5b728a 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,3 +1,7 @@ +If you are reporting a security vulnerability, please do not submit an issue. +Instead, follow the guidelines described in our +[security policy](../blob/main/SECURITY.md). + If you are submitting a bug report because you are receiving an error or because this project is incompatible with the [official JSON5 specification][spec], please continue. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 647597ea..29da2850 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,3 +1,7 @@ +If you are patching a security vulnerability, please do not submit a pull +request. Instead, follow the guidelines described in our +[security policy](../blob/main/SECURITY.md). + If you are submitting a bug fix for an an error or fixing an incompatibility with the [official JSON5 specification][spec], please continue. diff --git a/README.md b/README.md index d8ed2314..00ee7939 100644 --- a/README.md +++ b/README.md @@ -244,6 +244,10 @@ that compatibility is a fundamental premise of JSON5. To report bugs or request features regarding this **JavaScript implementation** of JSON5, please submit an issue to **_this_ repository**. +### Security Vulnerabilities and Disclosures +To report a security vulnerability, please follow the follow the guidelines +described in our [security policy](./SECURITY.md). + ## License MIT. See [LICENSE.md](./LICENSE.md) for details. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..6ae19cc5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,36 @@ +# JSON5 Security Policy + +We take security seriously. Responsible reporting and disclosure of security +vulnerabilities is important for the protection and privacy of our users. If you +discover any security vulnerabilities, please follow these guidelines. + +To report a vulnerability, we recommend submitting a report to Snyk using their +[vulnerability disclosure form](https://snyk.io/vulnerability-disclosure/). +Snyk's security team will validate the vulnerability and coordinate with you and +us to fix it, release a patch, and responsibly disclose the vulnerability. Read +Snyk's +[Vulnerability Disclosure Policy](https://docs.snyk.io/more-info/disclosing-vulnerabilities/disclose-a-vulnerability-in-an-open-source-package) +for details. + +We also request that you send an email to +[security@json5.org](mailto:security@json5.org) detailing the vulnerability. +This ensures that we can begin work on a fix as soon as possible without waiting +for Snyk to contact us. + +Please do not report undisclosed vulnerabilities on public sites or forums, +including GitHub issues and pull requests. Reporting vulnerabilities to the +public could allow attackers to exploit vulnerable applications before we have +been able to release a patch and before applications have had time to install +the patch. Once we have released a patch and sufficient time has passed for +applications to install the patch, we will disclose the vulnerability to the +public, at which time you will be free to publish details of the vulnerability +on public sites and forums. + +If you have a fix for a security vulnerability, please do not submit a GitHub +pull request. Instead, report the vulnerability as described in this policy and +include a potential fix in the report. Once the vulnerability has been verified +and a disclosure timeline has been decided, we will contact you to see if you +would like to submit a pull request. + +We appreciate your cooperation in helping keep our users safe by following this +policy. From 3b8cebf0c474a8b20c78bd75c89cca0c4dce84ce Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Tue, 20 Dec 2022 11:55:13 -0600 Subject: [PATCH 38/40] docs(security): use GitHub security advisories --- SECURITY.md | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 6ae19cc5..2eaadb65 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,18 +4,19 @@ We take security seriously. Responsible reporting and disclosure of security vulnerabilities is important for the protection and privacy of our users. If you discover any security vulnerabilities, please follow these guidelines. -To report a vulnerability, we recommend submitting a report to Snyk using their -[vulnerability disclosure form](https://snyk.io/vulnerability-disclosure/). -Snyk's security team will validate the vulnerability and coordinate with you and -us to fix it, release a patch, and responsibly disclose the vulnerability. Read -Snyk's -[Vulnerability Disclosure Policy](https://docs.snyk.io/more-info/disclosing-vulnerabilities/disclose-a-vulnerability-in-an-open-source-package) -for details. - -We also request that you send an email to -[security@json5.org](mailto:security@json5.org) detailing the vulnerability. -This ensures that we can begin work on a fix as soon as possible without waiting -for Snyk to contact us. +Published security advisories are available on our [GitHub Security Advisories] +page. + +To report a vulnerability, please draft a [new security advisory on GitHub]. Any +fields that you are unsure of or don't understand can be left at their default +values. The important part is that the vulnerability is reported. Once the +security advisory draft has been created, we will validate the vulnerability and +coordinate with you to fix it, release a patch, and responsibly disclose the +vulnerability to the public. Read GitHub's documentation on [privately reporting +a security vulnerability] for details. + +If you are unable to draft a security advisory, or if you need help or have +security related questions, please send an email to [security@json5.org]. Please do not report undisclosed vulnerabilities on public sites or forums, including GitHub issues and pull requests. Reporting vulnerabilities to the @@ -27,10 +28,18 @@ public, at which time you will be free to publish details of the vulnerability on public sites and forums. If you have a fix for a security vulnerability, please do not submit a GitHub -pull request. Instead, report the vulnerability as described in this policy and -include a potential fix in the report. Once the vulnerability has been verified -and a disclosure timeline has been decided, we will contact you to see if you -would like to submit a pull request. +pull request. Instead, report the vulnerability as described in this policy. +Once we have verified the vulnerability, we can create a [temporary private +fork] to collaborate on a patch. We appreciate your cooperation in helping keep our users safe by following this policy. + +[github security advisories]: https://github.com/json5/json5/security/advisories +[new security advisory on github]: + https://github.com/json5/json5/security/advisories/new +[privately reporting a security vulnerability]: + https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability +[security@json5.org]: mailto:security@json5.org +[temporary private fork]: + https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-repository-security-vulnerability From 94fd06d82eeed225fa172f6fb2ca27375cbd2e39 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sat, 31 Dec 2022 11:06:52 -0600 Subject: [PATCH 39/40] docs: update CHANGELOG for v2.2.3 --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4be29a4..5d04cf06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,15 @@ ### Unreleased [[code][c-unreleased], [diff][d-unreleased]] [c-unreleased]: https://github.com/json5/json5/tree/main -[d-unreleased]: https://github.com/json5/json5/compare/v2.2.2...HEAD +[d-unreleased]: https://github.com/json5/json5/compare/v2.2.3...HEAD + +### v2.2.3 [[code][c2.2.3], [diff][d2.2.3]] + +[c2.2.3]: https://github.com/json5/json5/tree/v2.2.3 +[d2.2.3]: https://github.com/json5/json5/compare/v2.2.2...v2.2.3 + +- Fix: json5@2.2.3 is now the 'latest' release according to npm instead of + v1.0.2. ([#299]) ### v2.2.2 [[code][c2.2.2], [diff][d2.2.2]] @@ -379,3 +387,4 @@ parser for the regular JSON format. [#244]: https://github.com/json5/json5/issues/244 [#266]: https://github.com/json5/json5/issues/266 [#295]: https://github.com/json5/json5/issues/295 +[#299]: https://github.com/json5/json5/issues/299 From c3a75242772a5026a49c4017a16d9b3543b62776 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Sat, 31 Dec 2022 11:09:31 -0600 Subject: [PATCH 40/40] 2.2.3 --- package-lock.json | 2 +- package.json | 2 +- package.json5 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2f4affa9..ac2e4549 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "json5", - "version": "2.2.2", + "version": "2.2.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 38dfe875..60c51d93 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "json5", - "version": "2.2.2", + "version": "2.2.3", "description": "JSON for Humans", "main": "lib/index.js", "module": "dist/index.mjs", diff --git a/package.json5 b/package.json5 index 91464ab5..322bed55 100644 --- a/package.json5 +++ b/package.json5 @@ -1,7 +1,7 @@ // This is a generated file. Do not edit. { name: 'json5', - version: '2.2.2', + version: '2.2.3', description: 'JSON for Humans', main: 'lib/index.js', module: 'dist/index.mjs',