UNPKG

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