@optique/core 1.2.0-dev.2180 → 1.2.0-dev.2187

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.d.ts CHANGED
@@ -6,10 +6,10 @@ import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, Doc
6
6
  import { ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, DeferredMap, DomainOptions, EmailOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FirstOfOptions, FloatOptions, HostnameOptions, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, KeyValueOptions, LocaleOptions, MacAddressOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, SocketAddressOptions, SocketAddressValue, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, checkBooleanOption, checkEnumOption, choice, cidr, color, domain, email, fileSize, firstOf, float, hostname, integer, ip, ipv4, ipv6, isValueParser, json, keyValue, locale, macAddress, port, portRange, semVer, socketAddress, string, url, uuid } from "./valueparser.js";
7
7
  import { CombineModes, DocState, ExecutionContext, ExecutionPhase, InferMode, InferValue, Mode, ModeIterable, ModeValue, ParseFrame, Parser, ParserContext, ParserResult, Result, Suggestion, createParserContext, getDocPage, getDocPageAsync, getDocPageSync, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync } from "./internal/parser.js";
8
8
  import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.js";
9
+ import { FluentParser, MultipleErrorOptions, MultipleOptions, ParserModifiers, WithDefaultError, WithDefaultOptions, fluent, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
9
10
  import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, SeqOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, seq, tuple } from "./constructs.js";
10
11
  import { ParserValuePlaceholder, SourceContext, SourceContextRequest } from "./context.js";
11
12
  import { AnyDependencySource, CombineMode, CombinedDependencyMode, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, dependency, deriveFrom, deriveFromAsync, deriveFromSync, isDependencySource, isDerivedValueParser } from "./internal/dependency.js";
12
13
  import { CommandSubConfig, ContextOptionsParam, ExtractRequiredOptions, OptionSubConfig, RunOptions, RunParserError, RunWithOptions, SubstituteParserValue, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync } from "./facade.js";
13
- import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
14
14
  import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, fail, flag, negatableFlag, option, passThrough } from "./primitives.js";
