@optique/core 0.4.0-dev.52 → 0.4.0-dev.54

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/parser.cjs CHANGED
@@ -1492,6 +1492,81 @@ function parse(parser, args) {
1492
1492
  };
1493
1493
  }
1494
1494
  /**
1495
+ * Wraps a parser with a group label for documentation purposes.
1496
+ *
1497
+ * The `group()` function is a documentation-only wrapper that applies a label
1498
+ * to any parser for help text organization. This allows you to use clean code
1499
+ * structure with combinators like {@link merge} while maintaining well-organized
1500
+ * help text through group labeling.
1501
+ *
1502
+ * The wrapped parser has identical parsing behavior but generates documentation
1503
+ * fragments wrapped in a labeled section. This is particularly useful when
1504
+ * combining parsers using {@link merge}—you can wrap the merged result with
1505
+ * `group()` to add a section header in help output.
1506
+ *
1507
+ * @example
1508
+ * ```typescript
1509
+ * const apiOptions = merge(
1510
+ * object({ endpoint: option("--endpoint", string()) }),
1511
+ * object({ timeout: option("--timeout", integer()) })
1512
+ * );
1513
+ *
1514
+ * const groupedApiOptions = group("API Options", apiOptions);
1515
+ * // Now produces a labeled "API Options" section in help text
1516
+ * ```
1517
+ *
1518
+ * @example
1519
+ * ```typescript
1520
+ * // Can be used with any parser, not just merge()
1521
+ * const verboseGroup = group("Verbosity", object({
1522
+ * verbose: option("-v", "--verbose"),
1523
+ * quiet: option("-q", "--quiet")
1524
+ * }));
1525
+ * ```
1526
+ *
1527
+ * @template TValue The value type of the wrapped parser.
1528
+ * @template TState The state type of the wrapped parser.
1529
+ * @param label A descriptive label for this parser group, used for
1530
+ * documentation and help text organization.
1531
+ * @param parser The parser to wrap with a group label.
1532
+ * @returns A new parser that behaves identically to the input parser
1533
+ * but generates documentation within a labeled section.
1534
+ * @since 0.4.0
1535
+ */
1536
+ function group(label, parser) {
1537
+ return {
1538
+ $valueType: parser.$valueType,
1539
+ $stateType: parser.$stateType,
1540
+ priority: parser.priority,
1541
+ usage: parser.usage,
1542
+ initialState: parser.initialState,
1543
+ parse: (context) => parser.parse(context),
1544
+ complete: (state) => parser.complete(state),
1545
+ getDocFragments: (state, defaultValue) => {
1546
+ const { description, fragments } = parser.getDocFragments(state, defaultValue);
1547
+ const allEntries = [];
1548
+ const titledSections = [];
1549
+ for (const fragment of fragments) if (fragment.type === "entry") allEntries.push(fragment);
1550
+ else if (fragment.type === "section") if (fragment.title) titledSections.push(fragment);
1551
+ else allEntries.push(...fragment.entries);
1552
+ const labeledSection = {
1553
+ title: label,
1554
+ entries: allEntries
1555
+ };
1556
+ return {
1557
+ description,
1558
+ fragments: [...titledSections.map((s) => ({
1559
+ ...s,
1560
+ type: "section"
1561
+ })), {
1562
+ type: "section",
1563
+ ...labeledSection
1564
+ }]
1565
+ };
1566
+ }
1567
+ };
1568
+ }
1569
+ /**
1495
1570
  * Generates a documentation page for a parser based on its current state after
1496
1571
  * attempting to parse the provided arguments. This function is useful for
1497
1572
  * creating help documentation that reflects the current parsing context.
@@ -1576,6 +1651,7 @@ exports.concat = concat;
1576
1651
  exports.constant = constant;
1577
1652
  exports.flag = flag;
1578
1653
  exports.getDocPage = getDocPage;
1654
+ exports.group = group;
1579
1655
  exports.longestMatch = longestMatch;
1580
1656
  exports.map = map;
1581
1657
  exports.merge = merge;
package/dist/parser.d.cts CHANGED
@@ -400,7 +400,7 @@ declare function object<T extends {
400
400
  * as the input array, where each element is the result of the
401
401
  * corresponding parser.
402
402
  */
