@optique/core 1.0.0-dev.1326 → 1.0.0-dev.1344

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.
@@ -3,6 +3,7 @@ const require_message = require('./message.cjs');
3
3
  const require_dependency = require('./dependency.cjs');
4
4
  const require_mode_dispatch = require('./mode-dispatch.cjs');
5
5
  const require_usage = require('./usage.cjs');
6
+ const require_doc = require('./doc.cjs');
6
7
  const require_suggestion = require('./suggestion.cjs');
7
8
  const require_usage_internals = require('./usage-internals.cjs');
8
9
 
@@ -145,6 +146,19 @@ function extractRequiredUsage(usage) {
145
146
  return required;
146
147
  }
147
148
  /**
149
+ * Validates that every element of the given array is a {@link Parser} object.
150
+ * @param parsers The array of values to validate.
151
+ * @param callerName The name of the calling function, used in error messages.
152
+ * @throws {TypeError} If any element is not a valid {@link Parser}.
153
+ */
154
+ function assertParsers(parsers, callerName) {
155
+ for (let i = 0; i < parsers.length; i++) {
156
+ const p = parsers[i];
157
+ const r = p;
158
+ if (p == null || typeof p !== "object" && typeof p !== "function" || !(r.$mode === "sync" || r.$mode === "async") || !Array.isArray(r.usage) || typeof r.priority !== "number" || Number.isNaN(r.priority) || !("initialState" in p) || typeof r.parse !== "function" || typeof r.complete !== "function" || typeof r.suggest !== "function" || typeof r.getDocFragments !== "function") throw new TypeError(`${callerName} argument at index ${i} is not a valid Parser.`);
159
+ }
160
+ }
161
+ /**
148
162
  * Analyzes parsers to determine what types of inputs are expected.
149
163
  * @param parsers The parsers being combined
150
164
  * @returns Context about what types of inputs are expected
@@ -305,6 +319,7 @@ function or(...args) {
305
319
  options = void 0;
306
320
  }
307
321
  if (parsers.length < 1) throw new TypeError("or() requires at least one parser argument.");
322
+ assertParsers(parsers, "or()");
308
323
  const noMatchContext = analyzeNoMatchContext(parsers);
309
324
  const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
310
325
  const syncParsers = parsers;
@@ -471,24 +486,12 @@ function or(...args) {
471
486
  footer = docFragments.footer;
472
487
  fragments = docFragments.fragments;
473
488
  }
474
- const entries = fragments.filter((f) => f.type === "entry");
475
- const sections = [];
476
- for (const fragment of fragments) {
477
- if (fragment.type !== "section") continue;
478
- if (fragment.title == null) entries.push(...fragment.entries);
479
- else sections.push(fragment);
480
- }
489
+ if (state.kind === "unavailable" || state.state == null) fragments = require_doc.deduplicateDocFragments(fragments);
481
490
  return {
482
491
  brief,
483
492
  description,
484
493
  footer,
485
- fragments: [...sections.map((s) => ({
486
- ...s,
487
- type: "section"
488
- })), {
489
- type: "section",
490
- entries
491
- }]
494
+ fragments
492
495
  };
493
496
  }
494
497
  };
@@ -507,6 +510,7 @@ function longestMatch(...args) {
507
510
  options = void 0;
508
511
  }
509
512
  if (parsers.length < 1) throw new TypeError("longestMatch() requires at least one parser argument.");
513
+ assertParsers(parsers, "longestMatch()");
510
514
  const noMatchContext = analyzeNoMatchContext(parsers);
511
515
  const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
512
516
  const syncParsers = parsers;
@@ -606,8 +610,11 @@ function longestMatch(...args) {
606
610
  let description;
607
611
  let footer;
608
612
  let fragments;
609
- if (state.kind === "unavailable" || state.state == null) fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
610
- else {
613
+ let shouldDeduplicate;
614
+ if (state.kind === "unavailable" || state.state == null) {
615
+ fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
616
+ shouldDeduplicate = true;
617
+ } else {
611
618
  const [i, result] = state.state;
612
619
  if (result.success) {
613
620
  const docResult = parsers[i].getDocFragments({
@@ -618,12 +625,16 @@ function longestMatch(...args) {
618
625
  description = docResult.description;
619
626
  footer = docResult.footer;
620
627
  fragments = docResult.fragments;
621
- } else fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
628
+ shouldDeduplicate = false;
629
+ } else {
630
+ fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
631
+ shouldDeduplicate = true;
632
+ }
622
633
  }
623
634
  return {
624
635
  brief,
625
636
  description,
626
- fragments,
637
+ fragments: shouldDeduplicate ? require_doc.deduplicateDocFragments(fragments) : fragments,
627
638
  footer
628
639
  };
629
640
  }
@@ -1659,6 +1670,7 @@ function merge(...args) {
1659
1670
  const endIndex = hasOptions ? args.length - 1 : args.length;
1660
1671
  const rawParsers = args.slice(startIndex, endIndex);
1661
1672
  if (rawParsers.length < 1) throw new TypeError("merge() requires at least one parser argument.");
1673
+ assertParsers(rawParsers, "merge()");
1662
1674
  const combinedMode = rawParsers.some((p) => p.$mode === "async") ? "async" : "sync";
1663
1675
  const isAsync = combinedMode === "async";
1664
1676
  const syncRawParsers = rawParsers;
@@ -2102,6 +2114,7 @@ function tryParseSuggestList(context, stateArray, parsers, matchedParsers, remai
2102
2114
  }
2103
2115
  function concat(...parsers) {
2104
2116
  if (parsers.length < 1) throw new TypeError("concat() requires at least one parser argument.");
2117
+ assertParsers(parsers, "concat()");
2105
2118
  const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
2106
2119
  const isAsync = combinedMode === "async";
2107
2120
  const syncParsers = parsers;
@@ -3,6 +3,7 @@ import { message, optionName, text, values } from "./message.js";
3
3
  import { DependencyRegistry, createDependencySourceState, dependencyId, isDeferredParseState, isDependencySourceState, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, wrappedDependencySourceMarker } from "./dependency.js";
4
4
  import { dispatchByMode, dispatchIterableByMode } from "./mode-dispatch.js";
5
5
  import { extractArgumentMetavars, extractCommandNames, extractOptionNames, isDocHidden, mergeHidden } from "./usage.js";
6
+ import { deduplicateDocFragments } from "./doc.js";
6
7
  import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, findSimilar } from "./suggestion.js";
7
8
  import { collectLeadingCandidates } from "./usage-internals.js";
8
9
 
@@ -145,6 +146,19 @@ function extractRequiredUsage(usage) {
145
146
  return required;
146
147
  }
147
148
  /**
149
+ * Validates that every element of the given array is a {@link Parser} object.
150
+ * @param parsers The array of values to validate.
151
+ * @param callerName The name of the calling function, used in error messages.
152
+ * @throws {TypeError} If any element is not a valid {@link Parser}.
153
+ */
154
+ function assertParsers(parsers, callerName) {
155
+ for (let i = 0; i < parsers.length; i++) {
156
+ const p = parsers[i];
157
+ const r = p;
158
+ if (p == null || typeof p !== "object" && typeof p !== "function" || !(r.$mode === "sync" || r.$mode === "async") || !Array.isArray(r.usage) || typeof r.priority !== "number" || Number.isNaN(r.priority) || !("initialState" in p) || typeof r.parse !== "function" || typeof r.complete !== "function" || typeof r.suggest !== "function" || typeof r.getDocFragments !== "function") throw new TypeError(`${callerName} argument at index ${i} is not a valid Parser.`);
159
+ }
160
+ }
161
+ /**
148
162
  * Analyzes parsers to determine what types of inputs are expected.
149
163
  * @param parsers The parsers being combined
150
164
  * @returns Context about what types of inputs are expected
@@ -305,6 +319,7 @@ function or(...args) {
305
319
  options = void 0;
306
320
  }
307
321
  if (parsers.length < 1) throw new TypeError("or() requires at least one parser argument.");
322
+ assertParsers(parsers, "or()");
308
323
  const noMatchContext = analyzeNoMatchContext(parsers);
309
324
  const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
310
325
  const syncParsers = parsers;
@@ -471,24 +486,12 @@ function or(...args) {
471
486
  footer = docFragments.footer;
472
487
  fragments = docFragments.fragments;
473
488
  }
474
- const entries = fragments.filter((f) => f.type === "entry");
475
- const sections = [];
476
- for (const fragment of fragments) {
477
- if (fragment.type !== "section") continue;
478
- if (fragment.title == null) entries.push(...fragment.entries);
479
- else sections.push(fragment);
480
- }
489
+ if (state.kind === "unavailable" || state.state == null) fragments = deduplicateDocFragments(fragments);
481
490
  return {
482
491
  brief,
483
492
  description,
484
493
  footer,
485
- fragments: [...sections.map((s) => ({
486
- ...s,
487
- type: "section"
488
- })), {
489
- type: "section",
490
- entries
491
- }]
494
+ fragments
492
495
  };
493
496
  }
494
497
  };
@@ -507,6 +510,7 @@ function longestMatch(...args) {
507
510
  options = void 0;
508
511
  }
509
512
  if (parsers.length < 1) throw new TypeError("longestMatch() requires at least one parser argument.");
513
+ assertParsers(parsers, "longestMatch()");
510
514
  const noMatchContext = analyzeNoMatchContext(parsers);
511
515
  const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
512
516
  const syncParsers = parsers;
@@ -606,8 +610,11 @@ function longestMatch(...args) {
606
610
  let description;
607
611
  let footer;
608
612
  let fragments;
609
- if (state.kind === "unavailable" || state.state == null) fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
610
- else {
613
+ let shouldDeduplicate;
614
+ if (state.kind === "unavailable" || state.state == null) {
615
+ fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
616
+ shouldDeduplicate = true;
617
+ } else {
611
618
  const [i, result] = state.state;
612
619
  if (result.success) {
613
620
  const docResult = parsers[i].getDocFragments({
@@ -618,12 +625,16 @@ function longestMatch(...args) {
618
625
  description = docResult.description;
619
626
  footer = docResult.footer;
620
627
  fragments = docResult.fragments;
621
- } else fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
628
+ shouldDeduplicate = false;
629
+ } else {
630
+ fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
631
+ shouldDeduplicate = true;
632
+ }
622
633
  }
623
634
  return {
624
635
  brief,
625
636
  description,
626
- fragments,
637
+ fragments: shouldDeduplicate ? deduplicateDocFragments(fragments) : fragments,
627
638
  footer
628
639
  };
629
640
  }
@@ -1659,6 +1670,7 @@ function merge(...args) {
1659
1670
  const endIndex = hasOptions ? args.length - 1 : args.length;
1660
1671
  const rawParsers = args.slice(startIndex, endIndex);
1661
1672
  if (rawParsers.length < 1) throw new TypeError("merge() requires at least one parser argument.");
1673
+ assertParsers(rawParsers, "merge()");
1662
1674
  const combinedMode = rawParsers.some((p) => p.$mode === "async") ? "async" : "sync";
1663
1675
  const isAsync = combinedMode === "async";
1664
1676
  const syncRawParsers = rawParsers;
@@ -2102,6 +2114,7 @@ function tryParseSuggestList(context, stateArray, parsers, matchedParsers, remai
2102
2114
  }
2103
2115
  function concat(...parsers) {
2104
2116
  if (parsers.length < 1) throw new TypeError("concat() requires at least one parser argument.");
2117
+ assertParsers(parsers, "concat()");
2105
2118
  const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
2106
2119
  const isAsync = combinedMode === "async";
2107
2120
  const syncParsers = parsers;
package/dist/doc.cjs CHANGED
@@ -2,6 +2,101 @@ const require_message = require('./message.cjs');
2
2
  const require_usage = require('./usage.cjs');
3
3
 
4
4
  //#region src/doc.ts
5
+ function getDocEntryKey(entry) {
6
+ const term = entry.term;
7
+ switch (term.type) {
8
+ case "command": return `command:${term.name}`;
9
+ case "option": return `option:${[...term.names].sort().join(",")}:${term.metavar ?? ""}`;
10
+ case "argument": return `argument:${term.metavar}`;
11
+ default: return JSON.stringify(term);
12
+ }
13
+ }
14
+ /**
15
+ * Removes duplicate {@link DocEntry} values that share the same surface
16
+ * syntax (same term type and identifying names). When duplicates exist,
17
+ * the first occurrence is kept and later ones are discarded.
18
+ *
19
+ * Positional argument entries are never deduplicated because they are
20
+ * distinguished by position, not by metavar, and {@link DocEntry} does
21
+ * not carry position information.
22
+ *
23
+ * @param entries The entries to deduplicate.
24
+ * @returns A new array with duplicates removed, preserving insertion order.
25
+ * @since 1.0.0
26
+ */
27
+ function deduplicateDocEntries(entries) {
28
+ const seen = /* @__PURE__ */ new Set();
29
+ const result = [];
30
+ for (const entry of entries) {
31
+ if (entry.term.type === "argument") {
32
+ result.push(entry);
33
+ continue;
34
+ }
35
+ const key = getDocEntryKey(entry);
36
+ if (!seen.has(key)) {
37
+ seen.add(key);
38
+ result.push(entry);
39
+ }
40
+ }
41
+ return result;
42
+ }
43
+ /**
44
+ * Removes duplicate entries from a list of {@link DocFragment} values.
45
+ * Entry-type fragments are deduplicated by their surface syntax key.
46
+ * Section-type fragments have their entries deduplicated internally.
47
+ *
48
+ * @param fragments The fragments to deduplicate.
49
+ * @returns A new array with duplicate entries removed.
50
+ * @since 1.0.0
51
+ */
52
+ function deduplicateDocFragments(fragments) {
53
+ const untitledSeen = /* @__PURE__ */ new Set();
54
+ const titledSectionMap = /* @__PURE__ */ new Map();
55
+ const slots = [];
56
+ for (const fragment of fragments) if (fragment.type === "entry") if (fragment.term.type === "argument") slots.push(fragment);
57
+ else {
58
+ const key = getDocEntryKey(fragment);
59
+ if (!untitledSeen.has(key)) {
60
+ untitledSeen.add(key);
61
+ slots.push(fragment);
62
+ }
63
+ }
64
+ else if (fragment.title == null) {
65
+ const dedupedEntries = [];
66
+ for (const entry of fragment.entries) {
67
+ if (entry.term.type === "argument") {
68
+ dedupedEntries.push(entry);
69
+ continue;
70
+ }
71
+ const key = getDocEntryKey(entry);
72
+ if (!untitledSeen.has(key)) {
73
+ untitledSeen.add(key);
74
+ dedupedEntries.push(entry);
75
+ }
76
+ }
77
+ if (dedupedEntries.length > 0) slots.push({
78
+ ...fragment,
79
+ type: "section",
80
+ entries: dedupedEntries
81
+ });
82
+ } else {
83
+ if (!titledSectionMap.has(fragment.title)) {
84
+ titledSectionMap.set(fragment.title, []);
85
+ slots.push(fragment.title);
86
+ }
87
+ titledSectionMap.get(fragment.title).push(...fragment.entries);
88
+ }
89
+ const result = [];
90
+ for (const slot of slots) if (typeof slot === "string") {
91
+ const entries = deduplicateDocEntries(titledSectionMap.get(slot));
92
+ if (entries.length > 0) result.push({
93
+ type: "section",
94
+ title: slot,
95
+ entries
96
+ });
97
+ } else result.push(slot);
98
+ return result;
99
+ }
5
100
  /**
6
101
  * Creates a deep clone of a {@link DocEntry}. The `term` is cloned via
7
102
  * {@link cloneUsageTerm}, and `description`, `default`, and `choices`
@@ -345,4 +440,6 @@ function lastLineVisibleLength(text$1) {
345
440
 
346
441
  //#endregion
347
442
  exports.cloneDocEntry = cloneDocEntry;
443
+ exports.deduplicateDocEntries = deduplicateDocEntries;
444
+ exports.deduplicateDocFragments = deduplicateDocFragments;
348
445
  exports.formatDocPage = formatDocPage;
package/dist/doc.d.cts CHANGED
@@ -103,6 +103,30 @@ interface DocFragments {
103
103
  */
