mirror of
https://github.com/antonmedv/fx
synced 2024-11-03 15:40:12 +00:00
Add dot feature
This commit is contained in:
parent
17b30f2622
commit
9bd442da48
15
README.md
15
README.md
@ -40,7 +40,7 @@ $ echo '{"key":"value"}' | fx
|
||||
Use an anonymous function as reducer which gets JSON and processes it:
|
||||
```
|
||||
$ echo '{"foo": [{"bar": "value"}]}' | fx 'x => x.foo[0].bar'
|
||||
"value"
|
||||
value
|
||||
```
|
||||
|
||||
### This Binding
|
||||
@ -49,7 +49,16 @@ If you don't pass anonymous function `param => ...`, code will be automatically
|
||||
And you can get access to JSON by `this` keyword:
|
||||
```
|
||||
$ echo '{"foo": [{"bar": "value"}]}' | fx 'this.foo[0].bar'
|
||||
"value"
|
||||
value
|
||||
```
|
||||
|
||||
### Dot
|
||||
|
||||
It is possible to omit `this` keyword:
|
||||
|
||||
```
|
||||
$ echo '{"foo": [{"bar": "value"}]}' | fx .foo[0].bar
|
||||
value
|
||||
```
|
||||
|
||||
### Chain
|
||||
@ -57,7 +66,7 @@ $ echo '{"foo": [{"bar": "value"}]}' | fx 'this.foo[0].bar'
|
||||
You can pass any number of anonymous functions for reducing JSON:
|
||||
```
|
||||
$ echo '{"foo": [{"bar": "value"}]}' | fx 'x => x.foo' 'this[0]' 'this.bar'
|
||||
"value"
|
||||
value
|
||||
```
|
||||
|
||||
### Generator
|
||||
|
29
index.js
29
index.js
@ -10,16 +10,22 @@ const cli = meow(`
|
||||
|
||||
Examples
|
||||
$ echo '{"key": "value"}' | fx 'x => x.key'
|
||||
"value"
|
||||
value
|
||||
|
||||
$ echo '[1,2,3]' | fx 'this.map(x => x * 2)'
|
||||
[2, 4, 6]
|
||||
|
||||
$ echo '{"items": ["one", "two"]}' | fx 'this.items' 'this[1]'
|
||||
"two"
|
||||
two
|
||||
|
||||
$ echo '{"count": 0}' | fx '{...this, count: 1}'
|
||||
{"count": 1}
|
||||
|
||||
$ echo '{"foo": 1, "bar": 2}' | fx ?
|
||||
["foo", "bar"]
|
||||
|
||||
$ echo '{"key": "value"}' | fx .key
|
||||
value
|
||||
`)
|
||||
|
||||
async function main() {
|
||||
@ -34,6 +40,8 @@ async function main() {
|
||||
|
||||
if (typeof result === 'undefined') {
|
||||
process.stderr.write('undefined\n')
|
||||
} else if (typeof result === 'string') {
|
||||
console.log(result)
|
||||
} else if (process.stdout.isTTY) {
|
||||
console.log(pretty(result))
|
||||
} else {
|
||||
@ -45,7 +53,9 @@ function reduce(json, code) {
|
||||
if (/^\w+\s*=>/.test(code)) {
|
||||
const fx = eval(code)
|
||||
return fx(json)
|
||||
} else if (/yield/.test(code)) {
|
||||
}
|
||||
|
||||
if (/yield/.test(code)) {
|
||||
const fx = eval(`
|
||||
function fn() {
|
||||
const gen = (function*(){
|
||||
@ -55,12 +65,19 @@ function reduce(json, code) {
|
||||
}; fn
|
||||
`)
|
||||
return fx.call(json)
|
||||
} else if (/^\?$/.test(code)) {
|
||||
}
|
||||
|
||||
if (/^\?$/.test(code)) {
|
||||
return Object.keys(json)
|
||||
} else {
|
||||
const fx = eval(`function fn() { return ${code} }; fn`)
|
||||
}
|
||||
|
||||
if (/^\./.test(code)) {
|
||||
const fx = eval(`function fn() { return ${code === '.' ? 'this' : 'this' + code} }; fn`)
|
||||
return fx.call(json)
|
||||
}
|
||||
|
||||
const fx = eval(`function fn() { return ${code} }; fn`)
|
||||
return fx.call(json)
|
||||
}
|
||||
|
||||
main()
|
||||
|
18
test.js
18
test.js
@ -3,26 +3,30 @@ const test = require('ava')
|
||||
const {execSync} = require('child_process')
|
||||
|
||||
function fx(json, code = '') {
|
||||
const output = execSync(`echo '${JSON.stringify(json)}' | node index.js ${code}`).toString('utf8')
|
||||
return JSON.parse(output)
|
||||
return execSync(`echo '${JSON.stringify(json)}' | node index.js ${code}`).toString('utf8')
|
||||
}
|
||||
|
||||
test('pass', t => {
|
||||
t.deepEqual(fx([{"greeting": "hello world"}]), [{"greeting": "hello world"}])
|
||||
const r = fx([{"greeting": "hello world"}])
|
||||
t.deepEqual(JSON.parse(r), [{"greeting": "hello world"}])
|
||||
})
|
||||
|
||||
test('anon func', t => {
|
||||
t.deepEqual(fx({"key": "value"}, "'x => x.key'"), 'value')
|
||||
const r = fx({"key": "value"}, "'x => x.key'")
|
||||
t.deepEqual(r, 'value\n')
|
||||
})
|
||||
|
||||
test('this bind', t => {
|
||||
t.deepEqual(fx([1, 2, 3, 4, 5], "'this.map(x => x * this.length)'"), [5, 10, 15, 20, 25])
|
||||
const r = fx([1, 2, 3, 4, 5], "'this.map(x => x * this.length)'")
|
||||
t.deepEqual(JSON.parse(r), [5, 10, 15, 20, 25])
|
||||
})
|
||||
|
||||
test('generator', t => {
|
||||
t.deepEqual(fx([1, 2, 3, 4, 5], "'for (let i of this) if (i % 2 == 0) yield i'"), [2, 4])
|
||||
const r = fx([1, 2, 3, 4, 5], "'for (let i of this) if (i % 2 == 0) yield i'")
|
||||
t.deepEqual(JSON.parse(r), [2, 4])
|
||||
})
|
||||
|
||||
test('chain', t => {
|
||||
t.deepEqual(fx({"items": ["foo", "bar"]}, "'this.items' 'yield* this' 'x => x[1]'"), 'bar')
|
||||
const r = fx({"items": ["foo", "bar"]}, "'this.items' 'yield* this' 'x => x[1]'")
|
||||
t.deepEqual(r, 'bar\n')
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user