@optique/core 1.0.12-dev.2703 → 1.0.13-dev.2743

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.
@@ -1,5 +1,6 @@
1
1
  const require_annotations = require('./internal/annotations.cjs');
2
2
  const require_message = require('./message.cjs');
3
+ const require_command_doc_metadata = require('./internal/command-doc-metadata.cjs');
3
4
  const require_passthrough = require('./internal/passthrough.cjs');
4
5
  const require_validate = require('./validate.cjs');
5
6
  const require_usage = require('./usage.cjs');
@@ -1275,6 +1276,7 @@ function or(...args) {
1275
1276
  },
1276
1277
  suggest: createExclusiveSuggest(parsers, combinedMode),
1277
1278
  getDocFragments(state, _defaultValue) {
1279
+ let commandMetadata;
1278
1280
  let brief;
1279
1281
  let description;
1280
1282
  let footer;
@@ -1287,18 +1289,19 @@ function or(...args) {
1287
1289
  state: parserResult.next.state
1288
1290
  } : { kind: "unavailable" };
1289
1291
  const docFragments = parsers[index].getDocFragments(innerState, void 0);
1292
+ commandMetadata = require_command_doc_metadata.getCommandDocMetadata(docFragments);
1290
1293
  brief = docFragments.brief;
1291
1294
  description = docFragments.description;
1292
1295
  footer = docFragments.footer;
1293
1296
  fragments = docFragments.fragments;
1294
1297
  }
1295
1298
  if (state.kind === "unavailable" || state.state == null) fragments = require_doc.deduplicateDocFragments(fragments);
1296
- return {
1299
+ return require_command_doc_metadata.withCommandDocMetadata({
1297
1300
  brief,
1298
1301
  description,
1299
1302
  footer,
1300
1303
  fragments
1301
- };
1304
+ }, commandMetadata);
1302
1305
  }
1303
1306
  };
1304
1307
  const singleDependencyMetadata = composeExclusiveDependencyMetadata(parsers);
@@ -1501,6 +1504,7 @@ function longestMatch(...args) {
1501
1504
  },
1502
1505
  suggest: createExclusiveSuggest(parsers, combinedMode),
1503
1506
  getDocFragments(state, _defaultValue) {
1507
+ let commandMetadata;
1504
1508
  let brief;
1505
1509
  let description;
1506
1510
  let footer;
@@ -1516,6 +1520,7 @@ function longestMatch(...args) {
1516
1520
  kind: "available",
1517
1521
  state: result.next.state
1518
1522
  });
1523
+ commandMetadata = require_command_doc_metadata.getCommandDocMetadata(docResult);
1519
1524
  brief = docResult.brief;
1520
1525
  description = docResult.description;
1521
1526
  footer = docResult.footer;
@@ -1526,12 +1531,12 @@ function longestMatch(...args) {
1526
1531
  shouldDeduplicate = true;
1527
1532
  }
1528
1533
  }
1529
- return {
1534
+ return require_command_doc_metadata.withCommandDocMetadata({
1530
1535
  brief,
1531
1536
  description,
1532
1537
  fragments: shouldDeduplicate ? require_doc.deduplicateDocFragments(fragments) : fragments,
1533
1538
  footer
1534
- };
1539
+ }, commandMetadata);
1535
1540
  }
1536
1541
  };
1537
1542
  const multiDependencyMetadata = composeExclusiveDependencyMetadata(parsers);
@@ -2477,12 +2482,15 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2477
2482
  }, () => suggestObjectAsync(context, prefix, parserPairs));
2478
2483
  },
2479
2484
  getDocFragments(state, defaultValue) {
2485
+ let commandMetadata;
2480
2486
  const fragments = parserPairs.flatMap(([field, p]) => {
2481
2487
  const fieldState = state.kind === "unavailable" ? { kind: "unavailable" } : {
2482
2488
  kind: "available",
2483
2489
  state: state.state[field]
2484
2490
  };
2485
- return p.getDocFragments(fieldState, defaultValue?.[field]).fragments;
2491
+ const docs = p.getDocFragments(fieldState, defaultValue?.[field]);
2492
+ commandMetadata = require_command_doc_metadata.collectCommandDocMetadata(commandMetadata, docs);
2493
+ return docs.fragments;
2486
2494
  });
2487
2495
  const hiddenAwareFragments = applyHiddenToDocFragments(fragments, options.hidden);
2488
2496
  const entries = hiddenAwareFragments.filter((d) => d.type === "entry");
@@ -2497,10 +2505,13 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2497
2505
  entries
2498
2506
  };
2499
2507
  sections.push(section);
2500
- return { fragments: sections.map((s) => ({
2501
- ...s,
2502
- type: "section"
2503
- })) };
2508
+ return require_command_doc_metadata.withCommandDocMetadata({
2509
+ ...commandMetadata,
2510
+ fragments: sections.map((s) => ({
2511
+ ...s,
2512
+ type: "section"
2513
+ }))
2514
+ }, commandMetadata);
2504
2515
  }
2505
2516
  };
2506
2517
  const fieldNormalizers = [];
@@ -3126,12 +3137,15 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3126
3137
  return require_mode_dispatch.dispatchIterableByMode(combinedMode, () => suggestTupleSync(context, prefix, syncParsers), () => suggestTupleAsync(context, prefix, parsers));
3127
3138
  },
3128
3139
  getDocFragments(state, defaultValue) {
3140
+ let commandMetadata;
3129
3141
  const fragments = syncParsers.flatMap((p, i) => {
3130
3142
  const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
3131
3143
  kind: "available",
3132
3144
  state: state.state[i]
3133
3145
  };
3134
- return p.getDocFragments(indexState, defaultValue?.[i]).fragments;
3146
+ const docs = p.getDocFragments(indexState, defaultValue?.[i]);
3147
+ commandMetadata = require_command_doc_metadata.collectCommandDocMetadata(commandMetadata, docs);
3148
+ return docs.fragments;
3135
3149
  });
3136
3150
  const entries = fragments.filter((d) => d.type === "entry");
