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