403
- declare function tuple<T extends readonly Parser<unknown, unknown>[]>(parsers: T): Parser<{ readonly [K in keyof T]: T[K]["$valueType"][number] extends (infer U) ? U : never }, { readonly [K in keyof T]: T[K]["$stateType"][number] extends (infer U2) ? U2 : never }>;
403
+ declare function tuple<const T extends readonly Parser<unknown, unknown>[]>(parsers: T): Parser<{ readonly [K in keyof T]: T[K]["$valueType"][number] extends (infer U) ? U : never }, { readonly [K in keyof T]: T[K]["$stateType"][number] extends (infer U2) ? U2 : never }>;
404
404
  /**
405
405
  * Creates a labeled parser that combines multiple parsers into a sequential
406
406
  * tuple parser with an associated label for documentation or error reporting.
@@ -413,7 +413,7 @@ declare function tuple<T extends readonly Parser<unknown, unknown>[]>(parsers: T
413
413
  * as the input array, where each element is the result of the
414
414
  * corresponding parser.
415
415
  */
416
- declare function tuple<T extends readonly Parser<unknown, unknown>[]>(label: string, parsers: T): Parser<{ readonly [K in keyof T]: T[K]["$valueType"][number] extends (infer U) ? U : never }, { readonly [K in keyof T]: T[K]["$stateType"][number] extends (infer U2) ? U2 : never }>;
416
+ declare function tuple<const T extends readonly Parser<unknown, unknown>[]>(label: string, parsers: T): Parser<{ readonly [K in keyof T]: T[K]["$valueType"][number] extends (infer U) ? U : never }, { readonly [K in keyof T]: T[K]["$stateType"][number] extends (infer U2) ? U2 : never }>;
417
417
  /**
418
418
  * Creates a parser that combines two mutually exclusive parsers into one.
419
419
  * The resulting parser will try each of the provided parsers in order,
@@ -739,7 +739,7 @@ declare function longestMatch<TA, TB, TC, TD, TE, TStateA, TStateB, TStateC, TSt
739
739
  * Helper type to check if all members of a union are object-like.
740
740
  * This allows merge() to work with parsers like withDefault() that produce union types.
741
741
  */
742
- type AllObjectLike<T> = T extends Record<string | symbol, unknown> ? T : never;
742
+ type AllObjectLike<T> = T extends readonly unknown[] ? never : T extends Record<string | symbol, unknown> ? T : never;
743
743
  /**
744
744
  * Helper type to extract object-like types from parser value types,
745
745
  * including union types where all members are objects.
@@ -758,7 +758,7 @@ type ExtractObjectTypes<P> = P extends Parser<infer V, unknown> ? [AllObjectLike
758
758
  * @return A new {@link object} parser that combines the values and states
759
759
  * of the two parsers into a single object.
760
760
  */
761
- declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>>(a: TA, b: TB): ExtractObjectTypes<TA> extends never ? never : ExtractObjectTypes<TB> extends never ? never : Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB>, Record<string | symbol, unknown>>;
761
+ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>>(a: ExtractObjectTypes<TA> extends never ? never : TA, b: ExtractObjectTypes<TB> extends never ? never : TB): Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB>, Record<string | symbol, unknown>>;
762
762
  /**
763
763
  * Merges multiple {@link object} parsers into a single {@link object} parser
764
764
  * with a label for documentation and help text organization.
@@ -775,7 +775,7 @@ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<un
775
775
  * @return A new {@link object} parser that combines the values and states
776
776
  * of the two parsers into a single object.
777
777
  */