104
104
  readonly footer?: Message;
105
105
  }
106
+ /**
107
+ * Removes duplicate {@link DocEntry} values that share the same surface
108
+ * syntax (same term type and identifying names). When duplicates exist,
109
+ * the first occurrence is kept and later ones are discarded.
110
+ *
111
+ * Positional argument entries are never deduplicated because they are
112
+ * distinguished by position, not by metavar, and {@link DocEntry} does
113
+ * not carry position information.
114
+ *
115
+ * @param entries The entries to deduplicate.
116
+ * @returns A new array with duplicates removed, preserving insertion order.
117
+ * @since 1.0.0
118
+ */
119
+ declare function deduplicateDocEntries(entries: readonly DocEntry[]): DocEntry[];
120
+ /**
121
+ * Removes duplicate entries from a list of {@link DocFragment} values.
122
+ * Entry-type fragments are deduplicated by their surface syntax key.
123
+ * Section-type fragments have their entries deduplicated internally.
124
+ *
125
+ * @param fragments The fragments to deduplicate.
126
+ * @returns A new array with duplicate entries removed.
127
+ * @since 1.0.0
128
+ */
129
+ declare function deduplicateDocFragments(fragments: readonly DocFragment[]): DocFragment[];
106
130
  /**
107
131
  * Creates a deep clone of a {@link DocEntry}. The `term` is cloned via
108
132
  * {@link cloneUsageTerm}, and `description`, `default`, and `choices`
@@ -301,4 +325,4 @@ interface DocPageFormatOptions {
301
325
  */