15
- export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredMap, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExecutionContext, ExecutionPhase, ExtractRequiredOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FirstOfOptions, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, KeyValueOptions, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, Result, RunOptions, RunParserError, RunWithOptions, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, SeqOptions, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, SourceContextRequest, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, firstOf, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, keyValue, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, seq, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
15
+ export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredMap, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExecutionContext, ExecutionPhase, ExtractRequiredOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FirstOfOptions, FlagErrorOptions, FlagOptions, FloatOptions, FluentParser, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, KeyValueOptions, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserModifiers, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, Result, RunOptions, RunParserError, RunWithOptions, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, SeqOptions, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, SourceContextRequest, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, firstOf, fish, flag, float, fluent, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, keyValue, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, seq, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
package/dist/index.js CHANGED
@@ -5,11 +5,11 @@ import { cloneDocEntry, deduplicateDocEntries, deduplicateDocFragments, formatDo
5
5
  import { dependency, deriveFrom, deriveFromAsync, deriveFromSync, isDependencySource, isDerivedValueParser } from "./internal/dependency.js";
6
6
  import { createParserContext, getDocPage, getDocPageAsync, getDocPageSync, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync } from "./internal/parser.js";
7
7
  import { bash, fish, nu, pwsh, zsh } from "./completion.js";
8
+ import { WithDefaultError, fluent, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
8
9
  import { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, seq, tuple } from "./constructs.js";
9
- import { WithDefaultError, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
10
10
  import { ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
11
11
  import { checkBooleanOption, checkEnumOption, choice, cidr, color, domain, email, fileSize, firstOf, float, hostname, integer, ip, ipv4, ipv6, isValueParser, json, keyValue, locale, macAddress, port, portRange, semVer, socketAddress, string, url, uuid } from "./valueparser.js";
12
12
  import { argument, command, constant, fail, flag, negatableFlag, option, passThrough } from "./primitives.js";
13
13
  import { RunParserError, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync } from "./facade.js";
14
14
 
15
- export { DuplicateOptionError, RunParserError, WithDefaultError, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, firstOf, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, keyValue, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, seq, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
15
+ export { DuplicateOptionError, RunParserError, WithDefaultError, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, firstOf, fish, flag, float, fluent, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, keyValue, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, seq, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
@@ -422,7 +422,7 @@ function optional(parser) {
422
422
  }
423
423
  require_internal_parser.defineInheritedAnnotationParser(optionalParser);
424
424
  require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
425
- return optionalParser;
425
+ return fluent(optionalParser);
426
426
  }
427
427
  /**
428
428
  * Error type for structured error messages in {@link withDefault} default value callbacks.
@@ -656,7 +656,7 @@ function withDefault(parser, defaultValue, options) {
656
656
  }
657
657
  require_internal_parser.defineInheritedAnnotationParser(withDefaultParser);
658
658
  require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
659
- return withDefaultParser;
659
+ return fluent(withDefaultParser);
660
660
  }
661
661
  /**
662
662
  * Creates a parser that transforms the result value of another parser using
@@ -843,7 +843,7 @@ function map(parser, transform) {
843
843
  }
844
844
  if (composed != null) mappedParser.dependencyMetadata = composed;
845
845
  }
846
- return mappedParser;
846
+ return fluent(mappedParser);
847
847
  }
848
848
  /**
849
849
  * Creates a parser that allows multiple occurrences of a given parser.
@@ -1467,7 +1467,7 @@ function multiple(parser, options = {}) {
1467
1467
  enumerable: false
1468
1468
  });
1469
1469
  }
1470
- return resultParser;
1470
+ return fluent(resultParser);
1471
1471
  }
1472
1472
  /**
1473
1473
  * Creates a parser that requires the wrapped parser to consume at least one
@@ -1585,11 +1585,72 @@ function nonEmpty(parser) {
1585
1585
  configurable: true,
1586
1586
  enumerable: false
1587
1587
  });
1588
- return nonEmptyParser;
1588
+ return fluent(nonEmptyParser);
1589
+ }
1590
+ const fluentParserMarker = Symbol.for("@optique/core/fluent");
1591
+ /**
1592
+ * Decorates a parser with fluent modifier methods.
1593
+ *
1594
+ * The parser object is returned unchanged when it already has fluent methods.
1595
+ * Otherwise, the methods are defined as non-enumerable properties so object
1596
+ * spread and structural parser cloning continue to copy only parser data.
1597
+ *
1598
+ * @param parser The parser to decorate.
1599
+ * @returns The same parser object with fluent modifier methods.
1600
+ * @throws {TypeError} If the parser object is frozen and cannot be decorated.
1601
+ * @since 1.2.0
1602
+ */
1603
+ function fluent(parser) {
1604
+ const fluentParser = parser;
1605
+ if (fluentParserMarker in fluentParser) return fluentParser;
1606
+ Object.defineProperties(fluentParser, {
1607
+ [fluentParserMarker]: {
1608
+ value: true,
1609
+ configurable: true,
1610
+ enumerable: false
1611
+ },
1612
+ map: {
1613
+ value(transform) {
1614
+ return map(parser, transform);
1615
+ },
1616
+ configurable: true,
1617
+ enumerable: false
1618
+ },
1619
+ optional: {
1620
+ value() {
1621
+ return optional(parser);
1622
+ },
1623
+ configurable: true,
1624
+ enumerable: false
1625
+ },
1626
+ withDefault: {
1627
+ value(defaultValue, options) {
1628
+ return withDefault(parser, defaultValue, options);
1629
+ },
1630
+ configurable: true,
1631
+ enumerable: false
1632
+ },
1633
+ multiple: {
1634
+ value(options) {
1635
+ return multiple(parser, options);
1636
+ },
1637
+ configurable: true,
1638
+ enumerable: false
1639
+ },
1640
+ nonEmpty: {
1641
+ value() {
1642
+ return nonEmpty(parser);
1643
+ },
1644
+ configurable: true,
1645
+ enumerable: false
1646
+ }
1647
+ });
1648
+ return fluentParser;
1589
1649
  }
1590
1650
 
1591
1651
  //#endregion
1592
1652
  exports.WithDefaultError = WithDefaultError;
1653
+ exports.fluent = fluent;
1593
1654
  exports.map = map;
1594
1655
  exports.multiple = multiple;
1595
1656
  exports.nonEmpty = nonEmpty;
@@ -15,7 +15,7 @@ import { Mode, Parser } from "./internal/parser.cjs";
15
15
  * @returns A {@link Parser} that produces either the result of the wrapped parser
16
16
  * or `undefined` if the wrapped parser fails to match.
17
17
  */
18
- declare function optional<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>): Parser<M, TValue | undefined, [TState] | undefined>;
18
+ declare function optional<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>): FluentParser<M, TValue | undefined, [TState] | undefined>;
19
19
  /**
20
20
  * Options for the {@link withDefault} parser.
21
21
  */
@@ -83,7 +83,7 @@ declare class WithDefaultError extends Error {
83
83
  * or the default value if the wrapped parser fails to match
84
84
  * (union type {@link TValue} | {@link TDefault}).
85
85
  */
86
- declare function withDefault<M extends Mode, TValue, TState, const TDefault = TValue>(parser: Parser<M, TValue, TState>, defaultValue: TDefault | (() => TDefault)): Parser<M, TValue | TDefault, [TState] | undefined>;
86
+ declare function withDefault<M extends Mode, TValue, TState, const TDefault = TValue>(parser: Parser<M, TValue, TState>, defaultValue: TDefault | (() => TDefault)): FluentParser<M, TValue | TDefault, [TState] | undefined>;
87
87
  /**
88
88
  * Creates a parser that makes another parser use a default value when it fails
89
89
  * to match or consume input. This is similar to {@link optional}, but instead
@@ -103,7 +103,7 @@ declare function withDefault<M extends Mode, TValue, TState, const TDefault = TV
103
103
  * (union type {@link TValue} | {@link TDefault}).
104
104
  * @since 0.5.0
105
105
  */
106
- declare function withDefault<M extends Mode, TValue, TState, const TDefault = TValue>(parser: Parser<M, TValue, TState>, defaultValue: TDefault | (() => TDefault), options?: WithDefaultOptions): Parser<M, TValue | TDefault, [TState] | undefined>;
106
+ declare function withDefault<M extends Mode, TValue, TState, const TDefault = TValue>(parser: Parser<M, TValue, TState>, defaultValue: TDefault | (() => TDefault), options?: WithDefaultOptions): FluentParser<M, TValue | TDefault, [TState] | undefined>;
107
107
  /**
108
108
  * Creates a parser that transforms the result value of another parser using
109
109
  * a mapping function. This enables value transformation while preserving
@@ -179,7 +179,7 @@ declare function withDefault<M extends Mode, TValue, TState, const TDefault = TV
179
179
  * const prefixedParser = map(option("-n", integer()), n => `value: ${n}`);
180
180
  * ```
181
181
  */
182
- declare function map<M extends Mode, T, U, TState>(parser: Parser<M, T, TState>, transform: (value: T) => U): Parser<M, U, TState>;
182
+ declare function map<M extends Mode, T, U, TState>(parser: Parser<M, T, TState>, transform: (value: T) => U): FluentParser<M, U, TState>;
183
183
  /**
184
184
  * Options for the {@link multiple} parser.
185
185
  */
@@ -233,7 +233,7 @@ interface MultipleErrorOptions {
233
233
  * of type {@link TValue} and an array of states
234
234
  * of type {@link TState}.
235
235
  */
236
- declare function multiple<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, options?: MultipleOptions): Parser<M, readonly TValue[], readonly TState[]>;
236
+ declare function multiple<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, options?: MultipleOptions): FluentParser<M, readonly TValue[], readonly TState[]>;
237
237
  /**
238
238
  * Creates a parser that requires the wrapped parser to consume at least one
239
239
  * input token to succeed. If the wrapped parser succeeds without consuming
@@ -271,6 +271,76 @@ declare function multiple<M extends Mode, TValue, TState>(parser: Parser<M, TVal
271
271
  *
272
272
  * @since 0.10.0
273
273
  */
274
- declare function nonEmpty<M extends Mode, T, TState>(parser: Parser<M, T, TState>): Parser<M, T, TState>;
274
+ declare function nonEmpty<M extends Mode, T, TState>(parser: Parser<M, T, TState>): FluentParser<M, T, TState>;
275
+ /**
276
+ * Method-style parser modifiers.
277
+ *
278
+ * These methods are a convenience layer over the standalone modifier
279
+ * functions. They are intentionally separate from {@link Parser} so custom
280
+ * parser authors can keep implementing the smaller base parser contract.
281
+ *
282
+ * @template M The execution mode of the parser.
283
+ * @template TValue The parser result value.
284
+ * @template TState The parser state.
285
+ * @since 1.2.0
286
+ */
287
+ interface ParserModifiers<M extends Mode = "sync", TValue = unknown, TState = unknown> {
288
+ /**
289
+ * Transforms the parsed value.
290
+ *
291
+ * @param transform Function that maps the parser value.
292
+ * @returns A parser that produces the mapped value.
293
+ */
294
+ map<U>(transform: (value: TValue) => U): FluentParser<M, U, TState>;
295
+ /**
296
+ * Makes this parser optional.
297
+ *
298
+ * @returns A parser that produces this parser's value or `undefined`.
299
+ */
300
+ optional(): FluentParser<M, TValue | undefined, [TState] | undefined>;
301
+ /**
302
+ * Supplies a default value when this parser does not match.
303
+ *
304
+ * @param defaultValue Value or factory used as the default.
305
+ * @param options Optional default display configuration.
306
+ * @returns A parser that produces this parser's value or the default value.
307
+ */
308
+ withDefault<const TDefault = TValue>(defaultValue: TDefault | (() => TDefault), options?: WithDefaultOptions): FluentParser<M, TValue | TDefault, [TState] | undefined>;
309
+ /**
310
+ * Allows this parser to match multiple times.
311
+ *
312
+ * @param options Optional occurrence constraints.
313
+ * @returns A parser that produces all matched values.
314
+ */
315
+ multiple(options?: MultipleOptions): FluentParser<M, readonly TValue[], readonly TState[]>;
316
+ /**
317
+ * Requires this parser to consume at least one token.
318
+ *
319
+ * @returns A parser with the same value and state types.
320
+ */
321
+ nonEmpty(): FluentParser<M, TValue, TState>;
322
+ }
323
+ /**
324
+ * A parser decorated with method-style modifier helpers.
325
+ *
326
+ * @template M The execution mode of the parser.
327
+ * @template TValue The parser result value.
328
+ * @template TState The parser state.
329
+ * @since 1.2.0
330
+ */
331
+ type FluentParser<M extends Mode = "sync", TValue = unknown, TState = unknown> = Parser<M, TValue, TState> & ParserModifiers<M, TValue, TState>;
332
+ /**
333
+ * Decorates a parser with fluent modifier methods.
334
+ *
335
+ * The parser object is returned unchanged when it already has fluent methods.
336
+ * Otherwise, the methods are defined as non-enumerable properties so object
337
+ * spread and structural parser cloning continue to copy only parser data.
338
+ *
339
+ * @param parser The parser to decorate.
340
+ * @returns The same parser object with fluent modifier methods.
341
+ * @throws {TypeError} If the parser object is frozen and cannot be decorated.
342
+ * @since 1.2.0
343
+ */
344
+ declare function fluent<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>): FluentParser<M, TValue, TState>;
275
345
  //#endregion
276
- export { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault };
346
+ export { FluentParser, MultipleErrorOptions, MultipleOptions, ParserModifiers, WithDefaultError, WithDefaultOptions, fluent, map, multiple, nonEmpty, optional, withDefault };
@@ -15,7 +15,7 @@ import { Mode, Parser } from "./internal/parser.js";
15
15
  * @returns A {@link Parser} that produces either the result of the wrapped parser
16
16
  * or `undefined` if the wrapped parser fails to match.
17
17
  */
18
- declare function optional<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>): Parser<M, TValue | undefined, [TState] | undefined>;
18
+ declare function optional<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>): FluentParser<M, TValue | undefined, [TState] | undefined>;
19
19
  /**
20
20
  * Options for the {@link withDefault} parser.
21
21
  */