3137
3151
  const sections = [];
@@ -3145,10 +3159,13 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3145
3159
  entries
3146
3160
  };
3147
3161
  sections.push(section);
3148
- return { fragments: sections.map((s) => ({
3149
- ...s,
3150
- type: "section"
3151
- })) };
3162
+ return require_command_doc_metadata.withCommandDocMetadata({
3163
+ ...commandMetadata,
3164
+ fragments: sections.map((s) => ({
3165
+ ...s,
3166
+ type: "section"
3167
+ }))
3168
+ }, commandMetadata);
3152
3169
  },
3153
3170
  [Symbol.for("Deno.customInspect")]() {
3154
3171
  const parsersStr = parsers.length === 1 ? `[1 parser]` : `[${parsers.length} parsers]`;
@@ -4038,6 +4055,7 @@ function merge(...args) {
4038
4055
  }();
4039
4056
  },
4040
4057
  getDocFragments(state, _defaultValue) {
4058
+ let commandMetadata;
4041
4059
  let brief;
4042
4060
  let description;
4043
4061
  let footer;
@@ -4055,6 +4073,7 @@ function merge(...args) {
4055
4073
  state: state.state
4056
4074
  };
4057
4075
  const docFragments = p.getDocFragments(parserState, void 0);
4076
+ commandMetadata = require_command_doc_metadata.collectCommandDocMetadata(commandMetadata, docFragments, true);
4058
4077
  brief ??= docFragments.brief;
4059
4078
  description ??= docFragments.description;
4060
4079
  footer ??= docFragments.footer;
@@ -4074,7 +4093,7 @@ function merge(...args) {
4074
4093
  entries
4075
4094
  };
4076
4095
  sections.push(labeledSection);
4077
- return {
4096
+ return require_command_doc_metadata.withCommandDocMetadata({
4078
4097
  brief,
4079
4098
  description,
4080
4099
  footer,
@@ -4082,9 +4101,9 @@ function merge(...args) {
4082
4101
  ...s,
4083
4102
  type: "section"
4084
4103
  }))
4085
- };
4104
+ }, commandMetadata);
4086
4105
  }
4087
- return {
4106
+ return require_command_doc_metadata.withCommandDocMetadata({
4088
4107
  brief,
4089
4108
  description,
4090
4109
  footer,
@@ -4095,7 +4114,7 @@ function merge(...args) {
4095
4114
  type: "section",
4096
4115
  entries
4097
4116
  }]
4098
- };
4117
+ }, commandMetadata);
4099
4118
  }
4100
4119
  };
4101
4120
  require_parser.defineParseLanes(mergeParser, mergeParseLanes);
@@ -4707,12 +4726,15 @@ function concat(...parsers) {
4707
4726
  }();
4708
4727
  },
4709
4728
  getDocFragments(state, _defaultValue) {
4729
+ let commandMetadata;
4710
4730
  const fragments = syncParsers.flatMap((p, index) => {
4711
4731
  const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
4712
4732
  kind: "available",
4713
4733
  state: state.state[index]
4714
4734
  };
4715
- return p.getDocFragments(indexState, void 0).fragments;
4735
+ const docs = p.getDocFragments(indexState, void 0);
4736
+ commandMetadata = require_command_doc_metadata.collectCommandDocMetadata(commandMetadata, docs);
4737
+ return docs.fragments;
4716
4738
  });
4717
4739
  const entries = fragments.filter((f) => f.type === "entry");
4718
4740
  const sections = [];
@@ -4729,7 +4751,10 @@ function concat(...parsers) {
4729
4751
  type: "section",
4730
4752
  entries
4731
4753
  });
4732
- return { fragments: result };
4754
+ return require_command_doc_metadata.withCommandDocMetadata({
4755
+ ...commandMetadata,
4756
+ fragments: result
4757
+ }, commandMetadata);
4733
4758
  }
4734
4759
  };
4735
4760
  require_parser.defineInheritedAnnotationParser(concatParser);
@@ -4764,7 +4789,8 @@ function group(label, parser, options = {}) {
4764
4789
  return parser.suggest(context, prefix);
4765
4790
  },
4766
4791
  getDocFragments: (state, defaultValue) => {
4767
- const { brief, description, footer, fragments } = parser.getDocFragments(state, defaultValue);
4792
+ const docs = parser.getDocFragments(state, defaultValue);
4793
+ const { brief, description, footer, fragments } = docs;
4768
4794
  const hiddenAwareFragments = applyHiddenToDocFragments(fragments, options.hidden);
4769
4795
  const allEntries = [];
4770
4796
  const titledSections = [];
@@ -4787,7 +4813,7 @@ function group(label, parser, options = {}) {
4787
4813
  title: label,
4788
4814
  entries: allEntries
4789
4815
  } : { entries: allEntries };
4790
- return {
4816
+ return require_command_doc_metadata.withCommandDocMetadata({
4791
4817
  brief,
4792
4818
  description,
4793
4819
  footer,
@@ -4798,7 +4824,7 @@ function group(label, parser, options = {}) {
4798
4824
  type: "section",
4799
4825
  ...labeledSection
4800
4826
  }]
4801
- };
4827
+ }, require_command_doc_metadata.getCommandDocMetadata(docs));
4802
4828
  }
4803
4829
  };
4804
4830
  require_parser.defineParseLanes(groupParser, require_parser.getOwnParseLanes(parser));
@@ -1,5 +1,6 @@
1
1
  import { annotateFreshArray, getAnnotations, inheritAnnotations } from "./internal/annotations.js";
2
2
  import { message, optionName, text, values } from "./message.js";
3
+ import { collectCommandDocMetadata, getCommandDocMetadata, withCommandDocMetadata } from "./internal/command-doc-metadata.js";
3
4
  import { combineOptionMatches, combinePassThroughPriorities, defineOptionMatch, definePassThroughPriority, delegateKnownCompletion, getKnownCompletion, getOptionMatch, getPassThroughFailureHint, getPassThroughPriority, hasPassThroughUsage, matchesOptionToken, retainConsumingFailure, retainConsumingFailureHint, withPassThroughFailure } from "./internal/passthrough.js";
