Skip to content

Commit 441c735

Browse files
committed
feat(require): add the --require option, brings access to up to 300K modules!
1 parent a1feeaa commit 441c735

8 files changed

Lines changed: 252 additions & 13 deletions

File tree

BACKERS.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!-- BACKERSFILE/ -->
2+
3+
<h1>Backers</h1>
4+
5+
<h2>Maintainers</h2>
6+
7+
No maintainers yet! Will you be the first?
8+
9+
<h2>Sponsors</h2>
10+
11+
No sponsors yet! Will you be the first?
12+
13+
<span class="badge-patreon"><a href="http://patreon.com/fgribreau" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
14+
<span class="badge-gratipay"><a href="https://www.gratipay.com/fgribreau" title="Donate weekly to this project using Gratipay"><img src="https://img.shields.io/badge/gratipay-donate-yellow.svg" alt="Gratipay donate button" /></a></span>
15+
<span class="badge-flattr"><a href="https://flattr.com/profile/fgribreau" title="Donate to this project using Flattr"><img src="https://img.shields.io/badge/flattr-donate-yellow.svg" alt="Flattr donate button" /></a></span>
16+
<span class="badge-paypal"><a href="https://fgribreau.me/paypal" title="Donate to this project using Paypal"><img src="https://img.shields.io/badge/paypal-donate-yellow.svg" alt="PayPal donate button" /></a></span>
17+
<span class="badge-bitcoin"><a href="https://www.coinbase.com/fgribreau" title="Donate once-off to this project using Bitcoin"><img src="https://img.shields.io/badge/bitcoin-donate-yellow.svg" alt="Bitcoin donate button" /></a></span>
18+
19+
<h2>Contributors</h2>
20+
21+
These amazing people have contributed code to this project:
22+
23+
<ul><li><a href="http://bit.ly/2c7uFJq">Francois-Guillaume Ribreau</a> — <a href="https://github.com/fgribreau/jq.node/commits?author=FGRibreau" title="View the GitHub contributions of Francois-Guillaume Ribreau on repository fgribreau/jq.node">view contributions</a></li>
24+
<li><a href="https://github.com/chocolateboy">chocolateboy</a> — <a href="https://github.com/fgribreau/jq.node/commits?author=chocolateboy" title="View the GitHub contributions of chocolateboy on repository fgribreau/jq.node">view contributions</a></li></ul>
25+
26+
<a href="https://github.com/fgribreau/jq.node/blob/master/CONTRIBUTING.md#files">Discover how you can contribute by heading on over to the <code>CONTRIBUTING.md</code> file.</a>
27+
28+
<!-- /BACKERSFILE -->