@@ -83,7 +83,7 @@ declare class WithDefaultError extends Error {
83
83
  * or the default value if the wrapped parser fails to match
84
84
  * (union type {@link TValue} | {@link TDefault}).
85
85
  */
86
- declare function withDefault<M extends Mode, TValue, TState, const TDefault = TValue>(parser: Parser<M, TValue, TState>, defaultValue: TDefault | (() => TDefault)): Parser<M, TValue | TDefault, [TState] | undefined>;
86
+ declare function withDefault<M extends Mode, TValue, TState, const TDefault = TValue>(parser: Parser<M, TValue, TState>, defaultValue: TDefault | (() => TDefault)): FluentParser<M, TValue | TDefault, [TState] | undefined>;
87
87
  /**
88
88
  * Creates a parser that makes another parser use a default value when it fails
89
89
  * to match or consume input. This is similar to {@link optional}, but instead
@@ -103,7 +103,7 @@ declare function withDefault<M extends Mode, TValue, TState, const TDefault = TV
103
103
  * (union type {@link TValue} | {@link TDefault}).
104
104
  * @since 0.5.0
105
105
  */
106
- declare function withDefault<M extends Mode, TValue, TState, const TDefault = TValue>(parser: Parser<M, TValue, TState>, defaultValue: TDefault | (() => TDefault), options?: WithDefaultOptions): Parser<M, TValue | TDefault, [TState] | undefined>;
106
+ declare function withDefault<M extends Mode, TValue, TState, const TDefault = TValue>(parser: Parser<M, TValue, TState>, defaultValue: TDefault | (() => TDefault), options?: WithDefaultOptions): FluentParser<M, TValue | TDefault, [TState] | undefined>;
107
107
  /**
108
108
  * Creates a parser that transforms the result value of another parser using
109
109
  * a mapping function. This enables value transformation while preserving
@@ -179,7 +179,7 @@ declare function withDefault<M extends Mode, TValue, TState, const TDefault = TV
179
179
  * const prefixedParser = map(option("-n", integer()), n => `value: ${n}`);
180
180
  * ```
181
181
  */
182
- declare function map<M extends Mode, T, U, TState>(parser: Parser<M, T, TState>, transform: (value: T) => U): Parser<M, U, TState>;
182
+ declare function map<M extends Mode, T, U, TState>(parser: Parser<M, T, TState>, transform: (value: T) => U): FluentParser<M, U, TState>;
183
183
  /**
184
184
  * Options for the {@link multiple} parser.
185
185
  */
@@ -233,7 +233,7 @@ interface MultipleErrorOptions {
233
233
  * of type {@link TValue} and an array of states
234
234
  * of type {@link TState}.
235
235
  */
236
- declare function multiple<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, options?: MultipleOptions): Parser<M, readonly TValue[], readonly TState[]>;
236
+ declare function multiple<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, options?: MultipleOptions): FluentParser<M, readonly TValue[], readonly TState[]>;
237
237
  /**
238
238
  * Creates a parser that requires the wrapped parser to consume at least one
239
239
  * input token to succeed. If the wrapped parser succeeds without consuming
@@ -271,6 +271,76 @@ declare function multiple<M extends Mode, TValue, TState>(parser: Parser<M, TVal
271
271
  *
272
272
  * @since 0.10.0
273
273
  */