4
5
  import { validateLabel } from "./validate.js";
5
6
  import { extractArgumentMetavars, extractCommandNames, extractOptionNames, isDocHidden, mergeHidden } from "./usage.js";
@@ -1275,6 +1276,7 @@ function or(...args) {
1275
1276
  },
1276
1277
  suggest: createExclusiveSuggest(parsers, combinedMode),
1277
1278
  getDocFragments(state, _defaultValue) {
1279
+ let commandMetadata;
1278
1280
  let brief;
1279
1281
  let description;
1280
1282
  let footer;
@@ -1287,18 +1289,19 @@ function or(...args) {
1287
1289
  state: parserResult.next.state
1288
1290
  } : { kind: "unavailable" };
1289
1291
  const docFragments = parsers[index].getDocFragments(innerState, void 0);
1292
+ commandMetadata = getCommandDocMetadata(docFragments);
1290
1293
  brief = docFragments.brief;
1291
1294
  description = docFragments.description;
1292
1295
  footer = docFragments.footer;
1293
1296
  fragments = docFragments.fragments;
1294
1297
  }
1295
1298
  if (state.kind === "unavailable" || state.state == null) fragments = deduplicateDocFragments(fragments);
1296
- return {
1299
+ return withCommandDocMetadata({
1297
1300
  brief,
1298
1301
  description,
1299
1302
  footer,
1300
1303
  fragments
1301
- };
1304
+ }, commandMetadata);
1302
1305
  }
1303
1306
  };
1304
1307
  const singleDependencyMetadata = composeExclusiveDependencyMetadata(parsers);
@@ -1501,6 +1504,7 @@ function longestMatch(...args) {
1501
1504
  },
1502
1505
  suggest: createExclusiveSuggest(parsers, combinedMode),
1503
1506
  getDocFragments(state, _defaultValue) {
1507
+ let commandMetadata;
1504
1508
  let brief;
1505
1509
  let description;
1506
1510
  let footer;
@@ -1516,6 +1520,7 @@ function longestMatch(...args) {
1516
1520
  kind: "available",
1517
1521
  state: result.next.state
1518
1522
  });
1523
+ commandMetadata = getCommandDocMetadata(docResult);
1519
1524
  brief = docResult.brief;
1520
1525
  description = docResult.description;
1521
1526
  footer = docResult.footer;
@@ -1526,12 +1531,12 @@ function longestMatch(...args) {
1526
1531
  shouldDeduplicate = true;
1527
1532
  }
1528
1533
  }
1529
- return {
1534
+ return withCommandDocMetadata({
1530
1535
  brief,
1531
1536
  description,
1532
1537
  fragments: shouldDeduplicate ? deduplicateDocFragments(fragments) : fragments,
1533
1538
  footer
1534
- };
1539
+ }, commandMetadata);
1535
1540
  }
1536
1541
  };
1537
1542
  const multiDependencyMetadata = composeExclusiveDependencyMetadata(parsers);
@@ -2477,12 +2482,15 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2477
2482
  }, () => suggestObjectAsync(context, prefix, parserPairs));
2478
2483
  },
2479
2484
  getDocFragments(state, defaultValue) {
2485
+ let commandMetadata;
2480
2486
  const fragments = parserPairs.flatMap(([field, p]) => {
2481
2487
  const fieldState = state.kind === "unavailable" ? { kind: "unavailable" } : {
2482
2488
  kind: "available",
2483
2489
  state: state.state[field]
2484
2490
  };
2485
- return p.getDocFragments(fieldState, defaultValue?.[field]).fragments;
2491
+ const docs = p.getDocFragments(fieldState, defaultValue?.[field]);
2492
+ commandMetadata = collectCommandDocMetadata(commandMetadata, docs);
2493
+ return docs.fragments;
2486
2494
  });
2487
2495
  const hiddenAwareFragments = applyHiddenToDocFragments(fragments, options.hidden);
2488
2496
  const entries = hiddenAwareFragments.filter((d) => d.type === "entry");
@@ -2497,10 +2505,13 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2497
2505
  entries
2498
2506
  };
2499
2507
  sections.push(section);
2500
- return { fragments: sections.map((s) => ({
2501
- ...s,
2502
- type: "section"
2503
- })) };
2508
+ return withCommandDocMetadata({
2509
+ ...commandMetadata,
2510
+ fragments: sections.map((s) => ({
2511
+ ...s,
2512
+ type: "section"
2513
+ }))
2514
+ }, commandMetadata);
2504
2515
  }
2505
2516
  };
2506
2517
  const fieldNormalizers = [];
@@ -3126,12 +3137,15 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3126
3137
  return dispatchIterableByMode(combinedMode, () => suggestTupleSync(context, prefix, syncParsers), () => suggestTupleAsync(context, prefix, parsers));
3127
3138
  },
3128
3139
  getDocFragments(state, defaultValue) {
3140
+ let commandMetadata;
3129
3141
  const fragments = syncParsers.flatMap((p, i) => {
3130
3142
  const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
3131
3143
  kind: "available",
3132
3144
  state: state.state[i]
3133
3145
  };
3134
- return p.getDocFragments(indexState, defaultValue?.[i]).fragments;
3146
+ const docs = p.getDocFragments(indexState, defaultValue?.[i]);
3147
+ commandMetadata = collectCommandDocMetadata(commandMetadata, docs);
3148
+ return docs.fragments;
3135
3149
  });
3136
3150
  const entries = fragments.filter((d) => d.type === "entry");
3137
3151
  const sections = [];
@@ -3145,10 +3159,13 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3145
3159
  entries
3146
3160
  };
3147
3161
  sections.push(section);
3148
- return { fragments: sections.map((s) => ({
3149
- ...s,
3150
- type: "section"
3151
- })) };
3162
+ return withCommandDocMetadata({
3163
+ ...commandMetadata,
3164
+ fragments: sections.map((s) => ({
3165
+ ...s,
3166
+ type: "section"
3167
+ }))
3168
+ }, commandMetadata);
3152
3169
  },