778
- declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>>(label: string, a: TA, b: TB): ExtractObjectTypes<TA> extends never ? never : ExtractObjectTypes<TB> extends never ? never : Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB>, Record<string | symbol, unknown>>;
778
+ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>>(label: string, a: ExtractObjectTypes<TA> extends never ? never : TA, b: ExtractObjectTypes<TB> extends never ? never : TB): Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB>, Record<string | symbol, unknown>>;
779
779
  /**
780
780
  * Merges multiple {@link object} parsers into a single {@link object} parser.
781
781
  * It is useful for combining multiple {@link object} parsers so that
@@ -791,7 +791,7 @@ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<un
791
791
  * @return A new {@link object} parser that combines the values and states
792
792
  * of the two parsers into a single object.
793
793
  */
794
- declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>, TC extends Parser<unknown, unknown>>(a: TA, b: TB, c: TC): ExtractObjectTypes<TA> extends never ? never : ExtractObjectTypes<TB> extends never ? never : ExtractObjectTypes<TC> extends never ? never : Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB> & ExtractObjectTypes<TC>, Record<string | symbol, unknown>>;
794
+ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>, TC extends Parser<unknown, unknown>>(a: ExtractObjectTypes<TA> extends never ? never : TA, b: ExtractObjectTypes<TB> extends never ? never : TB, c: ExtractObjectTypes<TC> extends never ? never : TC): Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB> & ExtractObjectTypes<TC>, Record<string | symbol, unknown>>;
795
795
  /**
796
796
  * Merges multiple {@link object} parsers into a single {@link object} parser
797
797
  * with a label for documentation and help text organization.
@@ -869,7 +869,7 @@ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<un
869
869
  * @return A new {@link object} parser that combines the values and states
870
870
  * of the two parsers into a single object.
871
871
  */
872
- declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>, TC extends Parser<unknown, unknown>, TD extends Parser<unknown, unknown>, TE extends Parser<unknown, unknown>>(a: TA, b: TB, c: TC, d: TD, e: TE): ExtractObjectTypes<TA> extends never ? never : ExtractObjectTypes<TB> extends never ? never : ExtractObjectTypes<TC> extends never ? never : ExtractObjectTypes<TD> extends never ? never : ExtractObjectTypes<TE> extends never ? never : Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB> & ExtractObjectTypes<TC> & ExtractObjectTypes<TD> & ExtractObjectTypes<TE>, Record<string | symbol, unknown>>;
872
+ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>, TC extends Parser<unknown, unknown>, TD extends Parser<unknown, unknown>, TE extends Parser<unknown, unknown>>(a: ExtractObjectTypes<TA> extends never ? never : TA, b: ExtractObjectTypes<TB> extends never ? never : TB, c: ExtractObjectTypes<TC> extends never ? never : TC, d: ExtractObjectTypes<TD> extends never ? never : TD, e: ExtractObjectTypes<TE> extends never ? never : TE): Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB> & ExtractObjectTypes<TC> & ExtractObjectTypes<TD> & ExtractObjectTypes<TE>, Record<string | symbol, unknown>>;
873
873
  /**
874
874
  * Merges multiple {@link object} parsers into a single {@link object} parser
875
875
  * with a label for documentation and help text organization.
@@ -1353,6 +1353,49 @@ type Result<T> = {
1353
1353
  * failure.
1354
1354
  */
1355
1355
  declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]): Result<T>;