274
- declare function nonEmpty<M extends Mode, T, TState>(parser: Parser<M, T, TState>): Parser<M, T, TState>;
274
+ declare function nonEmpty<M extends Mode, T, TState>(parser: Parser<M, T, TState>): FluentParser<M, T, TState>;
275
+ /**
276
+ * Method-style parser modifiers.
277
+ *
278
+ * These methods are a convenience layer over the standalone modifier
279
+ * functions. They are intentionally separate from {@link Parser} so custom
280
+ * parser authors can keep implementing the smaller base parser contract.
281
+ *
282
+ * @template M The execution mode of the parser.
283
+ * @template TValue The parser result value.
284
+ * @template TState The parser state.
285
+ * @since 1.2.0
286
+ */
287
+ interface ParserModifiers<M extends Mode = "sync", TValue = unknown, TState = unknown> {
288
+ /**
289
+ * Transforms the parsed value.
290
+ *
291
+ * @param transform Function that maps the parser value.
292
+ * @returns A parser that produces the mapped value.
293
+ */
294
+ map<U>(transform: (value: TValue) => U): FluentParser<M, U, TState>;
295
+ /**
296
+ * Makes this parser optional.
297
+ *
298
+ * @returns A parser that produces this parser's value or `undefined`.
299
+ */
300
+ optional(): FluentParser<M, TValue | undefined, [TState] | undefined>;
301
+ /**
302
+ * Supplies a default value when this parser does not match.
303
+ *
304
+ * @param defaultValue Value or factory used as the default.
305
+ * @param options Optional default display configuration.
306
+ * @returns A parser that produces this parser's value or the default value.
307
+ */
308
+ withDefault<const TDefault = TValue>(defaultValue: TDefault | (() => TDefault), options?: WithDefaultOptions): FluentParser<M, TValue | TDefault, [TState] | undefined>;
309
+ /**
310
+ * Allows this parser to match multiple times.
311
+ *
312
+ * @param options Optional occurrence constraints.
313
+ * @returns A parser that produces all matched values.
314
+ */
315
+ multiple(options?: MultipleOptions): FluentParser<M, readonly TValue[], readonly TState[]>;
316
+ /**
317
+ * Requires this parser to consume at least one token.
318
+ *
319
+ * @returns A parser with the same value and state types.
320
+ */
321
+ nonEmpty(): FluentParser<M, TValue, TState>;
322
+ }
323
+ /**
324
+ * A parser decorated with method-style modifier helpers.
325
+ *
326
+ * @template M The execution mode of the parser.
327
+ * @template TValue The parser result value.
328
+ * @template TState The parser state.
329
+ * @since 1.2.0
330
+ */
331
+ type FluentParser<M extends Mode = "sync", TValue = unknown, TState = unknown> = Parser<M, TValue, TState> & ParserModifiers<M, TValue, TState>;
332
+ /**
333
+ * Decorates a parser with fluent modifier methods.
334
+ *
335
+ * The parser object is returned unchanged when it already has fluent methods.
336
+ * Otherwise, the methods are defined as non-enumerable properties so object
337
+ * spread and structural parser cloning continue to copy only parser data.
338
+ *
339
+ * @param parser The parser to decorate.
340
+ * @returns The same parser object with fluent modifier methods.
341
+ * @throws {TypeError} If the parser object is frozen and cannot be decorated.
342
+ * @since 1.2.0
343
+ */
344
+ declare function fluent<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>): FluentParser<M, TValue, TState>;
275
345
  //#endregion