CONTRIBUTING.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Before You Post!
2+
3+
## Support
4+
5+
You can either open a Github issues or contact me through [CodeMentor](https://www.codementor.io/francois-guillaume-ribreau) if you need an fast answer.
6+
7+
## Development
8+
9+
### Setup
10+
11+
1. Install [Node.js](https://learn.bevry.me/node/install)
12+
13+
1. Fork the project and clone your fork - [guide](https://help.github.com/articles/fork-a-repo/)
14+
15+
1. Install local dependencies
16+
17+
``` bash
18+
npm install
19+
```
20+
21+
22+
### Developing
23+
24+
1. Compile changes
25+
26+
``` bash
27+
npm run compile
28+
```
29+
30+
1. Run tests
31+
32+
``` bash
33+
npm test
34+
```
35+
36+
37+
### Publishing
38+
39+
Follow these steps in order to implement your changes/improvements into your desired project:
40+
41+
42+
#### Preparation
43+
44+
1. Make sure your changes are on their own branch that is branched off from master.
45+
1. You can do this by: `git checkout master; git checkout -b your-new-branch`
46+
1. And push the changes up by: `git push origin your-new-branch`
47+
48+
1. Ensure all tests pass:
49+
50+
``` bash
51+
npm test
52+
```
53+
54+
> If possible, add tests for your change, if you don't know how, mention this in your pull request
55+
56+
57+
#### Pull Request
58+
59+
To send your changes for the project owner to merge in:
60+
61+
1. Submit your pull request
62+
1. By submitting a pull request you agree for your changes to have the same license as the original plugin

LICENSE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!-- LICENSEFILE/ -->
2+
3+
<h1>License</h1>
4+
5+
Unless stated otherwise all works are:
6+
7+
<ul><li>Copyright &copy; <a href="http://fgribreau.com/">Francois-Guillaume Ribreau</a></li></ul>
8+
9+
and licensed under:
10+
11+
<ul><li><a href="http://spdx.org/licenses/MIT.html">MIT License</a></li></ul>
12+
13+
<h2>MIT License</h2>
14+
15+
<pre>
16+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
17+
18+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
19+
20+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
</pre>
22+
23+
<!-- /LICENSEFILE -->

README.md

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Build Status](https://img.shields.io/circleci/project/FGRibreau/jq.node.svg)](https://circleci.com/gh/FGRibreau/jq.node/) ![deps](https://img.shields.io/david/fgribreau/jq.node.svg?style=flat) ![Version](https://img.shields.io/npm/v/jq.node.svg?style=flat) [![Docker hub](https://img.shields.io/docker/pulls/fgribreau/jq.node.svg)](https://hub.docker.com/r/fgribreau/jq.node/) [![available-for-advisory](https://img.shields.io/badge/available%20for%20consulting%20advisory-yes-ff69b4.svg?)](http://bit.ly/2c7uFJq) ![extra](https://img.shields.io/badge/actively%20maintained-yes-ff69b4.svg) [![Twitter Follow](https://img.shields.io/twitter/follow/fgribreau.svg?style=flat)](https://twitter.com/FGRibreau) [![Get help on Codementor](https://cdn.codementor.io/badges/get_help_github.svg)](https://www.codementor.io/francois-guillaume-ribreau?utm_source=github&utm_medium=button&utm_term=francois-guillaume-ribreau&utm_campaign=github)
44

5-
jq.node is JavaScript and Lodash in your shell. It's a powerful command-line JSON/string processor. It so easy it feels like cheating your inner-bearded-sysadmin.
5+
jq.node is JavaScript and Lodash in your shell (along with the 300K+ npm modules). It's a powerful command-line JSON/string processor. It so easy it feels like cheating your inner-bearded-sysadmin.
66

77
## Rational
88

@@ -14,6 +14,7 @@ I'm a huge fan of [jq](https://github.com/stedolan/jq) **but** it was so many ti
1414
- jq.node does not try to implement its own expression language, it's pure JavaScript
1515
- no need to learn new operators or helpers, if you know [lodash/fp](https://github.com/lodash/lodash/wiki/FP-Guide), you know jq.node helpers
1616
- more powerful than jq **will ever be** `jq 'filter(has("email")) | groupBy(u => u.email.split("@")[1]) | csv'`
17+
- through `--require` command option, jq.node leverages **300K+ npm modules**. Hard to do more powerful than that!
1718

1819
## Why jq? Why not jq.node?
1920

@@ -47,6 +48,23 @@ cat users.json | jq 'filter(has("email")) | groupBy(flow(get("email"), split("@"
4748

4849
Note: the pipe ` | ` **must always** be surrounded by space to be understood by `jq` as a pipe.
4950

51+
## Examples
52+
53+
### Be notified when a JSON value Changelog
54+
55+
```
56+
while true; do curl -s http://10.10.0.5:9000/api/ce/task?id=AVhoYB1sNTnExzIJOq_k | jq 'property("task.status"), thru(a => exit(a === "IN_PROGRESS" ? 0 : 1))' || osascript -e 'display notification "Task done"'; sleep 5; done
57+
```
58+
59+
### Open every links from the clipboard
60+
61+
```
62+
pbpaste | jq -x -r opn 'split("\n") | forEach(opn)'
63+
```
64+
65+
- pbpaste, echoes clipboard content, MacOS only ([use xclip or xsel in Linux](http://superuser.com/a/288333/215986))
66+
- [opn](https://github.com/sindresorhus/opn) is "a better node-open. Opens stuff like websites, files, executables. Cross-platform."
67+
5068

5169
## Options
5270

@@ -66,6 +84,10 @@ Read input as a string.
6684

6785
Colorize JSON (--color=false to disable it)
6886

87+
### -r, --require <npm-module-name>
88+
89+
Require a NPM module `<npm-module-name>`. jq.node will automatically installs in a temporary folder it if its not available. The module will be available in the expression through its name (e.g. `lodash` for the `lodash` module)
90+
6991
### -v, --version
7092

7193
Display the version and exit.
@@ -80,6 +102,7 @@ Display the help message and exit.
80102

81103
- `templateSettings`, `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, `compact`, `concat`, `cond`, `conforms`, `constant`, `countBy`, `create`, `curry`, `curryRight`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, `filter`, `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAllWith`, `pullAt`, `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sortBy`, `sortedUniq`, `sortedUniqBy`, `split`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, `valuesIn`, `without`, `words`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, `zipWith`, `entries`, `entriesIn`, `extend`, `extendWith`, `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, `defaultTo`, `divide`, `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`, `isSet`, `isString`, `isSymbol`, `isTypedArray`, `isUndefined`, `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `stubArray`, `stubFalse`, `stubObject`, `stubString`, `stubTrue`, `multiply`, `nth`, `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`, `random`, `reduce`, `reduceRight`, `repeat`, `replace`, `result`, `round`, `runInContext`, `sample`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedIndexOf`, `sortedLastIndex`, `sortedLastIndexBy`, `sortedLastIndexOf`, `startCase`, `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toFinite`, `toInteger`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`, `each`, `eachRight`, `first` are exposed from [lodash/fp](https://github.com/lodash/lodash/wiki/FP-Guide).
82104
- `csv` is exposed from [json2csv](https://github.com/zemirco/json2csv)
105+
- any of 300 000+ [npm modules](https://www.npmjs.com/) through the `--require` option!
83106

84107

85108
## Performance
@@ -95,5 +118,49 @@ Display the help message and exit.
95118

96119
I accept pull-requests!
97120

98-
99121
## [Changelog](/CHANGELOG.md)
122+
123+
124+
<!-- BACKERS/ -->
125+
126+
<h2>Backers</h2>
127+
128+
<h3>Maintainers</h3>
129+
130+
No maintainers yet! Will you be the first?
131+
132+
<h3>Sponsors</h3>
133+
134+
No sponsors yet! Will you be the first?
135+
136+
<span class="badge-patreon"><a href="http://patreon.com/fgribreau" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
137+
<span class="badge-gratipay"><a href="https://www.gratipay.com/fgribreau" title="Donate weekly to this project using Gratipay"><img src="https://img.shields.io/badge/gratipay-donate-yellow.svg" alt="Gratipay donate button" /></a></span>
138+
<span class="badge-flattr"><a href="https://flattr.com/profile/fgribreau" title="Donate to this project using Flattr"><img src="https://img.shields.io/badge/flattr-donate-yellow.svg" alt="Flattr donate button" /></a></span>
139+
<span class="badge-paypal"><a href="https://fgribreau.me/paypal" title="Donate to this project using Paypal"><img src="https://img.shields.io/badge/paypal-donate-yellow.svg" alt="PayPal donate button" /></a></span>
140+
<span class="badge-bitcoin"><a href="https://www.coinbase.com/fgribreau" title="Donate once-off to this project using Bitcoin"><img src="https://img.shields.io/badge/bitcoin-donate-yellow.svg" alt="Bitcoin donate button" /></a></span>
141+
142+
<h3>Contributors</h3>
143+
144+
These amazing people have contributed code to this project:
145+
146+
<ul><li><a href="http://bit.ly/2c7uFJq">Francois-Guillaume Ribreau</a> — <a href="https://github.com/fgribreau/jq.node/commits?author=FGRibreau" title="View the GitHub contributions of Francois-Guillaume Ribreau on repository fgribreau/jq.node">view contributions</a></li>
147+
<li><a href="https://github.com/chocolateboy">chocolateboy</a> — <a href="https://github.com/fgribreau/jq.node/commits?author=chocolateboy" title="View the GitHub contributions of chocolateboy on repository fgribreau/jq.node">view contributions</a></li></ul>
148+
149+
<a href="https://github.com/fgribreau/jq.node/blob/master/CONTRIBUTING.md#files">Discover how you can contribute by heading on over to the <code>CONTRIBUTING.md</code> file.</a>
150+
151+
<!-- /BACKERS -->
152+
153+
154+
<!-- LICENSE/ -->
155+
156+
<h2>License</h2>
157+
158+
Unless stated otherwise all works are:
159+
160+
<ul><li>Copyright &copy; <a href="http://fgribreau.com/">Francois-Guillaume Ribreau</a></li></ul>
161+
162+
and licensed under:
163+
164+
<ul><li><a href="http://spdx.org/licenses/MIT.html">MIT License</a></li></ul>
165+
166+
<!-- /LICENSE -->

args.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ const argv = require('yargs')
1717
.boolean('color')
1818
.alias('C', 'color')
1919
.describe('color', 'Colorize JSON (--color=false to disable it)')
20-
.default('color', true);
20+
.default('color', true)
21+
22+
.describe('require', 'require the given module')
23+
.alias('r', 'require');
2124

2225
module.exports = {
2326
args: argv.argv,

jq.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,30 @@ if (process.stdin.isTTY) {
1515
process.exit(0);
1616
}
1717

18+
const deps = {};
19+
20+
if (args.require) {
21+
const lazyRequire = require('lazy-require');
22+
const TMP = require('os').tmpdir();
23+
(_.isArray(args.require)
24+
? args.require
25+
: [args.require]).reduce((deps, dep) => {
26+
deps[dep] = lazyRequire(dep, {
27+
cwd: TMP,
28+
save: false
29+
})
30+
return deps;
31+
}, deps);
32+
33+
}
1834
process.stdin.resume().on('data', function(buf) {
1935
content += buf.toString();
2036
}).on('end', function() {
21-
const sandbox = _;
22-
_.console = console;
23-
_.$$input$$ = args.rawInput
24-
? stripAnsi(content)
25-
: JSON.parse(stripAnsi(content));
37+
const sandbox = Object.assign({}, _, {
38+
console: console,
39+
exit: process.exit.bind(process),
40+
$$input$$: args.rawInput ? stripAnsi(content) : JSON.parse(stripAnsi(content))
41+
}, deps);
2642
const scriptStrWithPipes = args._[0];
2743
const scriptStr = (!scriptStrWithPipes || scriptStrWithPipes === '.'
2844
? 'identity'

jq.test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,14 @@ describe('jq', () => {
2424
t.strictEqual(run(`echo '{}' | ./jq 'console.log'`), "{}\n\n");
2525
});
2626
});
27+
28+
describe('require', () => {
29+
it('should handle not found npm modules', () => {
30+
t.strictEqual(run(`echo '{}' | ./jq --color=false -r will-never-exist-${+new Date()} ''`), '{}\n');
31+
});
32+
33+
it('should expose a valid npm module inside the expression', () => {
34+
t.strictEqual(run(`echo '20111031' | ./jq -x -r moment --color=false 'thru(a => moment(a, "YYYYMMDD"))'`), '"2011-10-30T23:00:00.000Z"\n');
35+
});
36+
});
2737
});

package.json

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "0.2.0",
44
"author": "Francois-Guillaume Ribreau <npm@fgribreau.com> (http://fgribreau.com/)",
55
"engines": {
6-
"node": "6"
6+
"node": ">=6"
77
},
88
"nyc": {
99
"exclude": [
@@ -24,6 +24,8 @@
2424
"test-coverage": "nyc --all --statements=100 --lines=100 --functions=90 --branches=70 --check-coverage --reporter=lcov --reporter=cobertura --report-dir=coverage -- mocha -R spec -t 100000 $(find src -name '*.test.js')",
2525
"send-coverage": "cat ./coverage/lcov.info | coveralls",
2626
"update": "updtr",
27+
"compile": "projectz compile",
28+
"posttest": "npm run compile",
2729
"changelog": "conventional-changelog -i CHANGELOG.md -s -r 0",
2830
"changelog-git": "npm run changelog && git add CHANGELOG.md && git commit -m 'docs(changelog): updated' && git push origin master"
2931
},
@@ -41,25 +43,53 @@
4143
"json",
4244
"cli"
4345
],
44-
"engines":{
45-
"node": ">=6"
46-
},
46+
"browsers": false,
47+
"maintainers": [],
48+
"sponsors": [],
49+
"contributors": [
50+
"Francois-Guillaume Ribreau <github@fgribreau.com> (http://bit.ly/2c7uFJq)",
51+
"chocolateboy <chocolate@cpan.org> (https://github.com/chocolateboy)"
52+
],
4753
"devDependencies": {
4854
"chai": "^3.5.0",
4955
"conventional-changelog": "^1.1.0",
5056
"conventional-changelog-cli": "^1.2.0",
5157
"coveralls": "^2.11.12",
5258
"mocha": "^3.0.1",
53-
"sinon": "^1.17.5",
5459
"nyc": "^8.1.0",
60+
"projectz": "^1.3.2",
61+
"sinon": "^1.17.5",
5562
"updtr": "^0.2.1"
5663
},
5764
"dependencies": {
5865
"cardinal": "^1.0.0",
5966
"json2csv": "^3.7.1",
67+
"lazy-require": "^2.2.0",
6068
"lodash": "^4.16.4",
6169
"strip-ansi": "^3.0.1",
6270
"yargs": "^6.3.0"
6371
},
72+
"badges": {
73+
"list": [
74+
"travisci",
75+
"npmversion",
76+
"npmdownloads",
77+
"daviddm",
78+
"daviddmdev",
79+
"---",
80+
"patreon",
81+
"gratipay",
82+
"flattr",
83+
"paypal",
84+
"bitcoin"
85+
],
86+
"config": {
87+
"patreonUsername": "fgribreau",
88+
"gratipayUsername": "fgribreau",
89+
"flattrUsername": "fgribreau",
90+
"paypalURL": "https://fgribreau.me/paypal",
91+
"bitcoinURL": "https://www.coinbase.com/fgribreau"
92+
}
93+
},
6494
"license": "MIT"
6595
}

0 commit comments

Comments
 (0)