302
326
  declare function formatDocPage(programName: string, page: DocPage, options?: DocPageFormatOptions): string;
303
327
  //#endregion
304
- export { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowChoicesOptions, ShowDefaultOptions, cloneDocEntry, formatDocPage };
328
+ export { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowChoicesOptions, ShowDefaultOptions, cloneDocEntry, deduplicateDocEntries, deduplicateDocFragments, formatDocPage };
package/dist/doc.d.ts CHANGED
@@ -103,6 +103,30 @@ interface DocFragments {
103
103
  */
104
104
  readonly footer?: Message;
105
105
  }
106
+ /**
107
+ * Removes duplicate {@link DocEntry} values that share the same surface
108
+ * syntax (same term type and identifying names). When duplicates exist,
109
+ * the first occurrence is kept and later ones are discarded.
110
+ *
111
+ * Positional argument entries are never deduplicated because they are
112
+ * distinguished by position, not by metavar, and {@link DocEntry} does
113
+ * not carry position information.
114
+ *
115
+ * @param entries The entries to deduplicate.
116
+ * @returns A new array with duplicates removed, preserving insertion order.
117
+ * @since 1.0.0
118
+ */
119
+ declare function deduplicateDocEntries(entries: readonly DocEntry[]): DocEntry[];
120
+ /**
121
+ * Removes duplicate entries from a list of {@link DocFragment} values.
122
+ * Entry-type fragments are deduplicated by their surface syntax key.
123
+ * Section-type fragments have their entries deduplicated internally.
124
+ *
125
+ * @param fragments The fragments to deduplicate.
126
+ * @returns A new array with duplicate entries removed.
127
+ * @since 1.0.0
128
+ */
129
+ declare function deduplicateDocFragments(fragments: readonly DocFragment[]): DocFragment[];
106
130
  /**
107
131
  * Creates a deep clone of a {@link DocEntry}. The `term` is cloned via
108
132
  * {@link cloneUsageTerm}, and `description`, `default`, and `choices`
@@ -301,4 +325,4 @@ interface DocPageFormatOptions {
301
325
  */