3153
3170
  [Symbol.for("Deno.customInspect")]() {
3154
3171
  const parsersStr = parsers.length === 1 ? `[1 parser]` : `[${parsers.length} parsers]`;
@@ -4038,6 +4055,7 @@ function merge(...args) {
4038
4055
  }();
4039
4056
  },
4040
4057
  getDocFragments(state, _defaultValue) {
4058
+ let commandMetadata;
4041
4059
  let brief;
4042
4060
  let description;
4043
4061
  let footer;
@@ -4055,6 +4073,7 @@ function merge(...args) {
4055
4073
  state: state.state
4056
4074
  };
4057
4075
  const docFragments = p.getDocFragments(parserState, void 0);
4076
+ commandMetadata = collectCommandDocMetadata(commandMetadata, docFragments, true);
4058
4077
  brief ??= docFragments.brief;
4059
4078
  description ??= docFragments.description;
4060
4079
  footer ??= docFragments.footer;
@@ -4074,7 +4093,7 @@ function merge(...args) {
4074
4093
  entries
4075
4094
  };
4076
4095
  sections.push(labeledSection);
4077
- return {
4096
+ return withCommandDocMetadata({
4078
4097
  brief,
4079
4098
  description,
4080
4099
  footer,
@@ -4082,9 +4101,9 @@ function merge(...args) {
4082
4101
  ...s,
4083
4102
  type: "section"
4084
4103
  }))
4085
- };
4104
+ }, commandMetadata);
4086
4105
  }
4087
- return {
4106
+ return withCommandDocMetadata({
4088
4107
  brief,
4089
4108
  description,
4090
4109
  footer,
@@ -4095,7 +4114,7 @@ function merge(...args) {
4095
4114
  type: "section",
4096
4115
  entries
4097
4116
  }]
4098
- };
4117
+ }, commandMetadata);
4099
4118
  }
4100
4119
  };
4101
4120
  defineParseLanes(mergeParser, mergeParseLanes);
@@ -4707,12 +4726,15 @@ function concat(...parsers) {
4707
4726
  }();
4708
4727
  },
4709
4728
  getDocFragments(state, _defaultValue) {
4729
+ let commandMetadata;
4710
4730
  const fragments = syncParsers.flatMap((p, index) => {
4711
4731
  const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
4712
4732
  kind: "available",
4713
4733
  state: state.state[index]
4714
4734
  };
4715
- return p.getDocFragments(indexState, void 0).fragments;
4735
+ const docs = p.getDocFragments(indexState, void 0);
4736
+ commandMetadata = collectCommandDocMetadata(commandMetadata, docs);
4737
+ return docs.fragments;
4716
4738
  });
4717
4739
  const entries = fragments.filter((f) => f.type === "entry");
4718
4740
  const sections = [];
@@ -4729,7 +4751,10 @@ function concat(...parsers) {
4729
4751
  type: "section",
4730
4752
  entries
4731
4753
  });
4732
- return { fragments: result };
4754
+ return withCommandDocMetadata({
4755
+ ...commandMetadata,
4756
+ fragments: result
4757
+ }, commandMetadata);
4733
4758
  }
4734
4759
  };
4735
4760
  defineInheritedAnnotationParser(concatParser);
@@ -4764,7 +4789,8 @@ function group(label, parser, options = {}) {
4764
4789
  return parser.suggest(context, prefix);
4765
4790
  },
4766
4791
  getDocFragments: (state, defaultValue) => {
4767
- const { brief, description, footer, fragments } = parser.getDocFragments(state, defaultValue);
4792
+ const docs = parser.getDocFragments(state, defaultValue);
4793
+ const { brief, description, footer, fragments } = docs;
4768
4794
  const hiddenAwareFragments = applyHiddenToDocFragments(fragments, options.hidden);
4769
4795
  const allEntries = [];
4770
4796
  const titledSections = [];
@@ -4787,7 +4813,7 @@ function group(label, parser, options = {}) {
4787
4813
  title: label,
4788
4814
  entries: allEntries
4789
4815
  } : { entries: allEntries };
4790
- return {
4816
+ return withCommandDocMetadata({
4791
4817
  brief,
4792
4818
  description,
4793
4819
  footer,
@@ -4798,7 +4824,7 @@ function group(label, parser, options = {}) {
4798
4824
  type: "section",
4799
4825
  ...labeledSection
4800
4826
  }]
4801
- };
4827
+ }, getCommandDocMetadata(docs));
4802
4828
  }
4803
4829
  };
4804
4830
  defineParseLanes(groupParser, getOwnParseLanes(parser));
