UNPKG

6.64 kBMarkdownView Raw
1# Arg
2
3`arg` is an unopinionated, no-frills CLI argument parser.
4
5## Installation
6
7```bash
8npm install arg
9```
10
11## Usage
12
13`arg()` takes either 1 or 2 arguments:
14
151. Command line specification object (see below)
162. Parse options (_Optional_, defaults to `{permissive: false, argv: process.argv.slice(2), stopAtPositional: false}`)
17
18It returns an object with any values present on the command-line (missing options are thus
19missing from the resulting object). Arg performs no validation/requirement checking - we
20leave that up to the application.
21
22All parameters that aren't consumed by options (commonly referred to as "extra" parameters)
23are added to `result._`, which is _always_ an array (even if no extra parameters are passed,
24in which case an empty array is returned).
25
26```javascript
27const arg = require('arg');
28
29// `options` is an optional parameter
30const args = arg(
31 spec,
32 (options = { permissive: false, argv: process.argv.slice(2) })
33);
34```
35
36For example:
37
38```console
39$ node ./hello.js --verbose -vvv --port=1234 -n 'My name' foo bar --tag qux --tag=qix -- --foobar
40```
41
42```javascript
43// hello.js
44const arg = require('arg');
45
46const args = arg({
47 // Types
48 '--help': Boolean,
49 '--version': Boolean,
50 '--verbose': arg.COUNT, // Counts the number of times --verbose is passed
51 '--port': Number, // --port <number> or --port=<number>
52 '--name': String, // --name <string> or --name=<string>
53 '--tag': [String], // --tag <string> or --tag=<string>
54
55 // Aliases
56 '-v': '--verbose',
57 '-n': '--name', // -n <string>; result is stored in --name
58 '--label': '--name' // --label <string> or --label=<string>;
59 // result is stored in --name
60});
61
62console.log(args);
63/*
64{
65 _: ["foo", "bar", "--foobar"],
66 '--port': 1234,
67 '--verbose': 4,
68 '--name': "My name",
69 '--tag': ["qux", "qix"]
70}
71*/
72```
73
74The values for each key=&gt;value pair is either a type (function or [function]) or a string (indicating an alias).
75
76- In the case of a function, the string value of the argument's value is passed to it,
77 and the return value is used as the ultimate value.
78
79- In the case of an array, the only element _must_ be a type function. Array types indicate
80 that the argument may be passed multiple times, and as such the resulting value in the returned
81 object is an array with all of the values that were passed using the specified flag.
82
83- In the case of a string, an alias is established. If a flag is passed that matches the _key_,
84 then the _value_ is substituted in its place.
85
86Type functions are passed three arguments:
87
881. The parameter value (always a string)
892. The parameter name (e.g. `--label`)
903. The previous value for the destination (useful for reduce-like operations or for supporting `-v` multiple times, etc.)
91
92This means the built-in `String`, `Number`, and `Boolean` type constructors "just work" as type functions.
93
94Note that `Boolean` and `[Boolean]` have special treatment - an option argument is _not_ consumed or passed, but instead `true` is
95returned. These options are called "flags".
96
97For custom handlers that wish to behave as flags, you may pass the function through `arg.flag()`:
98
99```javascript
100const arg = require('arg');
101
102const argv = [
103 '--foo',
104 'bar',
105 '-ff',
106 'baz',
107 '--foo',
108 '--foo',
109 'qux',
110 '-fff',
111 'qix'
112];
113
114function myHandler(value, argName, previousValue) {
115 /* `value` is always `true` */
116 return 'na ' + (previousValue || 'batman!');
117}
118
119const args = arg(
120 {
121 '--foo': arg.flag(myHandler),
122 '-f': '--foo'
123 },
124 {
125 argv
126 }
127);
128
129console.log(args);
130/*
131{
132 _: ['bar', 'baz', 'qux', 'qix'],
133 '--foo': 'na na na na na na na na batman!'
134}
135*/
136```
137
138As well, `arg` supplies a helper argument handler called `arg.COUNT`, which equivalent to a `[Boolean]` argument's `.length`
139property - effectively counting the number of times the boolean flag, denoted by the key, is passed on the command line..
140For example, this is how you could implement `ssh`'s multiple levels of verbosity (`-vvvv` being the most verbose).
141
142```javascript
143const arg = require('arg');
144
145const argv = ['-AAAA', '-BBBB'];
146
147const args = arg(
148 {
149 '-A': arg.COUNT,
150 '-B': [Boolean]
151 },
152 {
153 argv
154 }
155);
156
157console.log(args);
158/*
159{
160 _: [],
161 '-A': 4,
162 '-B': [true, true, true, true]
163}
164*/
165```
166
167### Options
168
169If a second parameter is specified and is an object, it specifies parsing options to modify the behavior of `arg()`.
170
171#### `argv`
172
173If you have already sliced or generated a number of raw arguments to be parsed (as opposed to letting `arg`
174slice them from `process.argv`) you may specify them in the `argv` option.
175
176For example:
177
178```javascript
179const args = arg(
180 {
181 '--foo': String
182 },
183 {
184 argv: ['hello', '--foo', 'world']
185 }
186);
187```
188
189results in:
190
191```javascript
192const args = {
193 _: ['hello'],
194 '--foo': 'world'
195};
196```
197
198#### `permissive`
199
200When `permissive` set to `true`, `arg` will push any unknown arguments
201onto the "extra" argument array (`result._`) instead of throwing an error about
202an unknown flag.
203
204For example:
205
206```javascript
207const arg = require('arg');
208
209const argv = [
210 '--foo',
211 'hello',
212 '--qux',
213 'qix',
214 '--bar',
215 '12345',
216 'hello again'
217];
218
219const args = arg(
220 {
221 '--foo': String,
222 '--bar': Number
223 },
224 {
225 argv,
226 permissive: true
227 }
228);
229```
230
231results in:
232
233```javascript
234const args = {
235 _: ['--qux', 'qix', 'hello again'],
236 '--foo': 'hello',
237 '--bar': 12345
238};
239```
240
241#### `stopAtPositional`
242
243When `stopAtPositional` is set to `true`, `arg` will halt parsing at the first
244positional argument.
245
246For example:
247
248```javascript
249const arg = require('arg');
250
251const argv = ['--foo', 'hello', '--bar'];
252
253const args = arg(
254 {
255 '--foo': Boolean,
256 '--bar': Boolean
257 },
258 {
259 argv,
260 stopAtPositional: true
261 }
262);
263```
264
265results in:
266
267```javascript
268const args = {
269 _: ['hello', '--bar'],
270 '--foo': true
271};
272```
273
274### Errors
275
276Some errors that `arg` throws provide a `.code` property in order to aid in recovering from user error, or to
277differentiate between user error and developer error (bug).
278
279##### ARG_UNKNOWN_OPTION
280
281If an unknown option (not defined in the spec object) is passed, an error with code `ARG_UNKNOWN_OPTION` will be thrown:
282
283```js
284// cli.js
285try {
286 require('arg')({ '--hi': String });
287} catch (err) {
288 if (err.code === 'ARG_UNKNOWN_OPTION') {
289 console.log(err.message);
290 } else {
291 throw err;
292 }
293}
294```
295
296```shell
297node cli.js --extraneous true
298Unknown or unexpected option: --extraneous
299```
300
301# FAQ
302
303A few questions and answers that have been asked before:
304
305### How do I require an argument with `arg`?
306
307Do the assertion yourself, such as:
308
309```javascript
310const args = arg({ '--name': String });
311
312if (!args['--name']) throw new Error('missing required argument: --name');
313```
314
315# License
316
317Released under the [MIT License](LICENSE.md).