@optique/core 0.2.0 → 0.3.0-dev.35

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 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.
@@ -1231,6 +1388,7 @@ exports.argument = argument;
1231
1388
  exports.command = command;
1232
1389
  exports.concat = concat;
1233
1390
  exports.constant = constant;
1391
+ exports.flag = flag;
1234
1392
  exports.getDocPage = getDocPage;
1235
1393
  exports.map = map;
1236
1394
  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
  */
@@ -434,6 +475,166 @@ declare function or<TA, TB, TC, TD, TStateA, TStateB, TStateC, TStateD>(a: Parse
434
475
  * in order, returning the result of the first successful parser.
435
476
  */
436
477
  declare function or<TA, TB, TC, TD, TE, TStateA, TStateB, TStateC, TStateD, TStateE>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>): Parser<TA | TB | TC | TD | TE, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>]>;
478
+ /**
479
+ * Creates a parser that combines six mutually exclusive parsers into one.
480
+ * The resulting parser will try each of the provided parsers in order,
481
+ * and return the result of the first successful parser.
482
+ * @template TA The type of the value returned by the first parser.
483
+ * @template TB The type of the value returned by the second parser.
484
+ * @template TC The type of the value returned by the third parser.
485
+ * @template TD The type of the value returned by the fourth parser.
486
+ * @template TE The type of the value returned by the fifth parser.
487
+ * @template TF The type of the value returned by the sixth parser.
488
+ * @template TStateA The type of the state used by the first parser.
489
+ * @template TStateB The type of the state used by the second parser.
490
+ * @template TStateC The type of the state used by the third parser.
491
+ * @template TStateD The type of the state used by the fourth parser.
492
+ * @template TStateE The type of the state used by the fifth parser.
493
+ * @template TStateF The type of the state used by the sixth parser.
494
+ * @param a The first {@link Parser} to try.
495
+ * @param b The second {@link Parser} to try.
496
+ * @param c The third {@link Parser} to try.
497
+ * @param d The fourth {@link Parser} to try.
498
+ * @param e The fifth {@link Parser} to try.
499
+ * @param f The sixth {@link Parser} to try.
500
+ * @return A {@link Parser} that tries to parse using the provided parsers
501
+ * in order, returning the result of the first successful parser.
502
+ */
503
+ declare function or<TA, TB, TC, TD, TE, TF, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>): Parser<TA | TB | TC | TD | TE | TF, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>]>;
504
+ /**
505
+ * Creates a parser that combines seven mutually exclusive parsers into one.
506
+ * The resulting parser will try each of the provided parsers in order,
507
+ * and return the result of the first successful parser.
508
+ * @template TA The type of the value returned by the first parser.
509
+ * @template TB The type of the value returned by the second parser.
510
+ * @template TC The type of the value returned by the third parser.
511
+ * @template TD The type of the value returned by the fourth parser.
512
+ * @template TE The type of the value returned by the fifth parser.
513
+ * @template TF The type of the value returned by the sixth parser.
514
+ * @template TG The type of the value returned by the seventh parser.
515
+ * @template TStateA The type of the state used by the first parser.
516
+ * @template TStateB The type of the state used by the second parser.
517
+ * @template TStateC The type of the state used by the third parser.
518
+ * @template TStateD The type of the state used by the fourth parser.
519
+ * @template TStateE The type of the state used by the fifth parser.
520
+ * @template TStateF The type of the state used by the sixth parser.
521
+ * @template TStateG The type of the state used by the seventh parser.
522
+ * @param a The first {@link Parser} to try.
523
+ * @param b The second {@link Parser} to try.
524
+ * @param c The third {@link Parser} to try.
525
+ * @param d The fourth {@link Parser} to try.
526
+ * @param e The fifth {@link Parser} to try.
527
+ * @param f The sixth {@link Parser} to try.
528
+ * @param g The seventh {@link Parser} to try.
529
+ * @return A {@link Parser} that tries to parse using the provided parsers
530
+ * in order, returning the result of the first successful parser.
531
+ */
532
+ declare function or<TA, TB, TC, TD, TE, TF, TG, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF, TStateG>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>, g: Parser<TG, TStateG>): Parser<TA | TB | TC | TD | TE | TF | TG, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>] | [6, ParserResult<TStateG>]>;
533
+ /**
534
+ * Creates a parser that combines eight mutually exclusive parsers into one.
535
+ * The resulting parser will try each of the provided parsers in order,
536
+ * and return the result of the first successful parser.
537
+ * @template TA The type of the value returned by the first parser.
538
+ * @template TB The type of the value returned by the second parser.
539
+ * @template TC The type of the value returned by the third parser.
540
+ * @template TD The type of the value returned by the fourth parser.
541
+ * @template TE The type of the value returned by the fifth parser.
542
+ * @template TF The type of the value returned by the sixth parser.
543
+ * @template TG The type of the value returned by the seventh parser.
544
+ * @template TH The type of the value returned by the eighth parser.
545
+ * @template TStateA The type of the state used by the first parser.
546
+ * @template TStateB The type of the state used by the second parser.
547
+ * @template TStateC The type of the state used by the third parser.
548
+ * @template TStateD The type of the state used by the fourth parser.
549
+ * @template TStateE The type of the state used by the fifth parser.
550
+ * @template TStateF The type of the state used by the sixth parser.
551
+ * @template TStateG The type of the state used by the seventh parser.
552
+ * @template TStateH The type of the state used by the eighth parser.
553
+ * @param a The first {@link Parser} to try.
554
+ * @param b The second {@link Parser} to try.
555
+ * @param c The third {@link Parser} to try.
556
+ * @param d The fourth {@link Parser} to try.
557
+ * @param e The fifth {@link Parser} to try.
558
+ * @param f The sixth {@link Parser} to try.
559
+ * @param g The seventh {@link Parser} to try.
560
+ * @param h The eighth {@link Parser} to try.
561
+ * @return A {@link Parser} that tries to parse using the provided parsers
562
+ * in order, returning the result of the first successful parser.
563
+ */
564
+ declare function or<TA, TB, TC, TD, TE, TF, TG, TH, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF, TStateG, TStateH>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>, g: Parser<TG, TStateG>, h: Parser<TH, TStateH>): Parser<TA | TB | TC | TD | TE | TF | TG | TH, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>] | [6, ParserResult<TStateG>] | [7, ParserResult<TStateH>]>;
565
+ /**
566
+ * Creates a parser that combines nine mutually exclusive parsers into one.
567
+ * The resulting parser will try each of the provided parsers in order,
568
+ * and return the result of the first successful parser.
569
+ * @template TA The type of the value returned by the first parser.
570
+ * @template TB The type of the value returned by the second parser.
571
+ * @template TC The type of the value returned by the third parser.
572
+ * @template TD The type of the value returned by the fourth parser.
573
+ * @template TE The type of the value returned by the fifth parser.
574
+ * @template TF The type of the value returned by the sixth parser.
575
+ * @template TG The type of the value returned by the seventh parser.
576
+ * @template TH The type of the value returned by the eighth parser.
577
+ * @template TI The type of the value returned by the ninth parser.
578
+ * @template TStateA The type of the state used by the first parser.
579
+ * @template TStateB The type of the state used by the second parser.
580
+ * @template TStateC The type of the state used by the third parser.
581
+ * @template TStateD The type of the state used by the fourth parser.
582
+ * @template TStateE The type of the state used by the fifth parser.
583
+ * @template TStateF The type of the state used by the sixth parser.
584
+ * @template TStateG The type of the state used by the seventh parser.
585
+ * @template TStateH The type of the state used by the eighth parser.
586
+ * @template TStateI The type of the state used by the ninth parser.
587
+ * @param a The first {@link Parser} to try.
588
+ * @param b The second {@link Parser} to try.
589
+ * @param c The third {@link Parser} to try.
590
+ * @param d The fourth {@link Parser} to try.
591
+ * @param e The fifth {@link Parser} to try.
592
+ * @param f The sixth {@link Parser} to try.
593
+ * @param g The seventh {@link Parser} to try.
594
+ * @param h The eighth {@link Parser} to try.
595
+ * @param i The ninth {@link Parser} to try.
596
+ * @return A {@link Parser} that tries to parse using the provided parsers
597
+ * in order, returning the result of the first successful parser.
598
+ */
599
+ declare function or<TA, TB, TC, TD, TE, TF, TG, TH, TI, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF, TStateG, TStateH, TStateI>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>, g: Parser<TG, TStateG>, h: Parser<TH, TStateH>, i: Parser<TI, TStateI>): Parser<TA | TB | TC | TD | TE | TF | TG | TH | TI, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>] | [6, ParserResult<TStateG>] | [7, ParserResult<TStateH>] | [8, ParserResult<TStateI>]>;
600
+ /**
601
+ * Creates a parser that combines ten mutually exclusive parsers into one.
602
+ * The resulting parser will try each of the provided parsers in order,
603
+ * and return the result of the first successful parser.
604
+ * @template TA The type of the value returned by the first parser.
605
+ * @template TB The type of the value returned by the second parser.
606
+ * @template TC The type of the value returned by the third parser.
607
+ * @template TD The type of the value returned by the fourth parser.
608
+ * @template TE The type of the value returned by the fifth parser.
609
+ * @template TF The type of the value returned by the sixth parser.
610
+ * @template TG The type of the value returned by the seventh parser.
611
+ * @template TH The type of the value returned by the eighth parser.
612
+ * @template TI The type of the value returned by the ninth parser.
613
+ * @template TJ The type of the value returned by the tenth parser.
614
+ * @template TStateA The type of the state used by the first parser.
615
+ * @template TStateB The type of the state used by the second parser.
616
+ * @template TStateC The type of the state used by the third parser.
617
+ * @template TStateD The type of the state used by the fourth parser.
618
+ * @template TStateE The type of the state used by the fifth parser.
619
+ * @template TStateF The type of the state used by the sixth parser.
620
+ * @template TStateG The type of the state used by the seventh parser.
621
+ * @template TStateH The type of the state used by the eighth parser.
622
+ * @template TStateI The type of the state used by the ninth parser.
623
+ * @template TStateJ The type of the state used by the tenth parser.
624
+ * @param a The first {@link Parser} to try.
625
+ * @param b The second {@link Parser} to try.
626
+ * @param c The third {@link Parser} to try.
627
+ * @param d The fourth {@link Parser} to try.
628
+ * @param e The fifth {@link Parser} to try.
629
+ * @param f The sixth {@link Parser} to try.
630
+ * @param g The seventh {@link Parser} to try.
631
+ * @param h The eighth {@link Parser} to try.
632
+ * @param i The ninth {@link Parser} to try.
633
+ * @param j The tenth {@link Parser} to try.
634
+ * @return A {@link Parser} that tries to parse using the provided parsers
635
+ * in order, returning the result of the first successful parser.
636
+ */
637
+ declare function or<TA, TB, TC, TD, TE, TF, TG, TH, TI, TJ, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF, TStateG, TStateH, TStateI, TStateJ>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>, g: Parser<TG, TStateG>, h: Parser<TH, TStateH>, i: Parser<TI, TStateI>, j: Parser<TJ, TStateJ>): Parser<TA | TB | TC | TD | TE | TF | TG | TH | TI | TJ, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>] | [6, ParserResult<TStateG>] | [7, ParserResult<TStateH>] | [8, ParserResult<TStateI>] | [9, ParserResult<TStateJ>]>;
437
638
  /**
438
639
  * Merges multiple {@link object} parsers into a single {@link object} parser.
439
640
  * It is useful for combining multiple {@link object} parsers so that
@@ -712,4 +913,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
712
913
  */