@@ -0,0 +1,90 @@
1
+
2
+ //#region src/internal/command-doc-metadata.ts
3
+ function withOrigin(metadata, origin) {
4
+ const result = { ...metadata };
5
+ Object.defineProperty(result, "origin", {
6
+ value: origin,
7
+ enumerable: false
8
+ });
9
+ return result;
10
+ }
11
+ const commandDocMetadata = Symbol.for("@optique/core/commandDocMetadata");
12
+ const commandDocCarrier = Symbol.for("@optique/core/commandDocMetadataCarrier");
13
+ /**
14
+ * Reads effective page metadata, including custom collection-level fields.
15
+ * @param docs The child's documentation.
16
+ * @returns Its selected-command metadata, if any.
17
+ */
18
+ function getCommandDocMetadata(docs) {
19
+ const carrier = docs.fragments[commandDocCarrier];
20
+ if (carrier != null) {
21
+ const brief = docs.brief === carrier.brief ? carrier.metadata.brief : docs.brief;
22
+ const origin = carrier.metadata.origin ?? "entry";
23
+ const customPage = origin === "entry" && (docs.brief !== carrier.brief || docs.footer !== carrier.footer);
24
+ const description = origin === "entry" && !customPage || docs.description === carrier.description ? carrier.metadata.description : docs.description;
25
+ const footer = docs.footer === carrier.footer ? carrier.metadata.footer : docs.footer;
26
+ return withOrigin({
27
+ ...brief == null ? {} : { brief },
28
+ ...description == null ? {} : { description },
29
+ ...footer == null ? {} : { footer }
30
+ }, customPage ? "custom" : origin);
31
+ }
32
+ const metadata = docs[commandDocMetadata];
33
+ if (metadata != null) return metadata;
34
+ return docs.brief != null || docs.description != null || docs.footer != null ? withOrigin({
35
+ brief: docs.brief,
36
+ description: docs.description,
37
+ footer: docs.footer
38
+ }, "custom") : void 0;
39
+ }
40
+ /**
41
+ * Preserves selected-command metadata when rebuilding documentation fragments.
42
+ * @param docs The rebuilt documentation.
43
+ * @param metadata The selected-command metadata to preserve.
44
+ * @returns Documentation with the internal metadata attached.
45
+ */
46
+ function withCommandDocMetadata(docs, metadata) {
47
+ if (metadata == null) return docs;
48
+ metadata = withOrigin(metadata, metadata.origin ?? "entry");
49
+ const fragments = [...docs.fragments];
50
+ Object.defineProperty(fragments, commandDocCarrier, { value: {
51
+ metadata,
52
+ brief: docs.brief,
53
+ description: docs.description,
54
+ footer: docs.footer
55
+ } });
56
+ const result = {
57
+ ...docs,
58
+ fragments
59
+ };
60
+ Object.defineProperty(result, commandDocMetadata, { value: metadata });
61
+ return result;
62
+ }
63
+ /**
64
+ * Collects selected-command metadata in documentation traversal order.
65
+ * @param current Metadata from earlier children.
66
+ * @param docs The next child's documentation.
67
+ * @param includeCustom Whether to retain custom page fields inside merge().
68
+ * @returns The first defined value from children with the same origin.
69
+ */
70
+ function collectCommandDocMetadata(current, docs, includeCustom = false) {
71
+ const next = getCommandDocMetadata(docs);
72
+ if (next == null) return current;
73
+ const origin = next.origin ?? "entry";
74
+ if (origin === "entry" || origin === "custom" && !includeCustom) return current ?? withOrigin({}, "entry");
75
+ if (current?.origin === "command" && origin !== "command") return current;
76
+ if (current?.origin !== origin) current = void 0;
77
+ const brief = current?.brief ?? next.brief;
78
+ const description = current?.description ?? next.description;
79
+ const footer = current?.footer ?? next.footer;
80
+ return withOrigin({
81
+ ...brief == null ? {} : { brief },
82
+ ...description == null ? {} : { description },
83
+ ...footer == null ? {} : { footer }
84
+ }, origin);
85
+ }
86
+
87
+ //#endregion
88
+ exports.collectCommandDocMetadata = collectCommandDocMetadata;
89
+ exports.getCommandDocMetadata = getCommandDocMetadata;
90
+ exports.withCommandDocMetadata = withCommandDocMetadata;
@@ -0,0 +1,87 @@
1
+ //#region src/internal/command-doc-metadata.ts
2
+ function withOrigin(metadata, origin) {
3
+ const result = { ...metadata };
4
+ Object.defineProperty(result, "origin", {
5
+ value: origin,
6
+ enumerable: false
7
+ });
8
+ return result;
9
+ }
10
+ const commandDocMetadata = Symbol.for("@optique/core/commandDocMetadata");
11
+ const commandDocCarrier = Symbol.for("@optique/core/commandDocMetadataCarrier");
12
+ /**
13
+ * Reads effective page metadata, including custom collection-level fields.
14
+ * @param docs The child's documentation.
15
+ * @returns Its selected-command metadata, if any.
16
+ */
17
+ function getCommandDocMetadata(docs) {
18
+ const carrier = docs.fragments[commandDocCarrier];
19
+ if (carrier != null) {
20
+ const brief = docs.brief === carrier.brief ? carrier.metadata.brief : docs.brief;
21
+ const origin = carrier.metadata.origin ?? "entry";
22
+ const customPage = origin === "entry" && (docs.brief !== carrier.brief || docs.footer !== carrier.footer);
23
+ const description = origin === "entry" && !customPage || docs.description === carrier.description ? carrier.metadata.description : docs.description;
24
+ const footer = docs.footer === carrier.footer ? carrier.metadata.footer : docs.footer;
25
+ return withOrigin({
26
+ ...brief == null ? {} : { brief },
27
+ ...description == null ? {} : { description },
28
+ ...footer == null ? {} : { footer }
29
+ }, customPage ? "custom" : origin);
30
+ }
31
+ const metadata = docs[commandDocMetadata];
32
+ if (metadata != null) return metadata;
33
+ return docs.brief != null || docs.description != null || docs.footer != null ? withOrigin({
34
+ brief: docs.brief,
35
+ description: docs.description,
36
+ footer: docs.footer
37
+ }, "custom") : void 0;
38
+ }
39
+ /**
40
+ * Preserves selected-command metadata when rebuilding documentation fragments.
41
+ * @param docs The rebuilt documentation.
42
+ * @param metadata The selected-command metadata to preserve.
43
+ * @returns Documentation with the internal metadata attached.
44
+ */
45
+ function withCommandDocMetadata(docs, metadata) {
46
+ if (metadata == null) return docs;
47
+ metadata = withOrigin(metadata, metadata.origin ?? "entry");
48
+ const fragments = [...docs.fragments];
49
+ Object.defineProperty(fragments, commandDocCarrier, { value: {
50
+ metadata,
51
+ brief: docs.brief,
52
+ description: docs.description,
53
+ footer: docs.footer
54
+ } });
55
+ const result = {
56
+ ...docs,
57
+ fragments
58
+ };
59
+ Object.defineProperty(result, commandDocMetadata, { value: metadata });
60
+ return result;
61
+ }
62
+ /**
63
+ * Collects selected-command metadata in documentation traversal order.
64
+ * @param current Metadata from earlier children.
65
+ * @param docs The next child's documentation.
66
+ * @param includeCustom Whether to retain custom page fields inside merge().
67
+ * @returns The first defined value from children with the same origin.
68
+ */
69
+ function collectCommandDocMetadata(current, docs, includeCustom = false) {
70
+ const next = getCommandDocMetadata(docs);
71
+ if (next == null) return current;
72
+ const origin = next.origin ?? "entry";
73
+ if (origin === "entry" || origin === "custom" && !includeCustom) return current ?? withOrigin({}, "entry");
74
+ if (current?.origin === "command" && origin !== "command") return current;
75
+ if (current?.origin !== origin) current = void 0;
76
+ const brief = current?.brief ?? next.brief;
77
+ const description = current?.description ?? next.description;
78
+ const footer = current?.footer ?? next.footer;
79
+ return withOrigin({
80
+ ...brief == null ? {} : { brief },
81
+ ...description == null ? {} : { description },
82
+ ...footer == null ? {} : { footer }
83
+ }, origin);
84
+ }
85
+
86
+ //#endregion
87
+ export { collectCommandDocMetadata, getCommandDocMetadata, withCommandDocMetadata };
@@ -1,5 +1,6 @@
1
1
  const require_annotations = require('./internal/annotations.cjs');
