@@ -1024,6 +1024,11 @@ equality.
1024
1024
1025
1025
<!-- YAML
1026
1026
added: v18.3.0
1027
+ changes:
1028
+ - version: REPLACEME
1029
+ pr-url: https://github.com/nodejs/node/pull/43459
1030
+ description: add support for returning detailed parse information
1031
+ using `tokens` in input `config` and returned properties.
1027
1032
-->
1028
1033
1029
1034
> Stability: 1 - Experimental
@@ -1040,18 +1045,24 @@ added: v18.3.0
1040
1045
times. If ` true ` , all values will be collected in an array. If
1041
1046
` false ` , values for the option are last-wins. ** Default:** ` false ` .
1042
1047
* ` short ` {string} A single character alias for the option.
1043
- * ` strict ` : {boolean} Should an error be thrown when unknown arguments
1048
+ * ` strict ` {boolean} Should an error be thrown when unknown arguments
1044
1049
are encountered, or when arguments are passed that do not match the
1045
1050
` type ` configured in ` options ` .
1046
1051
** Default:** ` true ` .
1047
- * ` allowPositionals ` : {boolean} Whether this command accepts positional
1052
+ * ` allowPositionals ` {boolean} Whether this command accepts positional
1048
1053
arguments.
1049
1054
** Default:** ` false ` if ` strict ` is ` true ` , otherwise ` true ` .
1055
+ * ` tokens ` {boolean} Return the parsed tokens. This is useful for extending
1056
+ the built-in behavior, from adding additional checks through to reprocessing
1057
+ the tokens in different ways.
1058
+ ** Default:** ` false ` .
1050
1059
1051
1060
* Returns: {Object} The parsed command line arguments:
1052
1061
* ` values ` {Object} A mapping of parsed option names with their {string}
1053
1062
or {boolean} values.
1054
1063
* ` positionals ` {string\[ ] } Positional arguments.
1064
+ * ` tokens ` {Object\[ ] | undefined} See [ parseArgs tokens] ( #parseargs-tokens )
1065
+ section. Only returned if ` config ` includes ` tokens: true ` .
1055
1066
1056
1067
Provides a higher level API for command-line argument parsing than interacting
1057
1068
with ` process.argv ` directly. Takes a specification for the expected arguments
@@ -1100,6 +1111,114 @@ console.log(values, positionals);
1100
1111
` util.parseArgs ` is experimental and behavior may change. Join the
1101
1112
conversation in [ pkgjs/parseargs] [ ] to contribute to the design.
1102
1113
1114
+ ### ` parseArgs ` ` tokens `
1115
+
1116
+ Detailed parse information is available for adding custom behaviours by
1117
+ specifying ` tokens: true ` in the configuration.
1118
+ The returned tokens have properties describing:
1119
+
1120
+ * all tokens
1121
+ * ` kind ` {string} One of 'option', 'positional', or 'option-terminator'.
1122
+ * ` index ` {number} Index of element in ` args ` containing token. So the
1123
+ source argument for a token is ` args[token.index] ` .
1124
+ * option tokens
1125
+ * ` name ` {string} Long name of option.
1126
+ * ` rawName ` {string} How option used in args, like ` -f ` of ` --foo ` .
1127
+ * ` value ` {string | undefined} Option value specified in args.
1128
+ Undefined for boolean options.
1129
+ * ` inlineValue ` {boolean | undefined} Whether option value specified inline,
1130
+ like ` --foo=bar ` .
1131
+ * positional tokens
1132
+ * ` value ` {string} The value of the positional argument in args (i.e. ` args[index] ` ).
1133
+ * option-terminator token
1134
+
1135
+ The returned tokens are in the order encountered in the input args. Options
1136
+ that appear more than once in args produce a token for each use. Short option
1137
+ groups like ` -xy ` expand to a token for each option. So ` -xxx ` produces
1138
+ three tokens.
1139
+
1140
+ For example to use the returned tokens to add support for a negated option
1141
+ like ` --no-color ` , the tokens can be reprocessed to change the value stored
1142
+ for the negated option.
1143
+
1144
+ ``` mjs
1145
+ import { parseArgs } from ' node:util' ;
1146
+
1147
+ const options = {
1148
+ ' color' : { type: ' boolean' },
1149
+ ' no-color' : { type: ' boolean' },
1150
+ ' logfile' : { type: ' string' },
1151
+ ' no-logfile' : { type: ' boolean' },
1152
+ };
1153
+ const { values , tokens } = parseArgs ({ options, tokens: true });
1154
+
1155
+ // Reprocess the option tokens and overwrite the returned values.
1156
+ tokens
1157
+ .filter ((token ) => token .kind === ' option' )
1158
+ .forEach ((token ) => {
1159
+ if (token .name .startsWith (' no-' )) {
1160
+ // Store foo:false for --no-foo
1161
+ const positiveName = token .name .slice (3 );
1162
+ values[positiveName] = false ;
1163
+ delete values[token .name ];
1164
+ } else {
1165
+ // Resave value so last one wins if both --foo and --no-foo.
1166
+ values[token .name ] = token .value ?? true ;
1167
+ }
1168
+ });
1169
+
1170
+ const color = values .color ;
1171
+ const logfile = values .logfile ?? ' default.log' ;
1172
+
1173
+ console .log ({ logfile, color });
1174
+ ` ` `
1175
+
1176
+ ` ` ` cjs
1177
+ const { parseArgs } = require (' node:util' );
1178
+
1179
+ const options = {
1180
+ ' color' : { type: ' boolean' },
1181
+ ' no-color' : { type: ' boolean' },
1182
+ ' logfile' : { type: ' string' },
1183
+ ' no-logfile' : { type: ' boolean' },
1184
+ };
1185
+ const { values , tokens } = parseArgs ({ options, tokens: true });
1186
+
1187
+ // Reprocess the option tokens and overwrite the returned values.
1188
+ tokens
1189
+ .filter ((token ) => token .kind === ' option' )
1190
+ .forEach ((token ) => {
1191
+ if (token .name .startsWith (' no-' )) {
1192
+ // Store foo:false for --no-foo
1193
+ const positiveName = token .name .slice (3 );
1194
+ values[positiveName] = false ;
1195
+ delete values[token .name ];
1196
+ } else {
1197
+ // Resave value so last one wins if both --foo and --no-foo.
1198
+ values[token .name ] = token .value ?? true ;
1199
+ }
1200
+ });
1201
+
1202
+ const color = values .color ;
1203
+ const logfile = values .logfile ?? ' default.log' ;
1204
+
1205
+ console .log ({ logfile, color });
1206
+ ` ` `
1207
+
1208
+ Example usage showing negated options, and when an option is used
1209
+ multiple ways then last one wins.
1210
+
1211
+ ` ` ` console
1212
+ $ node negate .js
1213
+ { logfile: ' default.log' , color: undefined }
1214
+ $ node negate .js -- no- logfile -- no- color
1215
+ { logfile: false , color: false }
1216
+ $ node negate .js -- logfile= test .log -- color
1217
+ { logfile: ' test.log' , color: true }
1218
+ $ node negate .js -- no- logfile -- logfile= test .log -- color -- no- color
1219
+ { logfile: ' test.log' , color: false }
1220
+ ` ` `
1221
+
1103
1222
## ` util .promisify (original)`
1104
1223
1105
1224
<!-- YAML
0 commit comments