276
- export { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault };
346
+ export { FluentParser, MultipleErrorOptions, MultipleOptions, ParserModifiers, WithDefaultError, WithDefaultOptions, fluent, map, multiple, nonEmpty, optional, withDefault };
package/dist/modifiers.js CHANGED
@@ -422,7 +422,7 @@ function optional(parser) {
422
422
  }
423
423
  defineInheritedAnnotationParser(optionalParser);
424
424
  defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
425
- return optionalParser;
425
+ return fluent(optionalParser);
426
426
  }
427
427
  /**
428
428
  * Error type for structured error messages in {@link withDefault} default value callbacks.
@@ -656,7 +656,7 @@ function withDefault(parser, defaultValue, options) {
656
656
  }
657
657
  defineInheritedAnnotationParser(withDefaultParser);
658
658
  defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
659
- return withDefaultParser;
659
+ return fluent(withDefaultParser);
660
660
  }
661
661
  /**
662
662
  * Creates a parser that transforms the result value of another parser using
@@ -843,7 +843,7 @@ function map(parser, transform) {
843
843
  }
844
844
  if (composed != null) mappedParser.dependencyMetadata = composed;
845
845
  }
846
- return mappedParser;
846
+ return fluent(mappedParser);
847
847
  }
848
848
  /**
849
849
  * Creates a parser that allows multiple occurrences of a given parser.
@@ -1467,7 +1467,7 @@ function multiple(parser, options = {}) {
1467
1467
  enumerable: false
1468
1468
  });
1469
1469
  }
1470
- return resultParser;
1470
+ return fluent(resultParser);
1471
1471
  }
1472
1472
  /**
1473
1473
  * Creates a parser that requires the wrapped parser to consume at least one
@@ -1585,8 +1585,68 @@ function nonEmpty(parser) {
1585
1585
  configurable: true,
1586
1586
  enumerable: false
1587
1587
  });
1588
- return nonEmptyParser;
1588
+ return fluent(nonEmptyParser);
1589
+ }
1590
+ const fluentParserMarker = Symbol.for("@optique/core/fluent");
1591
+ /**
1592
+ * Decorates a parser with fluent modifier methods.
1593
+ *
1594
+ * The parser object is returned unchanged when it already has fluent methods.
1595
+ * Otherwise, the methods are defined as non-enumerable properties so object
1596
+ * spread and structural parser cloning continue to copy only parser data.
1597
+ *
1598
+ * @param parser The parser to decorate.
1599
+ * @returns The same parser object with fluent modifier methods.
1600
+ * @throws {TypeError} If the parser object is frozen and cannot be decorated.
1601
+ * @since 1.2.0
1602
+ */
1603
+ function fluent(parser) {
1604
+ const fluentParser = parser;
1605
+ if (fluentParserMarker in fluentParser) return fluentParser;
1606
+ Object.defineProperties(fluentParser, {
1607
+ [fluentParserMarker]: {
1608
+ value: true,
1609
+ configurable: true,
1610
+ enumerable: false
1611
+ },
1612
+ map: {
1613
+ value(transform) {
1614
+ return map(parser, transform);
1615
+ },
1616
+ configurable: true,
1617
+ enumerable: false
1618
+ },
1619
+ optional: {
1620
+ value() {
1621
+ return optional(parser);
1622
+ },
1623
+ configurable: true,
1624
+ enumerable: false
1625
+ },
1626
+ withDefault: {
1627
+ value(defaultValue, options) {
1628
+ return withDefault(parser, defaultValue, options);
1629
+ },
1630
+ configurable: true,
1631
+ enumerable: false
1632
+ },
1633
+ multiple: {
1634
+ value(options) {
1635
+ return multiple(parser, options);
1636
+ },
1637
+ configurable: true,
1638
+ enumerable: false
1639
+ },
1640
+ nonEmpty: {
1641
+ value() {
1642
+ return nonEmpty(parser);
1643
+ },
1644
+ configurable: true,
1645
+ enumerable: false
1646
+ }
1647
+ });
1648
+ return fluentParser;
1589
1649
  }
