You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fx/DOCS.md

262 lines
6.4 KiB
Markdown

6 years ago
# Documentation
6 years ago
* [Getting started](#getting-started)
6 years ago
* [Usage](#usage)
+ [Anonymous function](#anonymous-function)
+ [Binding](#binding)
+ [Dot](#dot)
+ [Chaining](#chaining)
+ [Generator](#generator)
+ [Updating](#updating)
+ [Using packages](#using-packages)
6 years ago
* [Using .fxrc](#using-fxrc)
6 years ago
+ [Edit in place](#edit-in-place)
6 years ago
* [Formatting](#formatting)
* [Other examples](#other-examples)
* [Streaming mode](#streaming-mode)
* [Interactive mode](#interactive-mode)
6 years ago
+ [Searching](#searching)
6 years ago
+ [Selecting text](#selecting-text)
## Getting started
6 years ago
`fx` can work in two modes: cli and interactive. To start interactive mode pipe into `fx` any JSON:
6 years ago
```bash
6 years ago
$ curl ... | fx
```
Or you can pass file argument as first parameter:
6 years ago
```bash
6 years ago
$ fx my.json
```
If any argument was passed, `fx` will apply it and prints to stdout.
6 years ago
## Usage
### Anonymous function
6 years ago
Use an anonymous function as reducer which gets JSON and processes it:
6 years ago
```bash
6 years ago
$ echo '{"foo": [{"bar": "value"}]}' | fx 'x => x.foo[0].bar'
value
```
6 years ago
### Binding
6 years ago
If you don't pass anonymous function `param => ...`, code will be automatically transformed into anonymous function.
And you can get access to JSON by `this` keyword:
6 years ago
```bash
6 years ago
$ echo '{"foo": [{"bar": "value"}]}' | fx 'this.foo[0].bar'
value
```
6 years ago
### Dot
6 years ago
It is possible to omit `this` keyword:
6 years ago
```bash
6 years ago
$ echo '{"foo": [{"bar": "value"}]}' | fx .foo[0].bar
value
```
If single dot is passed, JSON will be processed without modification:
6 years ago
```bash
6 years ago
$ echo '{"foo": "bar"}' | fx .
{
"foo": "bar"
}
```
6 years ago
### Chaining
6 years ago
You can pass any number of anonymous functions for reducing JSON:
6 years ago
```bash
6 years ago
$ echo '{"foo": [{"bar": "value"}]}' | fx 'x => x.foo' 'this[0]' 'this.bar'
value
```
6 years ago
### Generator
6 years ago
If passed code contains `yield` keyword, [generator expression](https://github.com/sebmarkbage/ecmascript-generator-expression)
will be used:
6 years ago
```bash
6 years ago
$ curl ... | fx 'for (let user of this) if (user.login.startsWith("a")) yield user'
```
Access to JSON through `this` keyword:
6 years ago
```bash
6 years ago
$ echo '["a", "b"]' | fx 'yield* this'
[
"a",
"b"
]
```
6 years ago
```bash
6 years ago
$ echo '["a", "b"]' | fx 'yield* this; yield "c";'
[
"a",
"b",
"c"
]
```
6 years ago
### Updating
6 years ago
You can update existing JSON using spread operator:
6 years ago
```bash
6 years ago
$ echo '{"count": 0}' | fx '{...this, count: 1}'
{
"count": 1
}
```
6 years ago
### Using packages
6 years ago
Use any npm package by installing it globally:
6 years ago
```bash
6 years ago
$ npm install -g lodash
$ cat package.json | fx 'require("lodash").keys(this.dependencies)'
```
## Using .fxrc
Create _.fxrc_ file in `$HOME` directory, and require any packages or define global functions.
For example, access all lodash methods without `_` prefix. Put in your `.fxrc` file:
```js
6 years ago
Object.assign(global, require('lodash/fp'))
6 years ago
```
And now you will be able to call all lodash methods. For example, see who's been committing to react recently:
6 years ago
```bash
6 years ago
curl 'https://api.github.com/repos/facebook/react/commits?per_page=100' \
6 years ago
| fx 'groupBy("commit.author.name")' 'mapValues(size)' toPairs 'sortBy(1)' reverse 'take(10)' fromPairs
6 years ago
```
> To be able require global modules make sure you have correct `NODE_PATH` env variable.
> ```bash
> export NODE_PATH=`npm root -g`
6 years ago
> ```
6 years ago
### Edit in place
6 years ago
Add next code to your _.fxrc_ file:
```js
6 years ago
const fs = require('fs')
6 years ago
global.save = json => {
fs.writeFileSync(process.argv[2], JSON.stringify(json, null, 2))
return json
}
```
Usage:
```bash
fx data.json '{...this, count: this.count+1}' save .count
```
6 years ago
## Formatting
If you need something different then JSON (for example arguments for xargs) do not return anything from reducer.
`undefined` value is printed into stderr by default.
6 years ago
```bash
6 years ago
echo '[]' | fx 'void 0'
undefined
```
6 years ago
```bash
6 years ago
echo '[1,2,3]' | fx 'this.forEach(x => console.log(x))' 2>/dev/null | xargs echo
1 2 3
```
## Other examples
Convert object to array:
6 years ago
```bash
6 years ago
$ cat package.json | fx 'Object.keys(this.dependencies)'
```
6 years ago
Or by two functions:
```bash
$ cat package.json | fx .dependencies Object.keys
```
By the way, fx has shortcut for `Object.keys`. Previous example can be rewritten as:
6 years ago
6 years ago
```bash
6 years ago
$ cat package.json | fx .dependencies ?
6 years ago
```
6 years ago
## Streaming mode
`fx` supports line-delimited JSON and concatenated JSON streaming.
```bash
$ kubectl logs ... | fx .message
```
Sometimes it is necessary to omit some messages in JSON stream, or select only specified log messages.
For this purpose, `fx` has special helper `select`, pass function into it to select only some JSON messages.
```bash
$ kubectl logs ... | fx 'select(x => x.message.length > 40)' .message
```
6 years ago
## Interactive mode
Click on fields to expand or collapse JSON tree, use mouse wheel to scroll view.
Next commands available in interactive mode:
| Key | Command |
|-------------------------------|-------------------------|
| `q` or `Esc` or `Ctrl`+`c` | Exit |
| `e`/`E` | Expand/Collapse all |
| `g`/`G` | Goto top/bottom |
| `up`/`down` or `k/j` | Move cursor up/down |
| `left`/`right` or `h/l` | Expand/Collapse |
6 years ago
| `.` | Edit filter |
6 years ago
| `/` | Search |
| `n` | Goto next found pattern |
6 years ago
These commands are available when editing the filter:
| Key | Command |
|-------------------------------|-------------------------|
| `Enter` | Apply filter |
| `Ctrl`+`u` | Clear filter |
| `Ctrl`+`w` | Delete last part |
| `up`/`down` | Select autocomplete |
6 years ago
6 years ago
### Searching
6 years ago
Press `/` and type regexp pattern to search in current JSON. Search work with currently applied filter.
Examples of pattern and corresponding regexp:
| Pattern | RegExp |
|------------|-------------|
| `/apple` | `/apple/ig` |
| `/apple/` | `/apple/` |
| `/apple/u` | `/apple/u` |
| `/\w+` | `/\w+/ig` |
6 years ago
### Selecting text
You may found what you can't just select text in fx. This is due the fact that all mouse events redirected to stdin. To be able select again you need instruct your terminal not to do it. This can be done by holding special keys while selecting:
6 years ago
| Key | Terminal |
6 years ago
|------------------|---------------|
| `Option`+`Mouse` | iTerm2, Hyper |
| `Fn`+`Mouse` | Terminal.app |
| `Shift`+`Mouse` | Linux |