2
2
  const require_message = require('./message.cjs');
3
+ const require_command_doc_metadata = require('./internal/command-doc-metadata.cjs');
3
4
  const require_passthrough = require('./internal/passthrough.cjs');
4
5
  const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
5
6
  const require_parser = require('./internal/parser.cjs');
@@ -621,10 +622,10 @@ function withDefault(parser, defaultValue, options) {
621
622
  };
622
623
  return fragment;
623
624
  });
624
- return {
625
+ return require_command_doc_metadata.withCommandDocMetadata({
625
626
  ...fragments,
626
627
  fragments: modifiedFragments
627
- };
628
+ }, require_command_doc_metadata.getCommandDocMetadata(fragments));
628
629
  }
629
630
  return fragments;
630
631
  }
package/dist/modifiers.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { annotateFreshArray, annotationKey, getAnnotations, inheritAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./internal/annotations.js";
2
2
  import { formatMessage, message, text } from "./message.js";
3
+ import { getCommandDocMetadata, withCommandDocMetadata } from "./internal/command-doc-metadata.js";
3
4
  import { defineKnownCompletionLookup, defineOptionMatch, definePassThroughPriority, getKnownCompletion, getOptionMatch, getPassThroughPriority } from "./internal/passthrough.js";
4
5
  import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } from "./internal/mode-dispatch.js";
5
6
  import { defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getOwnParseLanes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
@@ -621,10 +622,10 @@ function withDefault(parser, defaultValue, options) {
621
622
  };
622
623
  return fragment;
623
624
  });
624
- return {
625
+ return withCommandDocMetadata({
625
626
  ...fragments,
626
627
  fragments: modifiedFragments
627
- };
628
+ }, getCommandDocMetadata(fragments));
628
629
  }
629
630
  return fragments;
630
631
  }
@@ -1,5 +1,6 @@
1
1
  const require_annotations = require('./internal/annotations.cjs');
2
2
  const require_message = require('./message.cjs');
3
+ const require_command_doc_metadata = require('./internal/command-doc-metadata.cjs');
3
4
  const require_passthrough = require('./internal/passthrough.cjs');
4
5
  const require_validate = require('./validate.cjs');
5
6
  const require_usage = require('./usage.cjs');
@@ -626,10 +627,10 @@ function option(...args) {
626
627
  return suggestOptionSync(optionNames$1, valueParser, require_usage.isSuggestionHidden(options.hidden), options.description, context, prefix);
627
628
  },
