UNPKG

7.82 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', {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
98// start the spinner
99cli.annotation('sometest', 'annotated with this text')
100```
101
102![annotation demo](assets/annotation.png)
103
104# cli.wait
105
106Waits for 1 second or given milliseconds
107
108```typescript
109await cli.wait()
110await cli.wait(3000)
111```
112
113# cli.table
114
115Displays tabular data
116
117```typescript
118cli.table(data, columns, options)
119```
120
121Where:
122
123- `data`: array of data objects to display
124- `columns`: [Table.Columns](./src/styled/table.ts)
125- `options`: [Table.Options](./src/styled/table.ts)
126
127`cli.table.flags()` returns an object containing all the table flags to include in your command.
128
129```typescript
130{
131 columns: Flags.string({exclusive: ['additional'], description: 'only show provided columns (comma-separated)'}),
132 sort: Flags.string({description: 'property to sort by (prepend '-' for descending)'}),
133 filter: Flags.string({description: 'filter property by partial string matching, ex: name=foo'}),
134 csv: Flags.boolean({exclusive: ['no-truncate'], description: 'output is csv format'}),
135 extended: Flags.boolean({char: 'x', description: 'show extra columns'}),
136 'no-truncate': Flags.boolean({exclusive: ['csv'], description: 'do not truncate output to fit screen'}),
137 'no-header': Flags.boolean({exclusive: ['csv'], description: 'hide table header from output'}),
138}
139```
140
141Passing `{only: ['columns']}` or `{except: ['columns']}` as an argument into `cli.table.flags()` will whitelist/blacklist those flags from the returned object.
142
143`Table.Columns` defines the table columns and their display options.
144
145```typescript
146const columns: Table.Columns = {
147 // where `.name` is a property of a data object
148 name: {}, // "Name" inferred as the column header
149 id: {
150 header: 'ID', // override column header
151 minWidth: '10', // column must display at this width or greater
152 extended: true, // only display this column when the --extended flag is present
153 get: row => `US-O1-${row.id}`, // custom getter for data row object
154 },
155}
156```
157
158`Table.Options` defines the table options, most of which are the parsed flags from the user for display customization, all of which are optional.
159
160```typescript
161const options: Table.Options = {
162 printLine: myLogger, // custom logger
163 columns: flags.columns,
164 sort: flags.sort,
165 filter: flags.filter,
166 csv: flags.csv,
167 extended: flags.extended,
168 'no-truncate': flags['no-truncate'],
169 'no-header': flags['no-header'],
170}
171```
172
173Example class:
174
175```typescript
176import {Command} from '@oclif/command'
177import {cli} from 'cli-ux'
178import axios from 'axios'
179
180export default class Users extends Command {
181 static flags = {
182 ...cli.table.flags()
183 }
184
185 async run() {
186 const {flags} = this.parse(Users)
187 const {data: users} = await axios.get('https://jsonplaceholder.typicode.com/users')
188
189 cli.table(users, {
190 name: {
191 minWidth: 7,
192 },
193 company: {
194 get: row => row.company && row.company.name
195 },
196 id: {
197 header: 'ID',
198 extended: true
199 }
200 }, {
201 printLine: this.log,
202 ...flags, // parsed flags
203 })
204 }
205}
206```
207
208Displays:
209
210```shell
211$ example-cli users
212Name Company
213Leanne Graham Romaguera-Crona
214Ervin Howell Deckow-Crist
215Clementine Bauch Romaguera-Jacobson
216Patricia Lebsack Robel-Corkery
217Chelsey Dietrich Keebler LLC
218Mrs. Dennis Schulist Considine-Lockman
219Kurtis Weissnat Johns Group
220Nicholas Runolfsdottir V Abernathy Group
221Glenna Reichert Yost and Sons
222Clementina DuBuque Hoeger LLC
223
224$ example-cli users --extended
225Name Company ID
226Leanne Graham Romaguera-Crona 1
227Ervin Howell Deckow-Crist 2
228Clementine Bauch Romaguera-Jacobson 3
229Patricia Lebsack Robel-Corkery 4
230Chelsey Dietrich Keebler LLC 5
231Mrs. Dennis Schulist Considine-Lockman 6
232Kurtis Weissnat Johns Group 7
233Nicholas Runolfsdottir V Abernathy Group 8
234Glenna Reichert Yost and Sons 9
235Clementina DuBuque Hoeger LLC 10
236
237$ example-cli users --columns=name
238Name
239Leanne Graham
240Ervin Howell
241Clementine Bauch
242Patricia Lebsack
243Chelsey Dietrich
244Mrs. Dennis Schulist
245Kurtis Weissnat
246Nicholas Runolfsdottir V
247Glenna Reichert
248Clementina DuBuque
249
250$ example-cli users --filter="company=Group"
251Name Company
252Kurtis Weissnat Johns Group
253Nicholas Runolfsdottir V Abernathy Group
254
255$ example-cli users --sort=company
256Name Company
257Nicholas Runolfsdottir V Abernathy Group
258Mrs. Dennis Schulist Considine-Lockman
259Ervin Howell Deckow-Crist
260Clementina DuBuque Hoeger LLC
261Kurtis Weissnat Johns Group
262Chelsey Dietrich Keebler LLC
263Patricia Lebsack Robel-Corkery
264Leanne Graham Romaguera-Crona
265Clementine Bauch Romaguera-Jacobson
266Glenna Reichert Yost and Sons
267```
268
269# cli.tree
270
271Generate a tree and display it
272
273```typescript
274let tree = cli.tree()
275tree.insert('foo')
276tree.insert('bar')
277
278let subtree = cli.tree()
279subtree.insert('qux')
280tree.nodes.bar.insert('baz', subtree)
281
282tree.display()
283```
284
285Outputs:
286```shell
287├─ foo
288└─ bar
289 └─ baz
290 └─ qux
291```