1590
1650
 
1591
1651
  //#endregion
1592
- export { WithDefaultError, map, multiple, nonEmpty, optional, withDefault };
1652
+ export { WithDefaultError, fluent, map, multiple, nonEmpty, optional, withDefault };
@@ -9,9 +9,10 @@ const require_annotation_state = require('./annotation-state.cjs');
9
9
  const require_command_alias = require('./internal/command-alias.cjs');
10
10
  const require_execution_context = require('./execution-context.cjs');
11
11
  const require_phase2_seed = require('./phase2-seed.cjs');
12
+ const require_dependency_metadata = require('./dependency-metadata.cjs');
13
+ const require_modifiers = require('./modifiers.cjs');
12
14
  const require_suggestion = require('./suggestion.cjs');
13
15
  const require_usage_internals = require('./usage-internals.cjs');
14
- const require_dependency_metadata = require('./dependency-metadata.cjs');
15
16
  const require_valueparser = require('./valueparser.cjs');
16
17
 
17
18
  //#region src/primitives.ts
@@ -150,7 +151,7 @@ function constant(value) {
150
151
  enumerable: false,
151
152
  writable: false
152
153
  });
153
- return result;
154
+ return require_modifiers.fluent(result);
154
155
  }
155
156
  /**
156
157
  * Creates a parser that always fails without consuming any input.
@@ -172,7 +173,7 @@ function constant(value) {
172
173
  * @since 1.0.0
173
174
  */