628
629
  getDocFragments(_state, defaultValue) {
629
- if (require_usage.isDocHidden(options.hidden)) return {
630
+ if (require_usage.isDocHidden(options.hidden)) return require_command_doc_metadata.withCommandDocMetadata({
630
631
  fragments: [],
631
632
  description: options.description
632
- };
633
+ }, {});
633
634
  const choicesMessage = valueParser?.choices != null && valueParser.choices.length > 0 ? require_message.valueSet(valueParser.choices.map((c) => valueParser.format(c)), {
634
635
  fallback: "",
635
636
  type: "unit"
@@ -645,10 +646,10 @@ function option(...args) {
645
646
  default: defaultValue != null && valueParser != null ? require_message.message`${valueParser.format(defaultValue)}` : void 0,
646
647
  choices: choicesMessage
647
648
  }];
648
- return {
649
+ return require_command_doc_metadata.withCommandDocMetadata({
649
650
  fragments,
650
651
  description: options.description
651
- };
652
+ }, {});
652
653
  },
653
654
  [Symbol.for("Deno.customInspect")]() {
654
655
  return `option(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
@@ -913,10 +914,10 @@ function flag(...args) {
913
914
  return suggestions;
914
915
  },
915
916
  getDocFragments(_state, _defaultValue) {
916
- if (require_usage.isDocHidden(options.hidden)) return {
917
+ if (require_usage.isDocHidden(options.hidden)) return require_command_doc_metadata.withCommandDocMetadata({
917
918
  fragments: [],
918
919
  description: options.description
919
- };
920
+ }, {});
920
921
  const fragments = [{
921
922
  type: "entry",
922
923
  term: {
@@ -925,10 +926,10 @@ function flag(...args) {
925
926
  },
926
927
  description: options.description
927
928
  }];
928
- return {
929
+ return require_command_doc_metadata.withCommandDocMetadata({
929
930
  fragments,
930
931
  description: options.description
931
- };
932
+ }, {});
932
933
  },
933
934
  [Symbol.for("Deno.customInspect")]() {
934
935
  return `flag(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
@@ -1064,10 +1065,10 @@ function argument(valueParser, options = {}) {
1064
1065
  return suggestArgumentSync(valueParser, require_usage.isSuggestionHidden(options.hidden), prefix, context.dependencyRegistry, context.exec);
1065
1066
  },
1066
1067
  getDocFragments(_state, defaultValue) {
1067
- if (require_usage.isDocHidden(options.hidden)) return {
1068
+ if (require_usage.isDocHidden(options.hidden)) return require_command_doc_metadata.withCommandDocMetadata({
1068
1069
  fragments: [],
1069
1070
  description: options.description
1070
- };
1071
+ }, {});
1071
1072
  const choicesMessage = valueParser.choices != null && valueParser.choices.length > 0 ? require_message.valueSet(valueParser.choices.map((c) => valueParser.format(c)), {
1072
1073
  fallback: "",
1073
1074
  type: "unit"
@@ -1079,10 +1080,10 @@ function argument(valueParser, options = {}) {
1079
1080
  default: defaultValue == null ? void 0 : require_message.message`${valueParser.format(defaultValue)}`,
1080
1081
  choices: choicesMessage
1081
1082
  }];
1082
- return {
1083
+ return require_command_doc_metadata.withCommandDocMetadata({
1083
1084
  fragments,
1084
1085
  description: options.description
1085
- };
1086
+ }, {});
1086
1087
  },
1087
1088
  [Symbol.for("Deno.customInspect")]() {
1088
1089
  return `argument()`;
@@ -1392,11 +1393,11 @@ function command(name, parser, options = {}) {
1392
1393
  getDocFragments(state, defaultValue) {
1393
1394
  const commandState = state.kind === "available" ? normalizeCommandState(state.state) : void 0;
1394
1395
  if (state.kind === "unavailable" || typeof commandState === "undefined") {
1395
- if (require_usage.isDocHidden(options.hidden)) return {
1396
+ if (require_usage.isDocHidden(options.hidden)) return require_command_doc_metadata.withCommandDocMetadata({
1396
1397
  fragments: [],
1397
1398
  description: options.description
1398
- };
1399
- return {
1399
+ }, {});
1400
+ return require_command_doc_metadata.withCommandDocMetadata({
1400
1401
  description: options.description,
1401
1402
  fragments: [{
1402
1403
  type: "entry",
@@ -1406,7 +1407,7 @@ function command(name, parser, options = {}) {
1406
1407
  },
1407
1408
  description: options.brief ?? options.description
1408
1409
  }]
1409
- };
1410
+ }, {});
1410
1411
  }
1411
1412
  const innerState = commandState[0] === "parsing" ? {
1412
1413
  kind: "available",
@@ -1416,12 +1417,18 @@ function command(name, parser, options = {}) {
1416
1417
  state: getCommandChildState(state.state, parser.initialState, parser)
1417
1418
  };
1418
1419
  const innerFragments = parser.getDocFragments(innerState, defaultValue);
1419
- return {
1420
+ const innerMetadata = require_command_doc_metadata.getCommandDocMetadata(innerFragments) ?? innerFragments;
1421
+ return require_command_doc_metadata.withCommandDocMetadata({
1420
1422
  ...innerFragments,
1421
1423
  brief: innerFragments.brief ?? options.brief,
1422
1424
  description: innerFragments.description ?? options.description,
1423
1425
  footer: innerFragments.footer ?? options.footer
1424
- };
1426
+ }, {
1427
+ origin: "command",
1428
+ brief: innerMetadata?.brief ?? options.brief,
1429
+ description: innerMetadata?.description ?? options.description,
1430
+ footer: innerMetadata?.footer ?? options.footer
1431
+ });
1425
1432
  },
1426
1433
  [Symbol.for("Deno.customInspect")]() {
1427
1434
  return `command(${JSON.stringify(name)})`;
@@ -1619,18 +1626,18 @@ function passThrough(options = {}) {
1619
1626
  return [];
1620
1627
  },
1621
1628
  getDocFragments(_state, _defaultValue) {
1622
- if (require_usage.isDocHidden(options.hidden)) return {
1629
+ if (require_usage.isDocHidden(options.hidden)) return require_command_doc_metadata.withCommandDocMetadata({
1623
1630
  fragments: [],
1624
1631
  description: options.description
1625
- };
1626
- return {
1632
+ }, {});
1633
+ return require_command_doc_metadata.withCommandDocMetadata({
1627
1634
  fragments: [{
1628
1635
  type: "entry",
1629
1636
  term: { type: "passthrough" },
1630
1637
  description: options.description
1631
1638
  }],
1632
1639
  description: options.description
1633
- };
1640
+ }, {});
1634
1641
  },
1635
1642
  [Symbol.for("Deno.customInspect")]() {
1636
1643
  return `passThrough(${format})`;
@@ -1,5 +1,6 @@
1
1
  import { annotateFreshArray, getAnnotations } from "./internal/annotations.js";
2
2
  import { message, metavar, optionName, optionNames, text, valueSet } from "./message.js";
3
+ import { getCommandDocMetadata, withCommandDocMetadata } from "./internal/command-doc-metadata.js";
3
4
  import { defineKnownCompletion, defineOptionMatch, definePassThroughPriority, getOptionMatch, getPassThroughFailure, getPassThroughPriority } from "./internal/passthrough.js";
4
5
  import { validateCommandNames, validateOptionNames } from "./validate.js";
5
6
  import { extractOptionNames, isDocHidden, isSuggestionHidden } from "./usage.js";
@@ -626,10 +627,10 @@ function option(...args) {
626
627
  return suggestOptionSync(optionNames$1, valueParser, isSuggestionHidden(options.hidden), options.description, context, prefix);
627
628
  },
628
629
  getDocFragments(_state, defaultValue) {
629
- if (isDocHidden(options.hidden)) return {
630
+ if (isDocHidden(options.hidden)) return withCommandDocMetadata({
630
631
  fragments: [],
631
632
  description: options.description
632
- };
633
+ }, {});
633
634
  const choicesMessage = valueParser?.choices != null && valueParser.choices.length > 0 ? valueSet(valueParser.choices.map((c) => valueParser.format(c)), {
634
635
  fallback: "",
635
636
  type: "unit"
@@ -645,10 +646,10 @@ function option(...args) {
645
646
  default: defaultValue != null && valueParser != null ? message`${valueParser.format(defaultValue)}` : void 0,
646
647
  choices: choicesMessage
647
648
  }];
648
- return {
649
+ return withCommandDocMetadata({
649
650
  fragments,
650
651
  description: options.description
651
- };
652
+ }, {});
652
653
  },
653
654
  [Symbol.for("Deno.customInspect")]() {
654
655
  return `option(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
@@ -913,10 +914,10 @@ function flag(...args) {
913
914
  return suggestions;
914
915
  },
915
916
  getDocFragments(_state, _defaultValue) {
916
- if (isDocHidden(options.hidden)) return {
917
+ if (isDocHidden(options.hidden)) return withCommandDocMetadata({
917
918
  fragments: [],
918
919
  description: options.description
919
- };
920
+ }, {});
920
921
  const fragments = [{
921
922
  type: "entry",
922
923
  term: {
@@ -925,10 +926,10 @@ function flag(...args) {
925
926
  },
926
927
  description: options.description
927
928
  }];
928
- return {
929
+ return withCommandDocMetadata({
929
930
  fragments,
930
931
  description: options.description
931
- };
932
+ }, {});
932
933
  },
933
934
  [Symbol.for("Deno.customInspect")]() {
934
935
  return `flag(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
@@ -1064,10 +1065,10 @@ function argument(valueParser, options = {}) {
1064
1065
  return suggestArgumentSync(valueParser, isSuggestionHidden(options.hidden), prefix, context.dependencyRegistry, context.exec);
1065
1066
  },
1066
1067
  getDocFragments(_state, defaultValue) {
1067
- if (isDocHidden(options.hidden)) return {
1068
+ if (isDocHidden(options.hidden)) return withCommandDocMetadata({
1068
1069
  fragments: [],
1069
1070
  description: options.description
1070
- };
1071
+ }, {});
1071
1072
  const choicesMessage = valueParser.choices != null && valueParser.choices.length > 0 ? valueSet(valueParser.choices.map((c) => valueParser.format(c)), {
1072
1073
  fallback: "",
1073
1074
  type: "unit"
@@ -1079,10 +1080,10 @@ function argument(valueParser, options = {}) {
1079
1080
  default: defaultValue == null ? void 0 : message`${valueParser.format(defaultValue)}`,
1080
1081
  choices: choicesMessage
1081
1082
  }];
1082
- return {
1083
+ return withCommandDocMetadata({
1083
1084
  fragments,
1084
1085
  description: options.description
1085
- };
1086
+ }, {});
1086
1087
  },
1087
1088
  [Symbol.for("Deno.customInspect")]() {
1088
1089
  return `argument()`;
@@ -1392,11 +1393,11 @@ function command(name, parser, options = {}) {
1392
1393
  getDocFragments(state, defaultValue) {
1393
1394
  const commandState = state.kind === "available" ? normalizeCommandState(state.state) : void 0;
1394
1395
  if (state.kind === "unavailable" || typeof commandState === "undefined") {
1395
- if (isDocHidden(options.hidden)) return {
1396
+ if (isDocHidden(options.hidden)) return withCommandDocMetadata({
1396
1397
  fragments: [],
1397
1398
  description: options.description
1398
- };
1399
- return {
1399
+ }, {});
1400
+ return withCommandDocMetadata({
1400
1401
  description: options.description,
1401
1402
  fragments: [{
1402
1403
  type: "entry",
@@ -1406,7 +1407,7 @@ function command(name, parser, options = {}) {
1406
1407
  },
1407
1408
  description: options.brief ?? options.description
1408
1409
  }]
1409
- };
1410
+ }, {});
1410
1411
  }
1411
1412
  const innerState = commandState[0] === "parsing" ? {
1412
1413
  kind: "available",
@@ -1416,12 +1417,18 @@ function command(name, parser, options = {}) {
1416
1417
  state: getCommandChildState(state.state, parser.initialState, parser)
1417
1418
  };
1418
1419
  const innerFragments = parser.getDocFragments(innerState, defaultValue);
1419
- return {
1420
+ const innerMetadata = getCommandDocMetadata(innerFragments) ?? innerFragments;
1421
+ return withCommandDocMetadata({
1420
1422
  ...innerFragments,
1421
1423
  brief: innerFragments.brief ?? options.brief,
1422
1424
  description: innerFragments.description ?? options.description,
1423
1425
  footer: innerFragments.footer ?? options.footer
1424
- };
1426
+ }, {
1427
+ origin: "command",
1428
+ brief: innerMetadata?.brief ?? options.brief,
1429
+ description: innerMetadata?.description ?? options.description,
1430
+ footer: innerMetadata?.footer ?? options.footer
1431
+ });
1425
1432
  },
1426
1433
  [Symbol.for("Deno.customInspect")]() {
1427
1434
  return `command(${JSON.stringify(name)})`;
@@ -1619,18 +1626,18 @@ function passThrough(options = {}) {
1619
1626
  return [];
1620
1627
  },
1621
1628
  getDocFragments(_state, _defaultValue) {
1622
- if (isDocHidden(options.hidden)) return {
1629
+ if (isDocHidden(options.hidden)) return withCommandDocMetadata({
1623
1630
  fragments: [],
1624
1631
  description: options.description
1625
- };
1626
- return {
1632
+ }, {});
1633
+ return withCommandDocMetadata({
1627
1634
  fragments: [{
1628
1635
  type: "entry",
1629
1636
  term: { type: "passthrough" },
1630
1637
  description: options.description
1631
1638
  }],
1632
1639
  description: options.description
1633
- };
1640
+ }, {});
1634
1641
  },
1635
1642
  [Symbol.for("Deno.customInspect")]() {
1636
1643
  return `passThrough(${format})`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.12-dev.2703",
3
+ "version": "1.0.13-dev.2743",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",