Comparing version 8.0.0 to 9.0.0
# json Changelog | ||
## json 9.0.0 | ||
- [issue #52] Fix termination on EPIPE in some cases. | ||
- Add `-0`, `-2`, `-4` options to more conveniently set the JSON indentation | ||
without changing the mode. | ||
- [pull #64] Add `-M, --items` option for "itemizing" key/value pairs in an | ||
object for easy iteration. For example: | ||
$ echo '{"trent":{"age":38}, | ||
"ewan": {"age":4}}' | json -M | ||
[ | ||
{ | ||
"key": "trent", | ||
"value": { | ||
"age": 38 | ||
} | ||
}, | ||
{ | ||
"key": "ewan", | ||
"value": { | ||
"age": 4 | ||
} | ||
} | ||
] | ||
$ echo '{"trent":{"age":38}, | ||
"ewan": {"age":4}}' | json -Ma key value.age | ||
trent 38 | ||
ewan 4 | ||
# List people that can vote. | ||
$ echo '{"trent":{"age":38}, | ||
"ewan": {"age":4}}' | json -M -c 'this.value.age > 18' -a key | ||
trent | ||
Thanks to [AndrewO](https://github.com/AndrewO) for providing this! | ||
- **Backward incompatible change to `-c CODE` and `-e CODE`** changing their | ||
implementation to use a JS function for processing rather than | ||
`vm.runInNewContext`. This is the technique for which the `-C CODE` and `-E | ||
CODE` options were added in version 7.0.0. Basically: This technique is | ||
obviously better because it is 10x faster, so it is being made the only | ||
supported way. `-C` and `-E`, then, become synonyms and may be removed | ||
in a later release. | ||
Unfortunately this does mean a few semantic differences in the `CODE`, the | ||
most noticeable of which is that **`this` is required to access the object | ||
fields:** | ||
# Bad. Works with json < v9... | ||
$ echo '{"green": "eggs"}' | json-v8 -e 'green="ham"' | ||
{ | ||
"green": "ham" | ||
} | ||
# ... does *not* work with json v9. | ||
$ echo '{"green": "eggs"}' | json -e 'green="ham"' | ||
{ | ||
"green": "eggs" | ||
} | ||
# Good. Works with all versions of json. | ||
$ echo '{"green": "eggs"}' | json -e 'this.green="ham"' | ||
{ | ||
"green": "ham" | ||
} | ||
The old behaviour of `-c` and `-e` can be restored with the `JSON_EXEC=vm` | ||
environment variable: | ||
$ echo '{"green": "eggs"}' | JSON_EXEC=vm json -e 'green="ham"' | ||
{ | ||
"green": "ham" | ||
} | ||
See the notes on [json 7.0.0](#json-700) below for full details on the | ||
performance improvements and semantic changes. | ||
## json 8.0.0 | ||
@@ -55,4 +135,3 @@ | ||
`vm.runInNewContext`. This change means some semantic changes to the given | ||
`CODE` so *new* options were required. The old `-c/-e` remain for backward | ||
compatibility. Some examples to show the semantic differences: | ||
`CODE`. Some examples to show the semantic differences: | ||
@@ -198,3 +277,3 @@ 1. `this` is required to access the object fields: | ||
$ jsondev -nf foo.json | ||
$ json -nf foo.json | ||
json: error: "foo.json" is not JSON: Expected ',' instead of '"' at line 3, column 5: | ||
@@ -201,0 +280,0 @@ "baz": "car" |
134
lib/json.js
@@ -11,3 +11,3 @@ #!/usr/bin/env node | ||
var VERSION = '8.0.0'; | ||
var VERSION = '9.0.0'; | ||
@@ -159,4 +159,4 @@ var p = console.warn; | ||
w('Execution:'); | ||
w(' Use the "-E CODE" option to execute JavaScript code on the input JSON.'); | ||
w(' $ echo \'{"name":"trent","age":38}\' | json -E \'this.age++\''); | ||
w(' Use the "-e CODE" option to execute JavaScript code on the input JSON.'); | ||
w(' $ echo \'{"name":"trent","age":38}\' | json -e \'this.age++\''); | ||
w(' {'); | ||
@@ -170,4 +170,4 @@ w(' "name": "trent",'); | ||
w('Conditional filtering:'); | ||
w(' Use the "-C CODE" option to filter the input JSON.'); | ||
w(' $ echo \'[{"age":38},{"age":4}]\' | json -C \'this.age>21\''); | ||
w(' Use the "-c CODE" option to filter the input JSON.'); | ||
w(' $ echo \'[{"age":38},{"age":4}]\' | json -c \'this.age>21\''); | ||
w(' [{\'age\':38}]'); | ||
@@ -235,15 +235,15 @@ w(' If input is an array, this will automatically process each'); | ||
w(' -D DELIM Delimiter char between lookups (default is "."). E.g.:'); | ||
w(' $ echo \'{"a.b": {"b": 1}}\' | json -D / a.b/b'); | ||
w(' $ echo \'{"a.b": {"b": 1}}\' | json -D / a.b/b'); | ||
w(''); | ||
w(' -E CODE Execute the given JavaScript code on the input. If input'); | ||
w(' -M, --items Itemize an object into an array of '); | ||
w(' {"key": <key>, "value": <value>}'); | ||
w(' objects for easier processing.'); | ||
w(''); | ||
w(' -e CODE Execute the given JavaScript code on the input. If input'); | ||
w(' is an array, then each item of the array is processed'); | ||
w(' separately (use "-A" to override).'); | ||
w(' -C CODE Filter the input with JavaScript `CODE`. If `CODE`'); | ||
w(' -c CODE Filter the input with JavaScript `CODE`. If `CODE`'); | ||
w(' returns false-y, then the item is filtered out. If'); | ||
w(' input is an array, then each item of the array is '); | ||
w(' processed separately (use "-A" to override).'); | ||
w(' -e CODE, -c CODE'); | ||
w(' Similar to "-E CODE" and "-C CODE", respectively,'); | ||
w(' but potentially much slower. Deprecated. Remains '); | ||
w(' for backward compat. See the full docs for details.'); | ||
w(''); | ||
@@ -254,9 +254,14 @@ w(' -k, --keys Output the input object\'s keys.'); | ||
w(''); | ||
w(' -o, --output MODE Specify an output mode. One of'); | ||
w(' jsony (default): JSON with string quotes elided'); | ||
w(' json: JSON output, 2-space indent'); | ||
w(' json-N: JSON output, N-space indent, e.g. "json-4"'); | ||
w(' inspect: node.js `util.inspect` output'); | ||
w(' -i shortcut for `-o inspect`'); | ||
w(' -j shortcut for `-o json`'); | ||
w(' -o, --output MODE'); | ||
w(' Specify an output mode. One of:'); | ||
w(' jsony (default): JSON with string quotes elided'); | ||
w(' json: JSON output, 2-space indent'); | ||
w(' json-N: JSON output, N-space indent, e.g. "json-4"'); | ||
w(' inspect: node.js `util.inspect` output'); | ||
w(' -i Shortcut for `-o inspect`'); | ||
w(' -j Shortcut for `-o json`'); | ||
w(' -0, -2, -4 Set indentation to the given value w/o setting MODE.'); | ||
w(' -0 => -o jsony-0'); | ||
w(' -4 => -o jsony-4'); | ||
w(' -j0 => -o json-0'); | ||
w(''); | ||
@@ -288,5 +293,3 @@ w('See <http://trentm.com/json> for more docs and '); | ||
exeSnippets: [], | ||
vmExeSnippets: [], | ||
condSnippets: [], | ||
vmCondSnippets: [], | ||
outputMode: OM_JSONY, | ||
@@ -297,2 +300,3 @@ jsonIndent: 2, | ||
lookupDelim: '.', | ||
items: false, | ||
outputKeys: false, | ||
@@ -342,2 +346,6 @@ group: false, | ||
var arg = args.shift(); | ||
if (endOfOptions) { | ||
parsed.args.push(arg); | ||
break; | ||
} | ||
switch (arg) { | ||
@@ -380,2 +388,11 @@ case '--': | ||
break; | ||
case '-0': | ||
parsed.jsonIndent = 0; | ||
break; | ||
case '-2': | ||
parsed.jsonIndent = 2; | ||
break; | ||
case '-4': | ||
parsed.jsonIndent = 4; | ||
break; | ||
case '-I': | ||
@@ -410,13 +427,13 @@ case '--in-place': | ||
case '-e': | ||
parsed.vmExeSnippets.push(args.shift()); | ||
break; | ||
case '-E': | ||
case '-E': // DEPRECATED in v9 | ||
parsed.exeSnippets.push(args.shift()); | ||
break; | ||
case '-c': | ||
parsed.vmCondSnippets.push(args.shift()); | ||
break; | ||
case '-C': | ||
case '-C': // DEPRECATED in v9 | ||
parsed.condSnippets.push(args.shift()); | ||
break; | ||
case '-M': | ||
case '--items': | ||
parsed.items = true; | ||
break; | ||
case '-k': | ||
@@ -1149,2 +1166,5 @@ case '--keys': | ||
// mainline and be sure to only catch this particular error. | ||
if (drainingStdout) { | ||
return; | ||
} | ||
try { | ||
@@ -1178,6 +1198,14 @@ stdoutFlushed = process.stdout.write(s); | ||
*/ | ||
var drainingStdout = false; | ||
function drainStdoutAndExit(code) { | ||
if (drainingStdout) { | ||
return; | ||
} | ||
drainingStdout = true; | ||
process.stdout.on('drain', function () { | ||
process.exit(code); | ||
}); | ||
process.stdout.on('close', function () { | ||
process.exit(code); | ||
}); | ||
if (stdoutFlushed) { | ||
@@ -1194,5 +1222,6 @@ process.exit(code); | ||
* statement and wrap in 'return (...)'. This is for convenience for short | ||
* '-C ...' snippets. | ||
* '-c ...' snippets. | ||
*/ | ||
function funcWithReturnFromSnippet(js) { | ||
// auto-"return" | ||
if (js.indexOf('return') === -1) { | ||
@@ -1241,20 +1270,30 @@ if (js.substring(js.length - 1) === ';') { | ||
// Prepare condition and execution funcs (and vm scripts) for -C/-E (-c/-e). | ||
// Prepare condition and execution funcs (and vm scripts) for -c/-e. | ||
var execVm = Boolean(process.env.JSON_EXEC && | ||
process.env.JSON_EXEC === 'vm'); | ||
var i; | ||
var condFuncs = []; | ||
for (i = 0; i < opts.condSnippets.length; i++) { | ||
condFuncs[i] = funcWithReturnFromSnippet(opts.condSnippets[i]); | ||
if (!execVm) { | ||
for (i = 0; i < opts.condSnippets.length; i++) { | ||
condFuncs[i] = funcWithReturnFromSnippet(opts.condSnippets[i]); | ||
} | ||
} | ||
var condScripts = []; | ||
for (i = 0; i < opts.vmCondSnippets.length; i++) { | ||
condScripts[i] = vm.createScript(opts.vmCondSnippets[i]); | ||
if (execVm) { | ||
for (i = 0; i < opts.condSnippets.length; i++) { | ||
condScripts[i] = vm.createScript(opts.condSnippets[i]); | ||
} | ||
} | ||
var cond = Boolean(condFuncs.length + condScripts.length); | ||
var exeFuncs = []; | ||
for (i = 0; i < opts.exeSnippets.length; i++) { | ||
exeFuncs[i] = new Function(opts.exeSnippets[i]); | ||
if (!execVm) { | ||
for (i = 0; i < opts.exeSnippets.length; i++) { | ||
exeFuncs[i] = new Function(opts.exeSnippets[i]); | ||
} | ||
} | ||
var exeScripts = []; | ||
for (i = 0; i < opts.vmExeSnippets.length; i++) { | ||
exeScripts[i] = vm.createScript(opts.vmExeSnippets[i]); | ||
if (execVm) { | ||
for (i = 0; i < opts.exeSnippets.length; i++) { | ||
exeScripts[i] = vm.createScript(opts.exeSnippets[i]); | ||
} | ||
} | ||
@@ -1410,3 +1449,20 @@ var exe = Boolean(exeFuncs.length + exeScripts.length); | ||
// Process: executions (-E/-e) | ||
// Process: items (-M, --items) | ||
if (opts.items) { | ||
if (!Array.isArray(data)) { | ||
var key; | ||
var array = []; | ||
for (key in data) { | ||
if (data.hasOwnProperty(key)) { | ||
array.push({ | ||
key: key, | ||
value: data[key] | ||
}); | ||
} | ||
} | ||
data = array; | ||
} | ||
} | ||
// Process: executions (-e, -E) | ||
var i, j; | ||
@@ -1442,3 +1498,3 @@ if (!exe) { | ||
// Process: conditionals (-C/-c) | ||
// Process: conditionals (-c) | ||
if (!cond) { | ||
@@ -1445,0 +1501,0 @@ /* pass */ |
{ | ||
"name": "json", | ||
"description": "a 'json' command for massaging and processing JSON on the command line", | ||
"version": "8.0.0", | ||
"version": "9.0.0", | ||
"repository": { | ||
@@ -18,3 +18,3 @@ "type": "git", | ||
}, | ||
"engines": ["node >=0.4.0"], | ||
"engines": ["node >=0.6.0"], | ||
"keywords": ["json", "jsontool", "filter", "command", "shell"], | ||
@@ -21,0 +21,0 @@ "devDependencies": { |
@@ -61,3 +61,3 @@ `json` is a fast CLI tool for working with JSON. It is a single-file node.js | ||
$ json --version | ||
json 7.0.0 | ||
json 9.0.0 | ||
@@ -64,0 +64,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
229662
155
2419
4
8