@optique/core 0.3.0-dev.34 → 0.3.0-dev.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/parser.cjs +162 -3
- package/dist/parser.d.cts +46 -4
- package/dist/parser.d.ts +46 -4
- package/dist/parser.js +162 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -11,6 +11,7 @@ exports.choice = require_valueparser.choice;
|
|
|
11
11
|
exports.command = require_parser.command;
|
|
12
12
|
exports.concat = require_parser.concat;
|
|
13
13
|
exports.constant = require_parser.constant;
|
|
14
|
+
exports.flag = require_parser.flag;
|
|
14
15
|
exports.float = require_valueparser.float;
|
|
15
16
|
exports.formatDocPage = require_doc.formatDocPage;
|
|
16
17
|
exports.formatMessage = require_message.formatMessage;
|
package/dist/index.d.cts
CHANGED
|
@@ -2,6 +2,6 @@ import { Message, MessageFormatOptions, MessageTerm, formatMessage, message, met
|
|
|
2
2
|
import { OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, formatUsage, formatUsageTerm, normalizeUsage } from "./usage.cjs";
|
|
3
3
|
import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, formatDocPage } from "./doc.cjs";
|
|
4
4
|
import { ChoiceOptions, FloatOptions, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.cjs";
|
|
5
|
-
import { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.cjs";
|
|
5
|
+
import { ArgumentOptions, CommandOptions, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, flag, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.cjs";
|
|
6
6
|
import { RunError, RunOptions, run } from "./facade.cjs";
|
|
7
|
-
export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, argument, choice, command, concat, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
|
7
|
+
export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, argument, choice, command, concat, constant, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import { Message, MessageFormatOptions, MessageTerm, formatMessage, message, met
|
|
|
2
2
|
import { OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, formatUsage, formatUsageTerm, normalizeUsage } from "./usage.js";
|
|
3
3
|
import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, formatDocPage } from "./doc.js";
|
|
4
4
|
import { ChoiceOptions, FloatOptions, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.js";
|
|
5
|
-
import { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
|
|
5
|
+
import { ArgumentOptions, CommandOptions, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, flag, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
|
|
6
6
|
import { RunError, RunOptions, run } from "./facade.js";
|
|
7
|
-
export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, argument, choice, command, concat, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
|
7
|
+
export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, argument, choice, command, concat, constant, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { formatMessage, message, metavar, optionName, optionNames, text, value,
|
|
|
2
2
|
import { formatUsage, formatUsageTerm, normalizeUsage } from "./usage.js";
|
|
3
3
|
import { formatDocPage } from "./doc.js";
|
|
4
4
|
import { choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.js";
|
|
5
|
-
import { argument, command, concat, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
|
|
5
|
+
import { argument, command, concat, constant, flag, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
|
|
6
6
|
import { RunError, run } from "./facade.js";
|
|
7
7
|
|
|
8
|
-
export { RunError, argument, choice, command, concat, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
|
8
|
+
export { RunError, argument, choice, command, concat, constant, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
package/dist/parser.cjs
CHANGED
|
@@ -222,6 +222,163 @@ function option(...args) {
|
|
|
222
222
|
};
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
225
|
+
* Creates a parser for command-line flags that must be explicitly provided.
|
|
226
|
+
* Unlike {@link option}, this parser fails if the flag is not present, making
|
|
227
|
+
* it suitable for required boolean flags that don't have a meaningful default.
|
|
228
|
+
*
|
|
229
|
+
* The key difference from {@link option} is:
|
|
230
|
+
* - {@link option} without a value parser: Returns `false` when not present
|
|
231
|
+
* - {@link flag}: Fails parsing when not present, only produces `true`
|
|
232
|
+
*
|
|
233
|
+
* This is useful for dependent options where the presence of a flag changes
|
|
234
|
+
* the shape of the result type.
|
|
235
|
+
*
|
|
236
|
+
* @param args The {@link OptionName}s to parse, followed by an optional
|
|
237
|
+
* {@link FlagOptions} object that allows you to specify
|
|
238
|
+
* a description or other metadata.
|
|
239
|
+
* @returns A {@link Parser} that produces `true` when the flag is present
|
|
240
|
+
* and fails when it is not present.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* // Basic flag usage
|
|
245
|
+
* const parser = flag("-f", "--force");
|
|
246
|
+
* // Succeeds with true: parse(parser, ["-f"])
|
|
247
|
+
* // Fails: parse(parser, [])
|
|
248
|
+
*
|
|
249
|
+
* // With description
|
|
250
|
+
* const verboseFlag = flag("-v", "--verbose", {
|
|
251
|
+
* description: "Enable verbose output"
|
|
252
|
+
* });
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
function flag(...args) {
|
|
256
|
+
const lastArg = args.at(-1);
|
|
257
|
+
let optionNames$1;
|
|
258
|
+
let options = {};
|
|
259
|
+
if (typeof lastArg === "object" && lastArg != null && !Array.isArray(lastArg)) {
|
|
260
|
+
options = lastArg;
|
|
261
|
+
optionNames$1 = args.slice(0, -1);
|
|
262
|
+
} else optionNames$1 = args;
|
|
263
|
+
return {
|
|
264
|
+
$valueType: [],
|
|
265
|
+
$stateType: [],
|
|
266
|
+
priority: 10,
|
|
267
|
+
usage: [{
|
|
268
|
+
type: "option",
|
|
269
|
+
names: optionNames$1
|
|
270
|
+
}],
|
|
271
|
+
initialState: void 0,
|
|
272
|
+
parse(context) {
|
|
273
|
+
if (context.optionsTerminated) return {
|
|
274
|
+
success: false,
|
|
275
|
+
consumed: 0,
|
|
276
|
+
error: require_message.message`No more options can be parsed.`
|
|
277
|
+
};
|
|
278
|
+
else if (context.buffer.length < 1) return {
|
|
279
|
+
success: false,
|
|
280
|
+
consumed: 0,
|
|
281
|
+
error: require_message.message`Expected an option, but got end of input.`
|
|
282
|
+
};
|
|
283
|
+
if (context.buffer[0] === "--") return {
|
|
284
|
+
success: true,
|
|
285
|
+
next: {
|
|
286
|
+
...context,
|
|
287
|
+
buffer: context.buffer.slice(1),
|
|
288
|
+
state: context.state,
|
|
289
|
+
optionsTerminated: true
|
|
290
|
+
},
|
|
291
|
+
consumed: context.buffer.slice(0, 1)
|
|
292
|
+
};
|
|
293
|
+
if (optionNames$1.includes(context.buffer[0])) {
|
|
294
|
+
if (context.state?.success) return {
|
|
295
|
+
success: false,
|
|
296
|
+
consumed: 1,
|
|
297
|
+
error: require_message.message`${require_message.optionName(context.buffer[0])} cannot be used multiple times.`
|
|
298
|
+
};
|
|
299
|
+
return {
|
|
300
|
+
success: true,
|
|
301
|
+
next: {
|
|
302
|
+
...context,
|
|
303
|
+
state: {
|
|
304
|
+
success: true,
|
|
305
|
+
value: true
|
|
306
|
+
},
|
|
307
|
+
buffer: context.buffer.slice(1)
|
|
308
|
+
},
|
|
309
|
+
consumed: context.buffer.slice(0, 1)
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/")).map((name) => name.startsWith("/") ? `${name}:` : `${name}=`);
|
|
313
|
+
for (const prefix of prefixes) if (context.buffer[0].startsWith(prefix)) {
|
|
314
|
+
const value = context.buffer[0].slice(prefix.length);
|
|
315
|
+
return {
|
|
316
|
+
success: false,
|
|
317
|
+
consumed: 1,
|
|
318
|
+
error: require_message.message`Flag ${require_message.optionName(prefix.slice(0, -1))} does not accept a value, but got: ${value}.`
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
322
|
+
for (const shortOption of shortOptions) {
|
|
323
|
+
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
324
|
+
if (context.state?.success) return {
|
|
325
|
+
success: false,
|
|
326
|
+
consumed: 1,
|
|
327
|
+
error: require_message.message`${require_message.optionName(shortOption)} cannot be used multiple times.`
|
|
328
|
+
};
|
|
329
|
+
return {
|
|
330
|
+
success: true,
|
|
331
|
+
next: {
|
|
332
|
+
...context,
|
|
333
|
+
state: {
|
|
334
|
+
success: true,
|
|
335
|
+
value: true
|
|
336
|
+
},
|
|
337
|
+
buffer: [`-${context.buffer[0].slice(2)}`, ...context.buffer.slice(1)]
|
|
338
|
+
},
|
|
339
|
+
consumed: [context.buffer[0].slice(0, 2)]
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
success: false,
|
|
344
|
+
consumed: 0,
|
|
345
|
+
error: require_message.message`No matched option for ${require_message.optionName(context.buffer[0])}.`
|
|
346
|
+
};
|
|
347
|
+
},
|
|
348
|
+
complete(state) {
|
|
349
|
+
if (state == null) return {
|
|
350
|
+
success: false,
|
|
351
|
+
error: require_message.message`Required flag ${require_message.optionNames(optionNames$1)} is missing.`
|
|
352
|
+
};
|
|
353
|
+
if (state.success) return {
|
|
354
|
+
success: true,
|
|
355
|
+
value: true
|
|
356
|
+
};
|
|
357
|
+
return {
|
|
358
|
+
success: false,
|
|
359
|
+
error: require_message.message`${require_message.optionNames(optionNames$1)}: ${state.error}`
|
|
360
|
+
};
|
|
361
|
+
},
|
|
362
|
+
getDocFragments(_state, _defaultValue) {
|
|
363
|
+
const fragments = [{
|
|
364
|
+
type: "entry",
|
|
365
|
+
term: {
|
|
366
|
+
type: "option",
|
|
367
|
+
names: optionNames$1
|
|
368
|
+
},
|
|
369
|
+
description: options.description
|
|
370
|
+
}];
|
|
371
|
+
return {
|
|
372
|
+
fragments,
|
|
373
|
+
description: options.description
|
|
374
|
+
};
|
|
375
|
+
},
|
|
376
|
+
[Symbol.for("Deno.customInspect")]() {
|
|
377
|
+
return `flag(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
225
382
|
* Creates a parser that expects a single argument value.
|
|
226
383
|
* This parser is typically used for positional arguments
|
|
227
384
|
* that are not options or flags.
|
|
@@ -368,12 +525,13 @@ function optional(parser) {
|
|
|
368
525
|
* a specified default value.
|
|
369
526
|
* @template TValue The type of the value returned by the wrapped parser.
|
|
370
527
|
* @template TState The type of the state used by the wrapped parser.
|
|
528
|
+
* @template TDefault The type of the default value.
|
|
371
529
|
* @param parser The {@link Parser} to wrap with default behavior.
|
|
372
530
|
* @param defaultValue The default value to return when the wrapped parser
|
|
373
531
|
* doesn't match or consume input. Can be a value of type
|
|
374
|
-
* {@link
|
|
532
|
+
* {@link TDefault} or a function that returns such a value.
|
|
375
533
|
* @returns A {@link Parser} that produces either the result of the wrapped parser
|
|
376
|
-
* or the default value if the wrapped parser fails to match.
|
|
534
|
+
* or the default value if the wrapped parser fails to match (union type {@link TValue} | {@link TDefault}).
|
|
377
535
|
*/
|
|
378
536
|
function withDefault(parser, defaultValue) {
|
|
379
537
|
return {
|
|
@@ -408,7 +566,7 @@ function withDefault(parser, defaultValue) {
|
|
|
408
566
|
return parser.complete(state[0]);
|
|
409
567
|
},
|
|
410
568
|
getDocFragments(state, upperDefaultValue) {
|
|
411
|
-
return parser.getDocFragments(typeof state === "undefined" ? parser.initialState : state[0], upperDefaultValue
|
|
569
|
+
return parser.getDocFragments(typeof state === "undefined" ? parser.initialState : state[0], upperDefaultValue != null ? upperDefaultValue : typeof defaultValue === "function" ? defaultValue() : defaultValue);
|
|
412
570
|
}
|
|
413
571
|
};
|
|
414
572
|
}
|
|
@@ -1231,6 +1389,7 @@ exports.argument = argument;
|
|
|
1231
1389
|
exports.command = command;
|
|
1232
1390
|
exports.concat = concat;
|
|
1233
1391
|
exports.constant = constant;
|
|
1392
|
+
exports.flag = flag;
|
|
1234
1393
|
exports.getDocPage = getDocPage;
|
|
1235
1394
|
exports.map = map;
|
|
1236
1395
|
exports.merge = merge;
|
package/dist/parser.d.cts
CHANGED
|
@@ -189,6 +189,47 @@ declare function option(...optionNames: readonly OptionName[]): Parser<boolean,
|
|
|
189
189
|
* values.
|
|
190
190
|
*/
|
|
191
191
|
declare function option(...args: readonly [...readonly OptionName[], OptionOptions]): Parser<boolean, ValueParserResult<boolean> | undefined>;
|
|
192
|
+
/**
|
|
193
|
+
* Options for the {@link flag} parser.
|
|
194
|
+
*/
|
|
195
|
+
interface FlagOptions {
|
|
196
|
+
/**
|
|
197
|
+
* The description of the flag, which can be used for help messages.
|
|
198
|
+
*/
|
|
199
|
+
readonly description?: Message;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Creates a parser for command-line flags that must be explicitly provided.
|
|
203
|
+
* Unlike {@link option}, this parser fails if the flag is not present, making
|
|
204
|
+
* it suitable for required boolean flags that don't have a meaningful default.
|
|
205
|
+
*
|
|
206
|
+
* The key difference from {@link option} is:
|
|
207
|
+
* - {@link option} without a value parser: Returns `false` when not present
|
|
208
|
+
* - {@link flag}: Fails parsing when not present, only produces `true`
|
|
209
|
+
*
|
|
210
|
+
* This is useful for dependent options where the presence of a flag changes
|
|
211
|
+
* the shape of the result type.
|
|
212
|
+
*
|
|
213
|
+
* @param args The {@link OptionName}s to parse, followed by an optional
|
|
214
|
+
* {@link FlagOptions} object that allows you to specify
|
|
215
|
+
* a description or other metadata.
|
|
216
|
+
* @returns A {@link Parser} that produces `true` when the flag is present
|
|
217
|
+
* and fails when it is not present.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* // Basic flag usage
|
|
222
|
+
* const parser = flag("-f", "--force");
|
|
223
|
+
* // Succeeds with true: parse(parser, ["-f"])
|
|
224
|
+
* // Fails: parse(parser, [])
|
|
225
|
+
*
|
|
226
|
+
* // With description
|
|
227
|
+
* const verboseFlag = flag("-v", "--verbose", {
|
|
228
|
+
* description: "Enable verbose output"
|
|
229
|
+
* });
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
declare function flag(...args: readonly [...readonly OptionName[], FlagOptions] | readonly OptionName[]): Parser<true, ValueParserResult<true> | undefined>;
|
|
192
233
|
/**
|
|
193
234
|
* Options for the {@link argument} parser.
|
|
194
235
|
*/
|
|
@@ -230,14 +271,15 @@ declare function optional<TValue, TState>(parser: Parser<TValue, TState>): Parse
|
|
|
230
271
|
* a specified default value.
|
|
231
272
|
* @template TValue The type of the value returned by the wrapped parser.
|
|
232
273
|
* @template TState The type of the state used by the wrapped parser.
|
|
274
|
+
* @template TDefault The type of the default value.
|
|
233
275
|
* @param parser The {@link Parser} to wrap with default behavior.
|
|
234
276
|
* @param defaultValue The default value to return when the wrapped parser
|
|
235
277
|
* doesn't match or consume input. Can be a value of type
|
|
236
|
-
* {@link
|
|
278
|
+
* {@link TDefault} or a function that returns such a value.
|
|
237
279
|
* @returns A {@link Parser} that produces either the result of the wrapped parser
|
|
238
|
-
* or the default value if the wrapped parser fails to match.
|
|
280
|
+
* or the default value if the wrapped parser fails to match (union type {@link TValue} | {@link TDefault}).
|
|
239
281
|
*/
|
|
240
|
-
declare function withDefault<TValue, TState>(parser: Parser<TValue, TState>, defaultValue:
|
|
282
|
+
declare function withDefault<TValue, TState, TDefault = TValue>(parser: Parser<TValue, TState>, defaultValue: TDefault | (() => TDefault)): Parser<TValue | TDefault, [TState] | undefined>;
|
|
241
283
|
/**
|
|
242
284
|
* Creates a parser that transforms the result value of another parser using
|
|
243
285
|
* a mapping function. This enables value transformation while preserving
|
|
@@ -872,4 +914,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
|
|
|
872
914
|
*/
|
|
873
915
|
declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
|
|
874
916
|
//#endregion
|
|
875
|
-
export { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
|
917
|
+
export { ArgumentOptions, CommandOptions, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, flag, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
package/dist/parser.d.ts
CHANGED
|
@@ -189,6 +189,47 @@ declare function option(...optionNames: readonly OptionName[]): Parser<boolean,
|
|
|
189
189
|
* values.
|
|
190
190
|
*/
|
|
191
191
|
declare function option(...args: readonly [...readonly OptionName[], OptionOptions]): Parser<boolean, ValueParserResult<boolean> | undefined>;
|
|
192
|
+
/**
|
|
193
|
+
* Options for the {@link flag} parser.
|
|
194
|
+
*/
|
|
195
|
+
interface FlagOptions {
|
|
196
|
+
/**
|
|
197
|
+
* The description of the flag, which can be used for help messages.
|
|
198
|
+
*/
|
|
199
|
+
readonly description?: Message;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Creates a parser for command-line flags that must be explicitly provided.
|
|
203
|
+
* Unlike {@link option}, this parser fails if the flag is not present, making
|
|
204
|
+
* it suitable for required boolean flags that don't have a meaningful default.
|
|
205
|
+
*
|
|
206
|
+
* The key difference from {@link option} is:
|
|
207
|
+
* - {@link option} without a value parser: Returns `false` when not present
|
|
208
|
+
* - {@link flag}: Fails parsing when not present, only produces `true`
|
|
209
|
+
*
|
|
210
|
+
* This is useful for dependent options where the presence of a flag changes
|
|
211
|
+
* the shape of the result type.
|
|
212
|
+
*
|
|
213
|
+
* @param args The {@link OptionName}s to parse, followed by an optional
|
|
214
|
+
* {@link FlagOptions} object that allows you to specify
|
|
215
|
+
* a description or other metadata.
|
|
216
|
+
* @returns A {@link Parser} that produces `true` when the flag is present
|
|
217
|
+
* and fails when it is not present.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* // Basic flag usage
|
|
222
|
+
* const parser = flag("-f", "--force");
|
|
223
|
+
* // Succeeds with true: parse(parser, ["-f"])
|
|
224
|
+
* // Fails: parse(parser, [])
|
|
225
|
+
*
|
|
226
|
+
* // With description
|
|
227
|
+
* const verboseFlag = flag("-v", "--verbose", {
|
|
228
|
+
* description: "Enable verbose output"
|
|
229
|
+
* });
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
declare function flag(...args: readonly [...readonly OptionName[], FlagOptions] | readonly OptionName[]): Parser<true, ValueParserResult<true> | undefined>;
|
|
192
233
|
/**
|
|
193
234
|
* Options for the {@link argument} parser.
|
|
194
235
|
*/
|
|
@@ -230,14 +271,15 @@ declare function optional<TValue, TState>(parser: Parser<TValue, TState>): Parse
|
|
|
230
271
|
* a specified default value.
|
|
231
272
|
* @template TValue The type of the value returned by the wrapped parser.
|
|
232
273
|
* @template TState The type of the state used by the wrapped parser.
|
|
274
|
+
* @template TDefault The type of the default value.
|
|
233
275
|
* @param parser The {@link Parser} to wrap with default behavior.
|
|
234
276
|
* @param defaultValue The default value to return when the wrapped parser
|
|
235
277
|
* doesn't match or consume input. Can be a value of type
|
|
236
|
-
* {@link
|
|
278
|
+
* {@link TDefault} or a function that returns such a value.
|
|
237
279
|
* @returns A {@link Parser} that produces either the result of the wrapped parser
|
|
238
|
-
* or the default value if the wrapped parser fails to match.
|
|
280
|
+
* or the default value if the wrapped parser fails to match (union type {@link TValue} | {@link TDefault}).
|
|
239
281
|
*/
|
|
240
|
-
declare function withDefault<TValue, TState>(parser: Parser<TValue, TState>, defaultValue:
|
|
282
|
+
declare function withDefault<TValue, TState, TDefault = TValue>(parser: Parser<TValue, TState>, defaultValue: TDefault | (() => TDefault)): Parser<TValue | TDefault, [TState] | undefined>;
|
|
241
283
|
/**
|
|
242
284
|
* Creates a parser that transforms the result value of another parser using
|
|
243
285
|
* a mapping function. This enables value transformation while preserving
|
|
@@ -872,4 +914,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
|
|
|
872
914
|
*/
|
|
873
915
|
declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
|
|
874
916
|
//#endregion
|
|
875
|
-
export { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
|
917
|
+
export { ArgumentOptions, CommandOptions, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, flag, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
package/dist/parser.js
CHANGED
|
@@ -222,6 +222,163 @@ function option(...args) {
|
|
|
222
222
|
};
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
225
|
+
* Creates a parser for command-line flags that must be explicitly provided.
|
|
226
|
+
* Unlike {@link option}, this parser fails if the flag is not present, making
|
|
227
|
+
* it suitable for required boolean flags that don't have a meaningful default.
|
|
228
|
+
*
|
|
229
|
+
* The key difference from {@link option} is:
|
|
230
|
+
* - {@link option} without a value parser: Returns `false` when not present
|
|
231
|
+
* - {@link flag}: Fails parsing when not present, only produces `true`
|
|
232
|
+
*
|
|
233
|
+
* This is useful for dependent options where the presence of a flag changes
|
|
234
|
+
* the shape of the result type.
|
|
235
|
+
*
|
|
236
|
+
* @param args The {@link OptionName}s to parse, followed by an optional
|
|
237
|
+
* {@link FlagOptions} object that allows you to specify
|
|
238
|
+
* a description or other metadata.
|
|
239
|
+
* @returns A {@link Parser} that produces `true` when the flag is present
|
|
240
|
+
* and fails when it is not present.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* // Basic flag usage
|
|
245
|
+
* const parser = flag("-f", "--force");
|
|
246
|
+
* // Succeeds with true: parse(parser, ["-f"])
|
|
247
|
+
* // Fails: parse(parser, [])
|
|
248
|
+
*
|
|
249
|
+
* // With description
|
|
250
|
+
* const verboseFlag = flag("-v", "--verbose", {
|
|
251
|
+
* description: "Enable verbose output"
|
|
252
|
+
* });
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
function flag(...args) {
|
|
256
|
+
const lastArg = args.at(-1);
|
|
257
|
+
let optionNames$1;
|
|
258
|
+
let options = {};
|
|
259
|
+
if (typeof lastArg === "object" && lastArg != null && !Array.isArray(lastArg)) {
|
|
260
|
+
options = lastArg;
|
|
261
|
+
optionNames$1 = args.slice(0, -1);
|
|
262
|
+
} else optionNames$1 = args;
|
|
263
|
+
return {
|
|
264
|
+
$valueType: [],
|
|
265
|
+
$stateType: [],
|
|
266
|
+
priority: 10,
|
|
267
|
+
usage: [{
|
|
268
|
+
type: "option",
|
|
269
|
+
names: optionNames$1
|
|
270
|
+
}],
|
|
271
|
+
initialState: void 0,
|
|
272
|
+
parse(context) {
|
|
273
|
+
if (context.optionsTerminated) return {
|
|
274
|
+
success: false,
|
|
275
|
+
consumed: 0,
|
|
276
|
+
error: message`No more options can be parsed.`
|
|
277
|
+
};
|
|
278
|
+
else if (context.buffer.length < 1) return {
|
|
279
|
+
success: false,
|
|
280
|
+
consumed: 0,
|
|
281
|
+
error: message`Expected an option, but got end of input.`
|
|
282
|
+
};
|
|
283
|
+
if (context.buffer[0] === "--") return {
|
|
284
|
+
success: true,
|
|
285
|
+
next: {
|
|
286
|
+
...context,
|
|
287
|
+
buffer: context.buffer.slice(1),
|
|
288
|
+
state: context.state,
|
|
289
|
+
optionsTerminated: true
|
|
290
|
+
},
|
|
291
|
+
consumed: context.buffer.slice(0, 1)
|
|
292
|
+
};
|
|
293
|
+
if (optionNames$1.includes(context.buffer[0])) {
|
|
294
|
+
if (context.state?.success) return {
|
|
295
|
+
success: false,
|
|
296
|
+
consumed: 1,
|
|
297
|
+
error: message`${optionName(context.buffer[0])} cannot be used multiple times.`
|
|
298
|
+
};
|
|
299
|
+
return {
|
|
300
|
+
success: true,
|
|
301
|
+
next: {
|
|
302
|
+
...context,
|
|
303
|
+
state: {
|
|
304
|
+
success: true,
|
|
305
|
+
value: true
|
|
306
|
+
},
|
|
307
|
+
buffer: context.buffer.slice(1)
|
|
308
|
+
},
|
|
309
|
+
consumed: context.buffer.slice(0, 1)
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/")).map((name) => name.startsWith("/") ? `${name}:` : `${name}=`);
|
|
313
|
+
for (const prefix of prefixes) if (context.buffer[0].startsWith(prefix)) {
|
|
314
|
+
const value = context.buffer[0].slice(prefix.length);
|
|
315
|
+
return {
|
|
316
|
+
success: false,
|
|
317
|
+
consumed: 1,
|
|
318
|
+
error: message`Flag ${optionName(prefix.slice(0, -1))} does not accept a value, but got: ${value}.`
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
322
|
+
for (const shortOption of shortOptions) {
|
|
323
|
+
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
324
|
+
if (context.state?.success) return {
|
|
325
|
+
success: false,
|
|
326
|
+
consumed: 1,
|
|
327
|
+
error: message`${optionName(shortOption)} cannot be used multiple times.`
|
|
328
|
+
};
|
|
329
|
+
return {
|
|
330
|
+
success: true,
|
|
331
|
+
next: {
|
|
332
|
+
...context,
|
|
333
|
+
state: {
|
|
334
|
+
success: true,
|
|
335
|
+
value: true
|
|
336
|
+
},
|
|
337
|
+
buffer: [`-${context.buffer[0].slice(2)}`, ...context.buffer.slice(1)]
|
|
338
|
+
},
|
|
339
|
+
consumed: [context.buffer[0].slice(0, 2)]
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
success: false,
|
|
344
|
+
consumed: 0,
|
|
345
|
+
error: message`No matched option for ${optionName(context.buffer[0])}.`
|
|
346
|
+
};
|
|
347
|
+
},
|
|
348
|
+
complete(state) {
|
|
349
|
+
if (state == null) return {
|
|
350
|
+
success: false,
|
|
351
|
+
error: message`Required flag ${optionNames(optionNames$1)} is missing.`
|
|
352
|
+
};
|
|
353
|
+
if (state.success) return {
|
|
354
|
+
success: true,
|
|
355
|
+
value: true
|
|
356
|
+
};
|
|
357
|
+
return {
|
|
358
|
+
success: false,
|
|
359
|
+
error: message`${optionNames(optionNames$1)}: ${state.error}`
|
|
360
|
+
};
|
|
361
|
+
},
|
|
362
|
+
getDocFragments(_state, _defaultValue) {
|
|
363
|
+
const fragments = [{
|
|
364
|
+
type: "entry",
|
|
365
|
+
term: {
|
|
366
|
+
type: "option",
|
|
367
|
+
names: optionNames$1
|
|
368
|
+
},
|
|
369
|
+
description: options.description
|
|
370
|
+
}];
|
|
371
|
+
return {
|
|
372
|
+
fragments,
|
|
373
|
+
description: options.description
|
|
374
|
+
};
|
|
375
|
+
},
|
|
376
|
+
[Symbol.for("Deno.customInspect")]() {
|
|
377
|
+
return `flag(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
225
382
|
* Creates a parser that expects a single argument value.
|
|
226
383
|
* This parser is typically used for positional arguments
|
|
227
384
|
* that are not options or flags.
|
|
@@ -368,12 +525,13 @@ function optional(parser) {
|
|
|
368
525
|
* a specified default value.
|
|
369
526
|
* @template TValue The type of the value returned by the wrapped parser.
|
|
370
527
|
* @template TState The type of the state used by the wrapped parser.
|
|
528
|
+
* @template TDefault The type of the default value.
|
|
371
529
|
* @param parser The {@link Parser} to wrap with default behavior.
|
|
372
530
|
* @param defaultValue The default value to return when the wrapped parser
|
|
373
531
|
* doesn't match or consume input. Can be a value of type
|
|
374
|
-
* {@link
|
|
532
|
+
* {@link TDefault} or a function that returns such a value.
|
|
375
533
|
* @returns A {@link Parser} that produces either the result of the wrapped parser
|
|
376
|
-
* or the default value if the wrapped parser fails to match.
|
|
534
|
+
* or the default value if the wrapped parser fails to match (union type {@link TValue} | {@link TDefault}).
|
|
377
535
|
*/
|
|
378
536
|
function withDefault(parser, defaultValue) {
|
|
379
537
|
return {
|
|
@@ -408,7 +566,7 @@ function withDefault(parser, defaultValue) {
|
|
|
408
566
|
return parser.complete(state[0]);
|
|
409
567
|
},
|
|
410
568
|
getDocFragments(state, upperDefaultValue) {
|
|
411
|
-
return parser.getDocFragments(typeof state === "undefined" ? parser.initialState : state[0], upperDefaultValue
|
|
569
|
+
return parser.getDocFragments(typeof state === "undefined" ? parser.initialState : state[0], upperDefaultValue != null ? upperDefaultValue : typeof defaultValue === "function" ? defaultValue() : defaultValue);
|
|
412
570
|
}
|
|
413
571
|
};
|
|
414
572
|
}
|
|
@@ -1227,4 +1385,4 @@ function getDocPage(parser, args = []) {
|
|
|
1227
1385
|
}
|
|
1228
1386
|
|
|
1229
1387
|
//#endregion
|
|
1230
|
-
export { argument, command, concat, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
|
1388
|
+
export { argument, command, concat, constant, flag, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|