1356
+ /**
1357
+ * Wraps a parser with a group label for documentation purposes.
1358
+ *
1359
+ * The `group()` function is a documentation-only wrapper that applies a label
1360
+ * to any parser for help text organization. This allows you to use clean code
1361
+ * structure with combinators like {@link merge} while maintaining well-organized
1362
+ * help text through group labeling.
1363
+ *
1364
+ * The wrapped parser has identical parsing behavior but generates documentation
1365
+ * fragments wrapped in a labeled section. This is particularly useful when
1366
+ * combining parsers using {@link merge}—you can wrap the merged result with
1367
+ * `group()` to add a section header in help output.
1368
+ *
1369
+ * @example
1370
+ * ```typescript
1371
+ * const apiOptions = merge(
1372
+ * object({ endpoint: option("--endpoint", string()) }),
1373
+ * object({ timeout: option("--timeout", integer()) })
1374
+ * );
1375
+ *
1376
+ * const groupedApiOptions = group("API Options", apiOptions);
1377
+ * // Now produces a labeled "API Options" section in help text
1378
+ * ```
1379
+ *
1380
+ * @example
1381
+ * ```typescript
1382
+ * // Can be used with any parser, not just merge()
1383
+ * const verboseGroup = group("Verbosity", object({
1384
+ * verbose: option("-v", "--verbose"),
1385
+ * quiet: option("-q", "--quiet")
1386
+ * }));
1387
+ * ```
1388
+ *
1389
+ * @template TValue The value type of the wrapped parser.
1390
+ * @template TState The state type of the wrapped parser.
1391
+ * @param label A descriptive label for this parser group, used for
1392
+ * documentation and help text organization.
1393
+ * @param parser The parser to wrap with a group label.
1394
+ * @returns A new parser that behaves identically to the input parser
1395
+ * but generates documentation within a labeled section.
1396
+ * @since 0.4.0
1397
+ */
1398
+ declare function group<TValue, TState>(label: string, parser: Parser<TValue, TState>): Parser<TValue, TState>;
1356
1399
  /**
1357
1400
  * Generates a documentation page for a parser based on its current state after
1358
1401
  * attempting to parse the provided arguments. This function is useful for
@@ -1388,4 +1431,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
1388
1431
  */
1389
1432
  declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
1390
1433
  //#endregion