174
175
  function fail() {
175
- return {
176
+ return require_modifiers.fluent({
176
177
  $valueType: [],
177
178
  $stateType: [],
178
179
  mode: "sync",
@@ -203,7 +204,7 @@ function fail() {
203
204
  getDocFragments(_state, _defaultValue) {
204
205
  return { fragments: [] };
205
206
  }
206
- };
207
+ });
207
208
  }
208
209
  /**
209
210
  * Internal helper to get suggestions from a value parser, using dependency values
@@ -741,7 +742,7 @@ function option(...args) {
741
742
  configurable: true,
742
743
  enumerable: false
743
744
  });
744
- return result;
745
+ return require_modifiers.fluent(result);
745
746
  }
746
747
  /**
747
748
  * Creates a parser for command-line flags that must be explicitly provided.
@@ -944,7 +945,7 @@ function flag(...args) {
944
945
  enumerable: false,
945
946
  writable: false
946
947
  });
947
- return result;
948
+ return require_modifiers.fluent(result);
948
949
  }
949
950
  function normalizeNegatableFlagNameList(names) {
950
951
  return typeof names === "string" ? [names] : names;
@@ -1162,7 +1163,7 @@ function negatableFlag(names, options = {}) {
1162
1163
  enumerable: false,
1163
1164
  writable: false
1164
1165
  });
1165
- return result;
1166
+ return require_modifiers.fluent(result);
1166
1167
  }
1167
1168
  /**
1168
1169
  * Creates a parser that expects a single argument value.
@@ -1371,7 +1372,7 @@ function argument(valueParser, options = {}) {
1371
1372
  configurable: true,
1372
1373
  enumerable: false
1373
1374
  });
1374
- return result;
1375
+ return require_modifiers.fluent(result);
1375
1376
  }
1376
1377
  function normalizeCommandState(state) {
1377
1378
  return require_annotation_state.normalizeInjectedAnnotationState(state);
@@ -1700,7 +1701,7 @@ function command(name, parser, options = {}) {
1700
1701
  configurable: true,
1701
1702
  enumerable: false
1702
1703
  });
1703
- return result;
1704
+ return require_modifiers.fluent(result);
1704
1705
  }
1705
1706
  /**
1706
1707
  * Creates a parser that collects unrecognized options and passes them through.
@@ -1752,7 +1753,7 @@ function passThrough(options = {}) {
1752
1753
  const format = options.format ?? "equalsOnly";
1753
1754
  const optionPattern = /^-[a-z0-9-]|^--[a-z0-9-]+/i;
1754
1755
  const equalsOptionPattern = /^--[a-z0-9-]+=/i;
1755
- return {
1756
+ const result = {
1756
1757
  $valueType: [],
1757
1758
  $stateType: [],
1758
1759
  mode: "sync",
@@ -1884,6 +1885,7 @@ function passThrough(options = {}) {
1884
1885
  return `passThrough(${format})`;
1885
1886
  }
1886
1887
  };
1888
+ return require_modifiers.fluent(result);
1887
1889
  }
1888
1890
 
1889
1891
  //#endregion