UNPKG

8.65 kBMarkdownView Raw
1cli-ux
2======
3
4cli IO utilities
5
6[![Version](https://img.shields.io/npm/v/cli-ux.svg)](https://npmjs.org/package/cli-ux)
7[![CircleCI](https://circleci.com/gh/oclif/cli-ux/tree/master.svg?style=svg)](https://circleci.com/gh/oclif/cli-ux/tree/master)
8[![Appveyor CI](https://ci.appveyor.com/api/projects/status/github/oclif/cli-ux?branch=master&svg=true)](https://ci.appveyor.com/project/heroku/cli-ux/branch/master)
9[![Known Vulnerabilities](https://snyk.io/test/npm/cli-ux/badge.svg)](https://snyk.io/test/npm/cli-ux)
10[![Downloads/week](https://img.shields.io/npm/dw/cli-ux.svg)](https://npmjs.org/package/cli-ux)
11[![License](https://img.shields.io/npm/l/cli-ux.svg)](https://github.com/oclif/cli-ux/blob/master/package.json)
12
13# Usage
14
15The following assumes you have installed `cli-ux` to your project with `npm install cli-ux` or `yarn add cli-ux` and have it required in your script (TypeScript example):
16
17```typescript
18import cli from 'cli-ux'
19cli.prompt('What is your name?')
20```
21
22JavaScript:
23
24```javascript
25const {cli} = require('cli-ux')
26
27cli.prompt('What is your name?')
28```
29
30# cli.prompt()
31
32Prompt for user input.
33
34```typescript
35// just prompt for input
36await cli.prompt('What is your name?')
37
38// mask input after enter is pressed
39await cli.prompt('What is your two-factor token?', {type: 'mask'})
40
41// mask input on keypress (before enter is pressed)
42await cli.prompt('What is your password?', {type: 'hide'})
43
44// yes/no confirmation
45await cli.confirm('Continue?')
46
47// "press any key to continue"
48await cli.anykey()
49```
50
51![prompt demo](assets/prompt.gif)
52
53# cli.url(text, uri)
54
55Create a hyperlink (if supported in the terminal)
56
57```typescript
58await cli.url('sometext', 'https://google.com')
59// shows sometext as a hyperlink in supported terminals
60// shows https://google.com in unsupported terminals
61```
62
63![url demo](assets/url.gif)
64
65# cli.open
66
67Open a url in the browser
68
69```typescript
70await cli.open('https://oclif.io')
71```
72
73# cli.action
74
75Shows a spinner
76
77```typescript
78// start the spinner
79cli.action.start('starting a process')
80// show on stdout instead of stderr
81cli.action.start('starting a process', 'initializing', {stdout: true})
82
83// stop the spinner
84cli.action.stop() // shows 'starting a process... done'
85cli.action.stop('custom message') // shows 'starting a process... custom message'
86```
87
88This degrades gracefully when not connected to a TTY. It queues up any writes to stdout/stderr so they are displayed above the spinner.
89
90![action demo](assets/action.gif)
91
92# cli.annotation
93
94Shows an iterm annotation
95
96```typescript
97cli.annotation('sometext', 'annotated with this text')
98```
99
100![annotation demo](assets/annotation.png)
101
102# cli.wait
103
104Waits for 1 second or given milliseconds
105
106```typescript
107await cli.wait()
108await cli.wait(3000)
109```
110
111# cli.table
112
113Displays tabular data
114
115```typescript
116cli.table(data, columns, options)
117```
118
119Where:
120
121- `data`: array of data objects to display
122- `columns`: [Table.Columns](./src/styled/table.ts)
123- `options`: [Table.Options](./src/styled/table.ts)
124
125`cli.table.flags()` returns an object containing all the table flags to include in your command.
126
127```typescript
128{
129 columns: Flags.string({exclusive: ['additional'], description: 'only show provided columns (comma-separated)'}),
130 sort: Flags.string({description: 'property to sort by (prepend '-' for descending)'}),
131 filter: Flags.string({description: 'filter property by partial string matching, ex: name=foo'}),
132 csv: Flags.boolean({exclusive: ['no-truncate'], description: 'output is csv format'}),
133 extended: Flags.boolean({char: 'x', description: 'show extra columns'}),
134 'no-truncate': Flags.boolean({exclusive: ['csv'], description: 'do not truncate output to fit screen'}),
135 'no-header': Flags.boolean({exclusive: ['csv'], description: 'hide table header from output'}),
136}
137```
138
139Passing `{only: ['columns']}` or `{except: ['columns']}` as an argument into `cli.table.flags()` will allow/block those flags from the returned object.
140
141`Table.Columns` defines the table columns and their display options.
142
143```typescript
144const columns: Table.Columns = {
145 // where `.name` is a property of a data object
146 name: {}, // "Name" inferred as the column header
147 id: {
148 header: 'ID', // override column header
149 minWidth: '10', // column must display at this width or greater
150 extended: true, // only display this column when the --extended flag is present
151 get: row => `US-O1-${row.id}`, // custom getter for data row object
152 },
153}
154```
155
156`Table.Options` defines the table options, most of which are the parsed flags from the user for display customization, all of which are optional.
157
158```typescript
159const options: Table.Options = {
160 printLine: myLogger, // custom logger
161 columns: flags.columns,
162 sort: flags.sort,
163 filter: flags.filter,
164 csv: flags.csv,
165 extended: flags.extended,
166 'no-truncate': flags['no-truncate'],
167 'no-header': flags['no-header'],
168}
169```
170
171Example class:
172
173```typescript
174import {Command} from '@oclif/command'
175import {cli} from 'cli-ux'
176import axios from 'axios'
177
178export default class Users extends Command {
179 static flags = {
180 ...cli.table.flags()
181 }
182
183 async run() {
184 const {flags} = this.parse(Users)
185 const {data: users} = await axios.get('https://jsonplaceholder.typicode.com/users')
186
187 cli.table(users, {
188 name: {
189 minWidth: 7,
190 },
191 company: {
192 get: row => row.company && row.company.name
193 },
194 id: {
195 header: 'ID',
196 extended: true
197 }
198 }, {
199 printLine: this.log,
200 ...flags, // parsed flags
201 })
202 }
203}
204```
205
206Displays:
207
208```shell
209$ example-cli users
210Name Company
211Leanne Graham Romaguera-Crona
212Ervin Howell Deckow-Crist
213Clementine Bauch Romaguera-Jacobson
214Patricia Lebsack Robel-Corkery
215Chelsey Dietrich Keebler LLC
216Mrs. Dennis Schulist Considine-Lockman
217Kurtis Weissnat Johns Group
218Nicholas Runolfsdottir V Abernathy Group
219Glenna Reichert Yost and Sons
220Clementina DuBuque Hoeger LLC
221
222$ example-cli users --extended
223Name Company ID
224Leanne Graham Romaguera-Crona 1
225Ervin Howell Deckow-Crist 2
226Clementine Bauch Romaguera-Jacobson 3
227Patricia Lebsack Robel-Corkery 4
228Chelsey Dietrich Keebler LLC 5
229Mrs. Dennis Schulist Considine-Lockman 6
230Kurtis Weissnat Johns Group 7
231Nicholas Runolfsdottir V Abernathy Group 8
232Glenna Reichert Yost and Sons 9
233Clementina DuBuque Hoeger LLC 10
234
235$ example-cli users --columns=name
236Name
237Leanne Graham
238Ervin Howell
239Clementine Bauch
240Patricia Lebsack
241Chelsey Dietrich
242Mrs. Dennis Schulist
243Kurtis Weissnat
244Nicholas Runolfsdottir V
245Glenna Reichert
246Clementina DuBuque
247
248$ example-cli users --filter="company=Group"
249Name Company
250Kurtis Weissnat Johns Group
251Nicholas Runolfsdottir V Abernathy Group
252
253$ example-cli users --sort=company
254Name Company
255Nicholas Runolfsdottir V Abernathy Group
256Mrs. Dennis Schulist Considine-Lockman
257Ervin Howell Deckow-Crist
258Clementina DuBuque Hoeger LLC
259Kurtis Weissnat Johns Group
260Chelsey Dietrich Keebler LLC
261Patricia Lebsack Robel-Corkery
262Leanne Graham Romaguera-Crona
263Clementine Bauch Romaguera-Jacobson
264Glenna Reichert Yost and Sons
265```
266
267# cli.tree
268
269Generate a tree and display it
270
271```typescript
272let tree = cli.tree()
273tree.insert('foo')
274tree.insert('bar')
275
276let subtree = cli.tree()
277subtree.insert('qux')
278tree.nodes.bar.insert('baz', subtree)
279
280tree.display()
281```
282
283Outputs:
284```shell
285├─ foo
286└─ bar
287 └─ baz
288 └─ qux
289```
290
291# cli.progress
292
293Generate a customizable progress bar and display it
294
295```typescript
296const simpleBar = cli.progress()
297simpleBar.start()
298
299const customBar = cli.progress({
300 format: 'PROGRESS | {bar} | {value}/{total} Files',
301 barCompleteChar: '\u2588',
302 barIncompleteChar: '\u2591',
303 })
304customBar.start()
305```
306
307Outputs:
308```shell
309bar1:
310progress [=====================-------------------] 53% | ETA: 1s | 53/100
311bar2:
312PROGRESS | █████████████████████████████░░░░░░░░░░░ | 146/204 Files
313```
314
315To see a more detailed example, run
316```shell script
317$ ts-node examples/progress.ts
318```
319
320This extends [cli-progress](https://www.npmjs.com/package/cli-progress)
321see all of the options and customizations there, which can be passed in with the options object.
322Only the single bar variant of cli-progress is currently supported.
323