Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

util: add parseArgs module #42675

Merged
merged 2 commits into from May 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 35 additions & 0 deletions doc/api/errors.md
Expand Up @@ -2355,6 +2355,40 @@ The `package.json` [`"exports"`][] field does not export the requested subpath.
Because exports are encapsulated, private internal modules that are not exported
cannot be imported through the package resolution, unless using an absolute URL.

<a id="ERR_PARSE_ARGS_INVALID_OPTION_VALUE"></a>

### `ERR_PARSE_ARGS_INVALID_OPTION_VALUE`
bcoe marked this conversation as resolved.
Show resolved Hide resolved

<!-- YAML
added: REPLACEME
-->

When `strict` set to `true`, thrown by [`util.parseArgs()`][] if a {boolean}
value is provided for an option of type {string}, or if a {string}
value is provided for an option of type {boolean}.

<a id="ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL"></a>

### `ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL`

<!-- YAML
added: REPLACEME
-->

Thrown by [`util.parseArgs()`][], when a postional argument is provided and
`allowPositionals` is set to `false`.

<a id="ERR_PARSE_ARGS_UNKNOWN_OPTION"></a>

### `ERR_PARSE_ARGS_UNKNOWN_OPTION`

<!-- YAML
added: REPLACEME
-->

When `strict` set to `true`, thrown by [`util.parseArgs()`][] if an argument
is not configured in `options`.

<a id="ERR_PERFORMANCE_INVALID_TIMESTAMP"></a>

### `ERR_PERFORMANCE_INVALID_TIMESTAMP`
Expand Down Expand Up @@ -3466,6 +3500,7 @@ The native call from `process.cpuUsage` could not be processed.
[`subprocess.send()`]: child_process.md#subprocesssendmessage-sendhandle-options-callback
[`url.parse()`]: url.md#urlparseurlstring-parsequerystring-slashesdenotehost
[`util.getSystemErrorName(error.errno)`]: util.md#utilgetsystemerrornameerr
[`util.parseArgs()`]: util.md#utilparseargsconfig
[`zlib`]: zlib.md
[crypto digest algorithm]: crypto.md#cryptogethashes
[debugger]: debugger.md
Expand Down
81 changes: 81 additions & 0 deletions doc/api/util.md
Expand Up @@ -1020,6 +1020,86 @@ Otherwise, returns `false`.
See [`assert.deepStrictEqual()`][] for more information about deep strict
equality.

## `util.parseArgs([config])`
bcoe marked this conversation as resolved.
Show resolved Hide resolved

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
* `config` {Object} Used to provide arguments for parsing and to configure
the parser. `config` supports the following properties:
* `args` {string\[]} array of argument strings. **Default:** `process.argv`
with `execPath` and `filename` removed.
bcoe marked this conversation as resolved.
Show resolved Hide resolved
* `options` {Object} Used to describe arguments known to the parser.
Keys of `options` are the long names of options and values are an
{Object} accepting the following properties:
* `type` {string} Type of argument, which must be either `boolean` or `string`.
* `multiple` {boolean} Whether this option can be provided multiple
times. If `true`, all values will be collected in an array. If
`false`, values for the option are last-wins. **Default:** `false`.
* `short` {string} A single character alias for the option.
* `strict`: {boolean} Should an error be thrown when unknown arguments
are encountered, or when arguments are passed that do not match the
`type` configured in `options`.
**Default:** `true`.
* `allowPositionals`: {boolean} Whether this command accepts positional
arguments.
**Default:** `false` if `strict` is `true`, otherwise `true`.

* Returns: {Object} The parsed command line arguments:
* `values` {Object} A mapping of parsed option names with their {string}
or {boolean} values.
* `positionals` {string\[]} Positional arguments.

Provides a higher level API for command-line argument parsing than interacting
with `process.argv` directly. Takes a specification for the expected arguments
and returns a structured object with the parsed options and positionals.

```mjs
import { parseArgs } from 'node:util';
const args = ['-f', '--bar', 'b'];
const options = {
foo: {
type: 'boolean',
short: 'f'
},
bar: {
type: 'string'
}
};
const {
values,
positionals
} = parseArgs({ args, options });
bcoe marked this conversation as resolved.
Show resolved Hide resolved
console.log(values, positionals);
// Prints: [Object: null prototype] { foo: true, bar: 'b' } []
```

```cjs
const { parseArgs } = require('node:util');
const args = ['-f', '--bar', 'b'];
const options = {
foo: {
type: 'boolean',
short: 'f'
},
bar: {
type: 'string'
}
};
const {
values,
positionals
} = parseArgs({ args, options });
console.log(values, positionals);
// Prints: [Object: null prototype] { foo: true, bar: 'b' } []ss
```

`util.parseArgs` is experimental and behavior may change. Join the
conversation in [pkgjs/parseargs][] to contribute to the design.

## `util.promisify(original)`

<!-- YAML
Expand Down Expand Up @@ -2693,5 +2773,6 @@ util.log('Timestamped message.');
[default sort]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
[global symbol registry]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for
[list of deprecated APIS]: deprecations.md#list-of-deprecated-apis
[pkgjs/parseargs]: https://github.com/pkgjs/parseargs
[semantically incompatible]: https://github.com/nodejs/node/issues/4179
[util.inspect.custom]: #utilinspectcustom
9 changes: 9 additions & 0 deletions lib/internal/errors.js
Expand Up @@ -1481,6 +1481,15 @@ E('ERR_PACKAGE_PATH_NOT_EXPORTED', (pkgPath, subpath, base = undefined) => {
return `Package subpath '${subpath}' is not defined by "exports" in ${
pkgPath}package.json${base ? ` imported from ${base}` : ''}`;
}, Error);
E('ERR_PARSE_ARGS_INVALID_OPTION_VALUE', '%s', TypeError);
bcoe marked this conversation as resolved.
Show resolved Hide resolved
E('ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL', "Unexpected argument '%s'. This " +
'command does not take positional arguments', TypeError);
E('ERR_PARSE_ARGS_UNKNOWN_OPTION', (option, allowPositionals) => {
const suggestDashDash = allowPositionals ? '. To specify a positional ' +
"argument starting with a '-', place it at the end of the command after " +
`'--', as in '-- ${JSONStringify(option)}` : '';
return `Unknown option '${option}'${suggestDashDash}`;
}, TypeError);
E('ERR_PERFORMANCE_INVALID_TIMESTAMP',
'%d is not a valid timestamp', TypeError);
E('ERR_PERFORMANCE_MEASURE_INVALID_OPTIONS', '%s', TypeError);
Expand Down