1391
- export { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, flag, getDocPage, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
1434
+ export { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
package/dist/parser.d.ts CHANGED
@@ -400,7 +400,7 @@ declare function object<T extends {
400
400
  * as the input array, where each element is the result of the
401
401
  * corresponding parser.
402
402
  */
403
- declare function tuple<T extends readonly Parser<unknown, unknown>[]>(parsers: T): Parser<{ readonly [K in keyof T]: T[K]["$valueType"][number] extends (infer U) ? U : never }, { readonly [K in keyof T]: T[K]["$stateType"][number] extends (infer U2) ? U2 : never }>;
403
+ declare function tuple<const T extends readonly Parser<unknown, unknown>[]>(parsers: T): Parser<{ readonly [K in keyof T]: T[K]["$valueType"][number] extends (infer U) ? U : never }, { readonly [K in keyof T]: T[K]["$stateType"][number] extends (infer U2) ? U2 : never }>;
404
404
  /**
405
405
  * Creates a labeled parser that combines multiple parsers into a sequential
406
406
  * tuple parser with an associated label for documentation or error reporting.
@@ -413,7 +413,7 @@ declare function tuple<T extends readonly Parser<unknown, unknown>[]>(parsers: T
413
413
  * as the input array, where each element is the result of the
414
414
  * corresponding parser.
415
415
  */
416
- declare function tuple<T extends readonly Parser<unknown, unknown>[]>(label: string, parsers: T): Parser<{ readonly [K in keyof T]: T[K]["$valueType"][number] extends (infer U) ? U : never }, { readonly [K in keyof T]: T[K]["$stateType"][number] extends (infer U2) ? U2 : never }>;
416
+ declare function tuple<const T extends readonly Parser<unknown, unknown>[]>(label: string, parsers: T): Parser<{ readonly [K in keyof T]: T[K]["$valueType"][number] extends (infer U) ? U : never }, { readonly [K in keyof T]: T[K]["$stateType"][number] extends (infer U2) ? U2 : never }>;
417
417
  /**
418
418
  * Creates a parser that combines two mutually exclusive parsers into one.
419
419
  * The resulting parser will try each of the provided parsers in order,
@@ -739,7 +739,7 @@ declare function longestMatch<TA, TB, TC, TD, TE, TStateA, TStateB, TStateC, TSt
739
739
  * Helper type to check if all members of a union are object-like.
740
740
  * This allows merge() to work with parsers like withDefault() that produce union types.
741
741
  */
742
- type AllObjectLike<T> = T extends Record<string | symbol, unknown> ? T : never;
742
+ type AllObjectLike<T> = T extends readonly unknown[] ? never : T extends Record<string | symbol, unknown> ? T : never;
743
743
  /**
744
744
  * Helper type to extract object-like types from parser value types,
745
745
  * including union types where all members are objects.
@@ -758,7 +758,7 @@ type ExtractObjectTypes<P> = P extends Parser<infer V, unknown> ? [AllObjectLike
758
758
  * @return A new {@link object} parser that combines the values and states
759
759
  * of the two parsers into a single object.
760
760
  */
761
- declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>>(a: TA, b: TB): ExtractObjectTypes<TA> extends never ? never : ExtractObjectTypes<TB> extends never ? never : Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB>, Record<string | symbol, unknown>>;
761
+ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>>(a: ExtractObjectTypes<TA> extends never ? never : TA, b: ExtractObjectTypes<TB> extends never ? never : TB): Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB>, Record<string | symbol, unknown>>;
762
762
  /**
763
763
  * Merges multiple {@link object} parsers into a single {@link object} parser
764
764
  * with a label for documentation and help text organization.
@@ -775,7 +775,7 @@ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<un
775
775
  * @return A new {@link object} parser that combines the values and states
776
776
  * of the two parsers into a single object.
777
777
  */
778
- declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>>(label: string, a: TA, b: TB): ExtractObjectTypes<TA> extends never ? never : ExtractObjectTypes<TB> extends never ? never : Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB>, Record<string | symbol, unknown>>;
778
+ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>>(label: string, a: ExtractObjectTypes<TA> extends never ? never : TA, b: ExtractObjectTypes<TB> extends never ? never : TB): Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB>, Record<string | symbol, unknown>>;
779
779
  /**
780
780
  * Merges multiple {@link object} parsers into a single {@link object} parser.
781
781
  * It is useful for combining multiple {@link object} parsers so that
@@ -791,7 +791,7 @@ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<un
791
791
  * @return A new {@link object} parser that combines the values and states
792
792
  * of the two parsers into a single object.
793
793
  */
794
- declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>, TC extends Parser<unknown, unknown>>(a: TA, b: TB, c: TC): ExtractObjectTypes<TA> extends never ? never : ExtractObjectTypes<TB> extends never ? never : ExtractObjectTypes<TC> extends never ? never : Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB> & ExtractObjectTypes<TC>, Record<string | symbol, unknown>>;
794
+ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>, TC extends Parser<unknown, unknown>>(a: ExtractObjectTypes<TA> extends never ? never : TA, b: ExtractObjectTypes<TB> extends never ? never : TB, c: ExtractObjectTypes<TC> extends never ? never : TC): Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB> & ExtractObjectTypes<TC>, Record<string | symbol, unknown>>;
795
795
  /**
796
796
  * Merges multiple {@link object} parsers into a single {@link object} parser
797
797
  * with a label for documentation and help text organization.
@@ -869,7 +869,7 @@ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<un
869
869
  * @return A new {@link object} parser that combines the values and states
870
870
  * of the two parsers into a single object.
871
871
  */
872
- declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>, TC extends Parser<unknown, unknown>, TD extends Parser<unknown, unknown>, TE extends Parser<unknown, unknown>>(a: TA, b: TB, c: TC, d: TD, e: TE): ExtractObjectTypes<TA> extends never ? never : ExtractObjectTypes<TB> extends never ? never : ExtractObjectTypes<TC> extends never ? never : ExtractObjectTypes<TD> extends never ? never : ExtractObjectTypes<TE> extends never ? never : Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB> & ExtractObjectTypes<TC> & ExtractObjectTypes<TD> & ExtractObjectTypes<TE>, Record<string | symbol, unknown>>;
872
+ declare function merge<TA extends Parser<unknown, unknown>, TB extends Parser<unknown, unknown>, TC extends Parser<unknown, unknown>, TD extends Parser<unknown, unknown>, TE extends Parser<unknown, unknown>>(a: ExtractObjectTypes<TA> extends never ? never : TA, b: ExtractObjectTypes<TB> extends never ? never : TB, c: ExtractObjectTypes<TC> extends never ? never : TC, d: ExtractObjectTypes<TD> extends never ? never : TD, e: ExtractObjectTypes<TE> extends never ? never : TE): Parser<ExtractObjectTypes<TA> & ExtractObjectTypes<TB> & ExtractObjectTypes<TC> & ExtractObjectTypes<TD> & ExtractObjectTypes<TE>, Record<string | symbol, unknown>>;
873
873
  /**
874
874
  * Merges multiple {@link object} parsers into a single {@link object} parser
875
875
  * with a label for documentation and help text organization.
@@ -1353,6 +1353,49 @@ type Result<T> = {
1353
1353
  * failure.
1354
1354
  */
1355
1355
  declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]): Result<T>;
1356
+ /**
1357
+ * Wraps a parser with a group label for documentation purposes.
1358
+ *
1359
+ * The `group()` function is a documentation-only wrapper that applies a label
1360
+ * to any parser for help text organization. This allows you to use clean code
1361
+ * structure with combinators like {@link merge} while maintaining well-organized
1362
+ * help text through group labeling.
1363
+ *
1364
+ * The wrapped parser has identical parsing behavior but generates documentation
1365
+ * fragments wrapped in a labeled section. This is particularly useful when
1366
+ * combining parsers using {@link merge}—you can wrap the merged result with
1367
+ * `group()` to add a section header in help output.
1368
+ *
1369
+ * @example
1370
+ * ```typescript
1371
+ * const apiOptions = merge(
1372
+ * object({ endpoint: option("--endpoint", string()) }),
1373
+ * object({ timeout: option("--timeout", integer()) })
1374
+ * );
1375
+ *
1376
+ * const groupedApiOptions = group("API Options", apiOptions);
1377
+ * // Now produces a labeled "API Options" section in help text
1378
+ * ```
1379
+ *
1380
+ * @example
1381
+ * ```typescript
1382
+ * // Can be used with any parser, not just merge()
1383
+ * const verboseGroup = group("Verbosity", object({
1384
+ * verbose: option("-v", "--verbose"),
1385
+ * quiet: option("-q", "--quiet")
1386
+ * }));
1387
+ * ```
1388
+ *
1389
+ * @template TValue The value type of the wrapped parser.
1390
+ * @template TState The state type of the wrapped parser.
1391
+ * @param label A descriptive label for this parser group, used for
1392
+ * documentation and help text organization.
1393
+ * @param parser The parser to wrap with a group label.
1394
+ * @returns A new parser that behaves identically to the input parser
1395
+ * but generates documentation within a labeled section.
1396
+ * @since 0.4.0
1397
+ */
1398
+ declare function group<TValue, TState>(label: string, parser: Parser<TValue, TState>): Parser<TValue, TState>;
1356
1399
  /**
1357
1400
  * Generates a documentation page for a parser based on its current state after
1358
1401
  * attempting to parse the provided arguments. This function is useful for
@@ -1388,4 +1431,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
1388
1431
  */
1389
1432
  declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
1390
1433
  //#endregion
1391
- export { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, flag, getDocPage, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
1434
+ export { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
package/dist/parser.js CHANGED
@@ -1492,6 +1492,81 @@ function parse(parser, args) {
1492
1492
  };
1493
1493
  }
1494
1494
  /**
1495
+ * Wraps a parser with a group label for documentation purposes.
1496
+ *
1497
+ * The `group()` function is a documentation-only wrapper that applies a label
1498
+ * to any parser for help text organization. This allows you to use clean code
1499
+ * structure with combinators like {@link merge} while maintaining well-organized
1500
+ * help text through group labeling.
1501
+ *
1502
+ * The wrapped parser has identical parsing behavior but generates documentation
1503
+ * fragments wrapped in a labeled section. This is particularly useful when
1504
+ * combining parsers using {@link merge}—you can wrap the merged result with
1505
+ * `group()` to add a section header in help output.
1506
+ *
1507
+ * @example
1508
+ * ```typescript
1509
+ * const apiOptions = merge(
1510
+ * object({ endpoint: option("--endpoint", string()) }),
1511
+ * object({ timeout: option("--timeout", integer()) })
1512
+ * );
1513
+ *
1514
+ * const groupedApiOptions = group("API Options", apiOptions);
1515
+ * // Now produces a labeled "API Options" section in help text
1516
+ * ```
1517
+ *
1518
+ * @example
1519
+ * ```typescript
1520
+ * // Can be used with any parser, not just merge()
1521
+ * const verboseGroup = group("Verbosity", object({
1522
+ * verbose: option("-v", "--verbose"),
1523
+ * quiet: option("-q", "--quiet")
1524
+ * }));
1525
+ * ```
1526
+ *
1527
+ * @template TValue The value type of the wrapped parser.
1528
+ * @template TState The state type of the wrapped parser.
1529
+ * @param label A descriptive label for this parser group, used for
1530
+ * documentation and help text organization.
1531
+ * @param parser The parser to wrap with a group label.
1532
+ * @returns A new parser that behaves identically to the input parser
1533
+ * but generates documentation within a labeled section.
1534
+ * @since 0.4.0
1535
+ */
1536
+ function group(label, parser) {
1537
+ return {
1538
+ $valueType: parser.$valueType,
1539
+ $stateType: parser.$stateType,
1540
+ priority: parser.priority,
1541
+ usage: parser.usage,
1542
+ initialState: parser.initialState,
1543
+ parse: (context) => parser.parse(context),
1544
+ complete: (state) => parser.complete(state),
1545
+ getDocFragments: (state, defaultValue) => {
1546
+ const { description, fragments } = parser.getDocFragments(state, defaultValue);
1547
+ const allEntries = [];
1548
+ const titledSections = [];
1549
+ for (const fragment of fragments) if (fragment.type === "entry") allEntries.push(fragment);
1550
+ else if (fragment.type === "section") if (fragment.title) titledSections.push(fragment);
1551
+ else allEntries.push(...fragment.entries);
1552
+ const labeledSection = {
1553
+ title: label,
1554
+ entries: allEntries
1555
+ };
1556
+ return {
1557
+ description,
1558
+ fragments: [...titledSections.map((s) => ({
1559
+ ...s,
1560
+ type: "section"
1561
+ })), {
1562
+ type: "section",
1563
+ ...labeledSection
1564
+ }]
1565
+ };
1566
+ }
1567
+ };
1568
+ }
1569
+ /**
1495
1570
  * Generates a documentation page for a parser based on its current state after
1496
1571
  * attempting to parse the provided arguments. This function is useful for
1497
1572
  * creating help documentation that reflects the current parsing context.
@@ -1570,4 +1645,4 @@ function getDocPage(parser, args = []) {
1570
1645
  }
1571
1646
 
1572
1647
  //#endregion
1573
- export { argument, command, concat, constant, flag, getDocPage, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
1648
+ export { argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
@@ -84,7 +84,7 @@ function string(options = {}) {
84
84
  * @example
85
85
  * ```typescript
86
86
  * // Create a parser for regular integers
87
- * const portParser = integer({ min: 1, max: 65535 });
87
+ * const portParser = integer({ min: 1, max: 0xffff });
88
88
  *
89
89
  * // Create a parser for BigInt values
90
90
  * const bigIntParser = integer({ type: "bigint", min: 0n });
@@ -84,7 +84,7 @@ function string(options = {}) {
84
84
  * @example
85
85
  * ```typescript
86
86
  * // Create a parser for regular integers
87
- * const portParser = integer({ min: 1, max: 65535 });
87
+ * const portParser = integer({ min: 1, max: 0xffff });
88
88
  *
89
89
  * // Create a parser for BigInt values
90
90
  * const bigIntParser = integer({ type: "bigint", min: 0n });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "0.4.0-dev.52+12ee9e92",
3
+ "version": "0.4.0-dev.54+e30f3e5c",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",