713
914
  declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
714
915
  //#endregion
715
- 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 };
916
+ 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
  */
@@ -434,6 +475,166 @@ declare function or<TA, TB, TC, TD, TStateA, TStateB, TStateC, TStateD>(a: Parse
434
475
  * in order, returning the result of the first successful parser.
435
476
  */
436
477
  declare function or<TA, TB, TC, TD, TE, TStateA, TStateB, TStateC, TStateD, TStateE>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>): Parser<TA | TB | TC | TD | TE, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>]>;
478
+ /**
479
+ * Creates a parser that combines six mutually exclusive parsers into one.
480
+ * The resulting parser will try each of the provided parsers in order,
481
+ * and return the result of the first successful parser.
482
+ * @template TA The type of the value returned by the first parser.
483
+ * @template TB The type of the value returned by the second parser.
484
+ * @template TC The type of the value returned by the third parser.
485
+ * @template TD The type of the value returned by the fourth parser.
486
+ * @template TE The type of the value returned by the fifth parser.
487
+ * @template TF The type of the value returned by the sixth parser.
488
+ * @template TStateA The type of the state used by the first parser.
489
+ * @template TStateB The type of the state used by the second parser.
490
+ * @template TStateC The type of the state used by the third parser.
491
+ * @template TStateD The type of the state used by the fourth parser.
492
+ * @template TStateE The type of the state used by the fifth parser.
493
+ * @template TStateF The type of the state used by the sixth parser.
494
+ * @param a The first {@link Parser} to try.
495
+ * @param b The second {@link Parser} to try.
496
+ * @param c The third {@link Parser} to try.
497
+ * @param d The fourth {@link Parser} to try.
498
+ * @param e The fifth {@link Parser} to try.
499
+ * @param f The sixth {@link Parser} to try.
500
+ * @return A {@link Parser} that tries to parse using the provided parsers
501
+ * in order, returning the result of the first successful parser.
502
+ */
503
+ declare function or<TA, TB, TC, TD, TE, TF, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>): Parser<TA | TB | TC | TD | TE | TF, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>]>;
504
+ /**
505
+ * Creates a parser that combines seven mutually exclusive parsers into one.
506
+ * The resulting parser will try each of the provided parsers in order,
507
+ * and return the result of the first successful parser.
508
+ * @template TA The type of the value returned by the first parser.
509
+ * @template TB The type of the value returned by the second parser.
510
+ * @template TC The type of the value returned by the third parser.
511
+ * @template TD The type of the value returned by the fourth parser.
512
+ * @template TE The type of the value returned by the fifth parser.
513
+ * @template TF The type of the value returned by the sixth parser.
514
+ * @template TG The type of the value returned by the seventh parser.
515
+ * @template TStateA The type of the state used by the first parser.
516
+ * @template TStateB The type of the state used by the second parser.
517
+ * @template TStateC The type of the state used by the third parser.
518
+ * @template TStateD The type of the state used by the fourth parser.
519
+ * @template TStateE The type of the state used by the fifth parser.
520
+ * @template TStateF The type of the state used by the sixth parser.
521
+ * @template TStateG The type of the state used by the seventh parser.
522
+ * @param a The first {@link Parser} to try.
523
+ * @param b The second {@link Parser} to try.
524
+ * @param c The third {@link Parser} to try.
525
+ * @param d The fourth {@link Parser} to try.
526
+ * @param e The fifth {@link Parser} to try.
527
+ * @param f The sixth {@link Parser} to try.
528
+ * @param g The seventh {@link Parser} to try.
529
+ * @return A {@link Parser} that tries to parse using the provided parsers
530
+ * in order, returning the result of the first successful parser.
531
+ */
532
+ declare function or<TA, TB, TC, TD, TE, TF, TG, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF, TStateG>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>, g: Parser<TG, TStateG>): Parser<TA | TB | TC | TD | TE | TF | TG, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>] | [6, ParserResult<TStateG>]>;
533
+ /**
534
+ * Creates a parser that combines eight mutually exclusive parsers into one.
535
+ * The resulting parser will try each of the provided parsers in order,
536
+ * and return the result of the first successful parser.
537
+ * @template TA The type of the value returned by the first parser.
538
+ * @template TB The type of the value returned by the second parser.
539
+ * @template TC The type of the value returned by the third parser.
540
+ * @template TD The type of the value returned by the fourth parser.
541
+ * @template TE The type of the value returned by the fifth parser.
542
+ * @template TF The type of the value returned by the sixth parser.
543
+ * @template TG The type of the value returned by the seventh parser.
544
+ * @template TH The type of the value returned by the eighth parser.
545
+ * @template TStateA The type of the state used by the first parser.
546
+ * @template TStateB The type of the state used by the second parser.
547
+ * @template TStateC The type of the state used by the third parser.
548
+ * @template TStateD The type of the state used by the fourth parser.
549
+ * @template TStateE The type of the state used by the fifth parser.
550
+ * @template TStateF The type of the state used by the sixth parser.
551
+ * @template TStateG The type of the state used by the seventh parser.
552
+ * @template TStateH The type of the state used by the eighth parser.
553
+ * @param a The first {@link Parser} to try.
554
+ * @param b The second {@link Parser} to try.
555
+ * @param c The third {@link Parser} to try.
556
+ * @param d The fourth {@link Parser} to try.
557
+ * @param e The fifth {@link Parser} to try.
558
+ * @param f The sixth {@link Parser} to try.
559
+ * @param g The seventh {@link Parser} to try.
560
+ * @param h The eighth {@link Parser} to try.
561
+ * @return A {@link Parser} that tries to parse using the provided parsers
562
+ * in order, returning the result of the first successful parser.
563
+ */
564
+ declare function or<TA, TB, TC, TD, TE, TF, TG, TH, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF, TStateG, TStateH>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>, g: Parser<TG, TStateG>, h: Parser<TH, TStateH>): Parser<TA | TB | TC | TD | TE | TF | TG | TH, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>] | [6, ParserResult<TStateG>] | [7, ParserResult<TStateH>]>;
565
+ /**
566
+ * Creates a parser that combines nine mutually exclusive parsers into one.
567
+ * The resulting parser will try each of the provided parsers in order,
568
+ * and return the result of the first successful parser.
569
+ * @template TA The type of the value returned by the first parser.
570
+ * @template TB The type of the value returned by the second parser.
571
+ * @template TC The type of the value returned by the third parser.
572
+ * @template TD The type of the value returned by the fourth parser.
573
+ * @template TE The type of the value returned by the fifth parser.
574
+ * @template TF The type of the value returned by the sixth parser.
575
+ * @template TG The type of the value returned by the seventh parser.
576
+ * @template TH The type of the value returned by the eighth parser.
577
+ * @template TI The type of the value returned by the ninth parser.
578
+ * @template TStateA The type of the state used by the first parser.
579
+ * @template TStateB The type of the state used by the second parser.
580
+ * @template TStateC The type of the state used by the third parser.
581
+ * @template TStateD The type of the state used by the fourth parser.
582
+ * @template TStateE The type of the state used by the fifth parser.
583
+ * @template TStateF The type of the state used by the sixth parser.
584
+ * @template TStateG The type of the state used by the seventh parser.
585
+ * @template TStateH The type of the state used by the eighth parser.
586
+ * @template TStateI The type of the state used by the ninth parser.
587
+ * @param a The first {@link Parser} to try.
588
+ * @param b The second {@link Parser} to try.
589
+ * @param c The third {@link Parser} to try.
590
+ * @param d The fourth {@link Parser} to try.
591
+ * @param e The fifth {@link Parser} to try.
592
+ * @param f The sixth {@link Parser} to try.
593
+ * @param g The seventh {@link Parser} to try.
594
+ * @param h The eighth {@link Parser} to try.
595
+ * @param i The ninth {@link Parser} to try.
596
+ * @return A {@link Parser} that tries to parse using the provided parsers
597
+ * in order, returning the result of the first successful parser.
598
+ */
599
+ declare function or<TA, TB, TC, TD, TE, TF, TG, TH, TI, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF, TStateG, TStateH, TStateI>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>, g: Parser<TG, TStateG>, h: Parser<TH, TStateH>, i: Parser<TI, TStateI>): Parser<TA | TB | TC | TD | TE | TF | TG | TH | TI, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>] | [6, ParserResult<TStateG>] | [7, ParserResult<TStateH>] | [8, ParserResult<TStateI>]>;
600
+ /**
601
+ * Creates a parser that combines ten mutually exclusive parsers into one.
602
+ * The resulting parser will try each of the provided parsers in order,
603
+ * and return the result of the first successful parser.
604
+ * @template TA The type of the value returned by the first parser.
605
+ * @template TB The type of the value returned by the second parser.
606
+ * @template TC The type of the value returned by the third parser.
607
+ * @template TD The type of the value returned by the fourth parser.
608
+ * @template TE The type of the value returned by the fifth parser.
609
+ * @template TF The type of the value returned by the sixth parser.
610
+ * @template TG The type of the value returned by the seventh parser.
611
+ * @template TH The type of the value returned by the eighth parser.
612
+ * @template TI The type of the value returned by the ninth parser.
613
+ * @template TJ The type of the value returned by the tenth parser.
614
+ * @template TStateA The type of the state used by the first parser.
615
+ * @template TStateB The type of the state used by the second parser.
616
+ * @template TStateC The type of the state used by the third parser.
617
+ * @template TStateD The type of the state used by the fourth parser.
618
+ * @template TStateE The type of the state used by the fifth parser.
619
+ * @template TStateF The type of the state used by the sixth parser.
620
+ * @template TStateG The type of the state used by the seventh parser.
621
+ * @template TStateH The type of the state used by the eighth parser.
622
+ * @template TStateI The type of the state used by the ninth parser.
623
+ * @template TStateJ The type of the state used by the tenth parser.
624
+ * @param a The first {@link Parser} to try.
625
+ * @param b The second {@link Parser} to try.
626
+ * @param c The third {@link Parser} to try.
627
+ * @param d The fourth {@link Parser} to try.
628
+ * @param e The fifth {@link Parser} to try.
629
+ * @param f The sixth {@link Parser} to try.
630
+ * @param g The seventh {@link Parser} to try.
631
+ * @param h The eighth {@link Parser} to try.
632
+ * @param i The ninth {@link Parser} to try.
633
+ * @param j The tenth {@link Parser} to try.
634
+ * @return A {@link Parser} that tries to parse using the provided parsers
635
+ * in order, returning the result of the first successful parser.
636
+ */
637
+ declare function or<TA, TB, TC, TD, TE, TF, TG, TH, TI, TJ, TStateA, TStateB, TStateC, TStateD, TStateE, TStateF, TStateG, TStateH, TStateI, TStateJ>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>, f: Parser<TF, TStateF>, g: Parser<TG, TStateG>, h: Parser<TH, TStateH>, i: Parser<TI, TStateI>, j: Parser<TJ, TStateJ>): Parser<TA | TB | TC | TD | TE | TF | TG | TH | TI | TJ, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>] | [5, ParserResult<TStateF>] | [6, ParserResult<TStateG>] | [7, ParserResult<TStateH>] | [8, ParserResult<TStateI>] | [9, ParserResult<TStateJ>]>;
437
638
  /**
438
639
  * Merges multiple {@link object} parsers into a single {@link object} parser.
439
640
  * It is useful for combining multiple {@link object} parsers so that
@@ -712,4 +913,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
712
913
  */
713
914
  declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
714
915
  //#endregion
715
- 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 };
916
+ 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.
@@ -1227,4 +1384,4 @@ function getDocPage(parser, args = []) {
1227
1384
  }
1228
1385
 
1229
1386
  //#endregion
1230
- export { argument, command, concat, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
1387
+ export { argument, command, concat, constant, flag, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0-dev.35+3445f3b8",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",