302
326
  declare function formatDocPage(programName: string, page: DocPage, options?: DocPageFormatOptions): string;
303
327
  //#endregion
304
- export { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowChoicesOptions, ShowDefaultOptions, cloneDocEntry, formatDocPage };
328
+ export { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowChoicesOptions, ShowDefaultOptions, cloneDocEntry, deduplicateDocEntries, deduplicateDocFragments, formatDocPage };
package/dist/doc.js CHANGED
@@ -2,6 +2,101 @@ import { cloneMessage, formatMessage, text } from "./message.js";
2
2
  import { cloneUsageTerm, formatUsage, formatUsageTerm } from "./usage.js";
3
3
 
4
4
  //#region src/doc.ts
5
+ function getDocEntryKey(entry) {
6
+ const term = entry.term;
7
+ switch (term.type) {
8
+ case "command": return `command:${term.name}`;
9
+ case "option": return `option:${[...term.names].sort().join(",")}:${term.metavar ?? ""}`;
10
+ case "argument": return `argument:${term.metavar}`;
11
+ default: return JSON.stringify(term);
12
+ }
13
+ }
14
+ /**
15
+ * Removes duplicate {@link DocEntry} values that share the same surface
16
+ * syntax (same term type and identifying names). When duplicates exist,
17
+ * the first occurrence is kept and later ones are discarded.
18
+ *
19
+ * Positional argument entries are never deduplicated because they are
20
+ * distinguished by position, not by metavar, and {@link DocEntry} does
21
+ * not carry position information.
22
+ *
23
+ * @param entries The entries to deduplicate.
24
+ * @returns A new array with duplicates removed, preserving insertion order.
25
+ * @since 1.0.0
26
+ */
27
+ function deduplicateDocEntries(entries) {
28
+ const seen = /* @__PURE__ */ new Set();
29
+ const result = [];
30
+ for (const entry of entries) {
31
+ if (entry.term.type === "argument") {
32
+ result.push(entry);
33
+ continue;
34
+ }
35
+ const key = getDocEntryKey(entry);
36
+ if (!seen.has(key)) {
37
+ seen.add(key);
38
+ result.push(entry);
39
+ }
40
+ }
41
+ return result;
42
+ }
43
+ /**
44
+ * Removes duplicate entries from a list of {@link DocFragment} values.
45
+ * Entry-type fragments are deduplicated by their surface syntax key.
46
+ * Section-type fragments have their entries deduplicated internally.
47
+ *
48
+ * @param fragments The fragments to deduplicate.
49
+ * @returns A new array with duplicate entries removed.
50
+ * @since 1.0.0
51
+ */
52
+ function deduplicateDocFragments(fragments) {
53
+ const untitledSeen = /* @__PURE__ */ new Set();
54
+ const titledSectionMap = /* @__PURE__ */ new Map();
55
+ const slots = [];
56
+ for (const fragment of fragments) if (fragment.type === "entry") if (fragment.term.type === "argument") slots.push(fragment);
57
+ else {
58
+ const key = getDocEntryKey(fragment);
59
+ if (!untitledSeen.has(key)) {
60
+ untitledSeen.add(key);
61
+ slots.push(fragment);
62
+ }
63
+ }
64
+ else if (fragment.title == null) {
65
+ const dedupedEntries = [];
66
+ for (const entry of fragment.entries) {
67
+ if (entry.term.type === "argument") {
68
+ dedupedEntries.push(entry);
69
+ continue;
70
+ }
71
+ const key = getDocEntryKey(entry);
72
+ if (!untitledSeen.has(key)) {
73
+ untitledSeen.add(key);
74
+ dedupedEntries.push(entry);
75
+ }
76
+ }
77
+ if (dedupedEntries.length > 0) slots.push({
78
+ ...fragment,
79
+ type: "section",
80
+ entries: dedupedEntries
81
+ });
82
+ } else {
83
+ if (!titledSectionMap.has(fragment.title)) {
84
+ titledSectionMap.set(fragment.title, []);
85
+ slots.push(fragment.title);
86
+ }
87
+ titledSectionMap.get(fragment.title).push(...fragment.entries);
88
+ }
89
+ const result = [];
90
+ for (const slot of slots) if (typeof slot === "string") {
91
+ const entries = deduplicateDocEntries(titledSectionMap.get(slot));
92
+ if (entries.length > 0) result.push({
93
+ type: "section",
94
+ title: slot,
95
+ entries
96
+ });
97
+ } else result.push(slot);
98
+ return result;
99
+ }
5
100
  /**
6
101
  * Creates a deep clone of a {@link DocEntry}. The `term` is cloned via
7
102
  * {@link cloneUsageTerm}, and `description`, `default`, and `choices`
@@ -344,4 +439,4 @@ function lastLineVisibleLength(text$1) {
344
439
  }
345
440
 
346
441
  //#endregion
347
- export { cloneDocEntry, formatDocPage };
442
+ export { cloneDocEntry, deduplicateDocEntries, deduplicateDocFragments, formatDocPage };
package/dist/facade.cjs CHANGED
@@ -3,9 +3,9 @@ const require_message = require('./message.cjs');
3
3
  const require_completion = require('./completion.cjs');
4
4
  const require_mode_dispatch = require('./mode-dispatch.cjs');
5
5
  const require_usage = require('./usage.cjs');
6
+ const require_doc = require('./doc.cjs');
6
7
  const require_constructs = require('./constructs.cjs');
7
8
  const require_context = require('./context.cjs');
8
- const require_doc = require('./doc.cjs');
9
9
  const require_modifiers = require('./modifiers.cjs');
10
10
  const require_valueparser = require('./valueparser.cjs');
11
11
  const require_primitives = require('./primitives.cjs');
package/dist/facade.js CHANGED
@@ -3,9 +3,9 @@ import { commandLine, formatMessage, lineBreak, message, optionName, text, value
3
3
  import { bash, fish, nu, pwsh, zsh } from "./completion.js";
4
4
  import { dispatchByMode } from "./mode-dispatch.js";
5
5
  import { formatUsage } from "./usage.js";
6
+ import { formatDocPage } from "./doc.js";
6
7
  import { group, longestMatch, object } from "./constructs.js";
7
8
  import { isPlaceholderValue } from "./context.js";
8
- import { formatDocPage } from "./doc.js";
9
9
  import { multiple, optional, withDefault } from "./modifiers.js";
10
10
  import { string } from "./valueparser.js";
11
11
  import { argument, command, constant, flag, option } from "./primitives.js";
package/dist/index.cjs CHANGED
@@ -3,8 +3,8 @@ const require_message = require('./message.cjs');
3
3
  const require_completion = require('./completion.cjs');
4
4
  const require_dependency = require('./dependency.cjs');
5
5
  const require_usage = require('./usage.cjs');
6
- const require_constructs = require('./constructs.cjs');
7
6
  const require_doc = require('./doc.cjs');
7
+ const require_constructs = require('./constructs.cjs');
8
8
  const require_modifiers = require('./modifiers.cjs');
9
9
  const require_nonempty = require('./nonempty.cjs');
10
10
  const require_valueparser = require('./valueparser.cjs');
@@ -34,6 +34,8 @@ exports.constant = require_primitives.constant;
34
34
  exports.createDeferredParseState = require_dependency.createDeferredParseState;
35
35
  exports.createDependencySourceState = require_dependency.createDependencySourceState;
36
36
  exports.createPendingDependencySourceState = require_dependency.createPendingDependencySourceState;
37
+ exports.deduplicateDocEntries = require_doc.deduplicateDocEntries;
38
+ exports.deduplicateDocFragments = require_doc.deduplicateDocFragments;
37
39
  exports.defaultValues = require_dependency.defaultValues;
38
40
  exports.deferredParseMarker = require_dependency.deferredParseMarker;
39
41
  exports.dependency = require_dependency.dependency;
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@ import { Annotations, ParseOptions, annotationKey, getAnnotations } from "./anno
2
2
  import { NonEmptyString, ensureNonEmptyString, isNonEmptyString } from "./nonempty.cjs";
3
3
  import { Message, MessageFormatOptions, MessageTerm, ValueSetOptions, commandLine, envVar, formatMessage, lineBreak, link, message, metavar, optionName, optionNames, text, value, valueSet, values } from "./message.cjs";
4
4
  import { HiddenVisibility, OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, cloneUsage, cloneUsageTerm, extractArgumentMetavars, extractCommandNames, extractOptionNames, formatUsage, formatUsageTerm, isDocHidden, isSuggestionHidden, isUsageHidden, mergeHidden, normalizeUsage } from "./usage.cjs";
5
- import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowChoicesOptions, ShowDefaultOptions, cloneDocEntry, formatDocPage } from "./doc.cjs";
5
+ import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowChoicesOptions, ShowDefaultOptions, cloneDocEntry, deduplicateDocEntries, deduplicateDocFragments, formatDocPage } from "./doc.cjs";
6
6
  import { ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, DomainOptions, EmailOptions, FloatOptions, HostnameOptions, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, LocaleOptions, MacAddressOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, SocketAddressOptions, SocketAddressValue, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, checkBooleanOption, checkEnumOption, choice, cidr, domain, email, float, hostname, integer, ip, ipv4, ipv6, isValueParser, locale, macAddress, port, portRange, socketAddress, string, url, uuid } from "./valueparser.cjs";
7
7
  import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
8
8
  import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.cjs";
@@ -12,4 +12,4 @@ import { CombineModes, DocState, InferMode, InferValue, Mode, ModeIterable, Mode
12
12
  import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.cjs";
13
13
  import { ParserValuePlaceholder, SourceContext } from "./context.cjs";
14
14
  import { CommandSubConfig, ContextOptionsParam, ExtractRequiredOptions, OptionSubConfig, RunOptions, RunParserError, RunWithOptions, SubstituteParserValue, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync } from "./facade.cjs";
15
- export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredParseState, DependencyError, DependencyMode, DependencyRegistry, DependencySource, DependencySourceState, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExtractRequiredOptions, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PendingDependencySourceState, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, ResolvedDependency, Result, RunOptions, RunParserError, RunWithOptions, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, annotationKey, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, command, commandLine, concat, conditional, constant, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fail, fish, flag, float, formatDependencyError, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDefaultValuesFunction, getDependencyIds, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isDocHidden, isNonEmptyString, isPendingDependencySourceState, isSuggestionHidden, isUsageHidden, isValueParser, isWrappedDependencySource, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, parseWithDependency, passThrough, pendingDependencySourceStateMarker, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, socketAddress, string, suggest, suggestAsync, suggestSync, suggestWithDependency, text, transformsDependencyValue, transformsDependencyValueMarker, tuple, url, uuid, value, valueSet, values, withDefault, wrappedDependencySourceMarker, zsh };
15
+ export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredParseState, DependencyError, DependencyMode, DependencyRegistry, DependencySource, DependencySourceState, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExtractRequiredOptions, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PendingDependencySourceState, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, ResolvedDependency, Result, RunOptions, RunParserError, RunWithOptions, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, annotationKey, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, command, commandLine, concat, conditional, constant, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, deduplicateDocEntries, deduplicateDocFragments, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fail, fish, flag, float, formatDependencyError, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDefaultValuesFunction, getDependencyIds, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isDocHidden, isNonEmptyString, isPendingDependencySourceState, isSuggestionHidden, isUsageHidden, isValueParser, isWrappedDependencySource, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, parseWithDependency, passThrough, pendingDependencySourceStateMarker, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, socketAddress, string, suggest, suggestAsync, suggestSync, suggestWithDependency, text, transformsDependencyValue, transformsDependencyValueMarker, tuple, url, uuid, value, valueSet, values, withDefault, wrappedDependencySourceMarker, zsh };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Annotations, ParseOptions, annotationKey, getAnnotations } from "./anno
2
2
  import { NonEmptyString, ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
3
3
  import { Message, MessageFormatOptions, MessageTerm, ValueSetOptions, commandLine, envVar, formatMessage, lineBreak, link, message, metavar, optionName, optionNames, text, value, valueSet, values } from "./message.js";
4
4
  import { HiddenVisibility, OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, cloneUsage, cloneUsageTerm, extractArgumentMetavars, extractCommandNames, extractOptionNames, formatUsage, formatUsageTerm, isDocHidden, isSuggestionHidden, isUsageHidden, mergeHidden, normalizeUsage } from "./usage.js";
5
- import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowChoicesOptions, ShowDefaultOptions, cloneDocEntry, formatDocPage } from "./doc.js";
5
+ import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowChoicesOptions, ShowDefaultOptions, cloneDocEntry, deduplicateDocEntries, deduplicateDocFragments, formatDocPage } from "./doc.js";
6
6
  import { ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, DomainOptions, EmailOptions, FloatOptions, HostnameOptions, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, LocaleOptions, MacAddressOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, SocketAddressOptions, SocketAddressValue, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, checkBooleanOption, checkEnumOption, choice, cidr, domain, email, float, hostname, integer, ip, ipv4, ipv6, isValueParser, locale, macAddress, port, portRange, socketAddress, string, url, uuid } from "./valueparser.js";
7
7
  import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
8
8
  import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
@@ -12,4 +12,4 @@ import { CombineModes, DocState, InferMode, InferValue, Mode, ModeIterable, Mode
12
12
  import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.js";
13
13
  import { ParserValuePlaceholder, SourceContext } from "./context.js";
14
14
  import { CommandSubConfig, ContextOptionsParam, ExtractRequiredOptions, OptionSubConfig, RunOptions, RunParserError, RunWithOptions, SubstituteParserValue, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync } from "./facade.js";
15
- export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredParseState, DependencyError, DependencyMode, DependencyRegistry, DependencySource, DependencySourceState, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExtractRequiredOptions, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PendingDependencySourceState, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, ResolvedDependency, Result, RunOptions, RunParserError, RunWithOptions, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, annotationKey, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, command, commandLine, concat, conditional, constant, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fail, fish, flag, float, formatDependencyError, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDefaultValuesFunction, getDependencyIds, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isDocHidden, isNonEmptyString, isPendingDependencySourceState, isSuggestionHidden, isUsageHidden, isValueParser, isWrappedDependencySource, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, parseWithDependency, passThrough, pendingDependencySourceStateMarker, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, socketAddress, string, suggest, suggestAsync, suggestSync, suggestWithDependency, text, transformsDependencyValue, transformsDependencyValueMarker, tuple, url, uuid, value, valueSet, values, withDefault, wrappedDependencySourceMarker, zsh };
15
+ export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredParseState, DependencyError, DependencyMode, DependencyRegistry, DependencySource, DependencySourceState, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExtractRequiredOptions, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PendingDependencySourceState, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, ResolvedDependency, Result, RunOptions, RunParserError, RunWithOptions, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, annotationKey, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, command, commandLine, concat, conditional, constant, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, deduplicateDocEntries, deduplicateDocFragments, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fail, fish, flag, float, formatDependencyError, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDefaultValuesFunction, getDependencyIds, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isDocHidden, isNonEmptyString, isPendingDependencySourceState, isSuggestionHidden, isUsageHidden, isValueParser, isWrappedDependencySource, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, parseWithDependency, passThrough, pendingDependencySourceStateMarker, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, socketAddress, string, suggest, suggestAsync, suggestSync, suggestWithDependency, text, transformsDependencyValue, transformsDependencyValueMarker, tuple, url, uuid, value, valueSet, values, withDefault, wrappedDependencySourceMarker, zsh };
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@ import { commandLine, envVar, formatMessage, lineBreak, link, message, metavar,
3
3
  import { bash, fish, nu, pwsh, zsh } from "./completion.js";
4
4
  import { DependencyRegistry, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, formatDependencyError, getDefaultValuesFunction, getDependencyIds, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, pendingDependencySourceStateMarker, suggestWithDependency, transformsDependencyValue, transformsDependencyValueMarker, wrappedDependencySourceMarker } from "./dependency.js";
5
5
  import { cloneUsage, cloneUsageTerm, extractArgumentMetavars, extractCommandNames, extractOptionNames, formatUsage, formatUsageTerm, isDocHidden, isSuggestionHidden, isUsageHidden, mergeHidden, normalizeUsage } from "./usage.js";
6
+ import { cloneDocEntry, deduplicateDocEntries, deduplicateDocFragments, formatDocPage } from "./doc.js";
6
7
  import { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
7
- import { cloneDocEntry, formatDocPage } from "./doc.js";
8
8
  import { WithDefaultError, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
9
9
  import { ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
10
10
  import { checkBooleanOption, checkEnumOption, choice, cidr, domain, email, float, hostname, integer, ip, ipv4, ipv6, isValueParser, locale, macAddress, port, portRange, socketAddress, string, url, uuid } from "./valueparser.js";
@@ -12,4 +12,4 @@ import { argument, command, constant, fail, flag, option, passThrough } from "./
12
12
  import { getDocPage, getDocPageAsync, getDocPageSync, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync } from "./parser.js";
13
13
  import { RunParserError, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync } from "./facade.js";
14
14
 
15
- export { DependencyRegistry, DuplicateOptionError, RunParserError, WithDefaultError, annotationKey, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, command, commandLine, concat, conditional, constant, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fail, fish, flag, float, formatDependencyError, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDefaultValuesFunction, getDependencyIds, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isDocHidden, isNonEmptyString, isPendingDependencySourceState, isSuggestionHidden, isUsageHidden, isValueParser, isWrappedDependencySource, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, parseWithDependency, passThrough, pendingDependencySourceStateMarker, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, socketAddress, string, suggest, suggestAsync, suggestSync, suggestWithDependency, text, transformsDependencyValue, transformsDependencyValueMarker, tuple, url, uuid, value, valueSet, values, withDefault, wrappedDependencySourceMarker, zsh };
15
+ export { DependencyRegistry, DuplicateOptionError, RunParserError, WithDefaultError, annotationKey, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, command, commandLine, concat, conditional, constant, createDeferredParseState, createDependencySourceState, createPendingDependencySourceState, deduplicateDocEntries, deduplicateDocFragments, defaultValues, deferredParseMarker, dependency, dependencyId, dependencyIds, dependencySourceMarker, dependencySourceStateMarker, deriveFrom, deriveFromAsync, deriveFromSync, derivedValueParserMarker, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractOptionNames, fail, fish, flag, float, formatDependencyError, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDefaultValuesFunction, getDependencyIds, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDeferredParseState, isDependencySource, isDependencySourceState, isDerivedValueParser, isDocHidden, isNonEmptyString, isPendingDependencySourceState, isSuggestionHidden, isUsageHidden, isValueParser, isWrappedDependencySource, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, parseWithDependency, passThrough, pendingDependencySourceStateMarker, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, socketAddress, string, suggest, suggestAsync, suggestSync, suggestWithDependency, text, transformsDependencyValue, transformsDependencyValueMarker, tuple, url, uuid, value, valueSet, values, withDefault, wrappedDependencySourceMarker, zsh };
package/dist/parser.cjs CHANGED
@@ -2,8 +2,8 @@ const require_annotations = require('./annotations.cjs');
2
2
  const require_message = require('./message.cjs');
3
3
  const require_mode_dispatch = require('./mode-dispatch.cjs');
4
4
  const require_usage = require('./usage.cjs');
5
- const require_constructs = require('./constructs.cjs');
6
5
  const require_doc = require('./doc.cjs');
6
+ const require_constructs = require('./constructs.cjs');
7
7
  const require_modifiers = require('./modifiers.cjs');
8
8
  const require_primitives = require('./primitives.cjs');
9
9
 
package/dist/parser.js CHANGED
@@ -2,8 +2,8 @@ import { injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotatio
2
2
  import { cloneMessage, message } from "./message.js";
3
3
  import { dispatchByMode } from "./mode-dispatch.js";
4
4
  import { cloneUsage, normalizeUsage } from "./usage.js";
5
- import { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
6
5
  import { cloneDocEntry } from "./doc.js";
6
+ import { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
7
7
  import { WithDefaultError, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
8
8
  import { argument, command, constant, fail, flag, option, passThrough } from "./primitives.js";
9
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.0-dev.1326+40fd572e",
3
+ "version": "1.0.0-dev.1344+e7f36975",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",