@optique/core 1.4.0-dev.2616 → 1.4.0-dev.2618
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constructs.cjs +87 -144
- package/dist/constructs.js +87 -144
- package/dist/execution-context.cjs +1 -2
- package/dist/execution-context.js +1 -3
- package/dist/extension.cjs +0 -15
- package/dist/extension.d.cts +1 -12
- package/dist/extension.d.ts +1 -12
- package/dist/extension.js +1 -15
- package/dist/facade.cjs +140 -6
- package/dist/facade.d.cts +32 -2
- package/dist/facade.d.ts +32 -2
- package/dist/facade.js +141 -7
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/modifiers.cjs +4 -5
- package/dist/modifiers.js +4 -5
- package/dist/primitives.cjs +27 -69
- package/dist/primitives.d.cts +3 -3
- package/dist/primitives.d.ts +3 -3
- package/dist/primitives.js +27 -69
- package/dist/usage-internals.cjs +0 -73
- package/dist/usage-internals.js +1 -71
- package/package.json +2 -2
- package/skills/optique/SKILL.md +12 -12
- package/dist/short-option.cjs +0 -311
- package/dist/short-option.js +0 -297
package/dist/primitives.d.cts
CHANGED
|
@@ -104,7 +104,7 @@ interface OptionErrorOptions {
|
|
|
104
104
|
/**
|
|
105
105
|
* Creates a parser for various styles of command-line options that take an
|
|
106
106
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
107
|
-
*
|
|
107
|
+
* or `/option:value`.
|
|
108
108
|
* @template M The execution mode of the parser.
|
|
109
109
|
* @template T The type of value this parser produces.
|
|
110
110
|
* @param args The {@link OptionName}s to parse, followed by
|
|
@@ -118,7 +118,7 @@ declare function option<M extends Mode, T>(...args: readonly [OptionName, ...rea
|
|
|
118
118
|
/**
|
|
119
119
|
* Creates a parser for various styles of command-line options that take an
|
|
120
120
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
121
|
-
*
|
|
121
|
+
* or `/option:value`.
|
|
122
122
|
* @template M The execution mode of the parser.
|
|
123
123
|
* @template T The type of value this parser produces.
|
|
124
124
|
* @param args The {@link OptionName}s to parse, followed by
|
|
@@ -140,7 +140,7 @@ declare function option(...optionNames: readonly [OptionName, ...readonly Option
|
|
|
140
140
|
/**
|
|
141
141
|
* Creates a parser for various styles of command-line options that take an
|
|
142
142
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
143
|
-
*
|
|
143
|
+
* or `/option:value`.
|
|
144
144
|
* @param args The {@link OptionName}s to parse, followed by
|
|
145
145
|
* an optional {@link OptionOptions} object that allows you to
|
|
146
146
|
* specify a description or other metadata.
|
package/dist/primitives.d.ts
CHANGED
|
@@ -104,7 +104,7 @@ interface OptionErrorOptions {
|
|
|
104
104
|
/**
|
|
105
105
|
* Creates a parser for various styles of command-line options that take an
|
|
106
106
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
107
|
-
*
|
|
107
|
+
* or `/option:value`.
|
|
108
108
|
* @template M The execution mode of the parser.
|
|
109
109
|
* @template T The type of value this parser produces.
|
|
110
110
|
* @param args The {@link OptionName}s to parse, followed by
|
|
@@ -118,7 +118,7 @@ declare function option<M extends Mode, T>(...args: readonly [OptionName, ...rea
|
|
|
118
118
|
/**
|
|
119
119
|
* Creates a parser for various styles of command-line options that take an
|
|
120
120
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
121
|
-
*
|
|
121
|
+
* or `/option:value`.
|
|
122
122
|
* @template M The execution mode of the parser.
|
|
123
123
|
* @template T The type of value this parser produces.
|
|
124
124
|
* @param args The {@link OptionName}s to parse, followed by
|
|
@@ -140,7 +140,7 @@ declare function option(...optionNames: readonly [OptionName, ...readonly Option
|
|
|
140
140
|
/**
|
|
141
141
|
* Creates a parser for various styles of command-line options that take an
|
|
142
142
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
143
|
-
*
|
|
143
|
+
* or `/option:value`.
|
|
144
144
|
* @param args The {@link OptionName}s to parse, followed by
|
|
145
145
|
* an optional {@link OptionOptions} object that allows you to
|
|
146
146
|
* specify a description or other metadata.
|
package/dist/primitives.js
CHANGED
|
@@ -6,14 +6,13 @@ import { dispatchByMode, dispatchIterableByMode, wrapForMode } from "./internal/
|
|
|
6
6
|
import { getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDerivedValueParser, suggestWithDependency } from "./internal/dependency.js";
|
|
7
7
|
import { effectfulSchedulingNodesKey, exclusiveSourceScopeKey, includeSourceFailureChain, recordDerivedRawInput, replayDerivedParser, replayDerivedParserAsync, sourceCollectionExpansionKey } from "./dependency-runtime.js";
|
|
8
8
|
import { getWrappedChildParseState, getWrappedChildState, isAnnotationWrappedInitialState, normalizeInjectedAnnotationState } from "./annotation-state.js";
|
|
9
|
-
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
10
|
-
import { extractLeadingCommandNames } from "./usage-internals.js";
|
|
11
|
-
import { attachedValuePrefix, combinedOptionScope, fullNameOwnsToken, prefixSuggestion, scopeParser, selectableOptionScope } from "./short-option.js";
|
|
12
9
|
import { hiddenCommandAliasesKey } from "./internal/command-alias.js";
|
|
10
|
+
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
13
11
|
import { completeOrExtractPhase2Seed, extractPhase2SeedKey } from "./phase2-seed.js";
|
|
14
12
|
import { extractDependencyMetadata } from "./dependency-metadata.js";
|
|
15
13
|
import { fluent } from "./modifiers.js";
|
|
16
14
|
import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, expandCommandAliasSuggestions, findSimilar } from "./suggestion.js";
|
|
15
|
+
import { extractLeadingCommandNames } from "./usage-internals.js";
|
|
17
16
|
import { isValueParser } from "./valueparser.js";
|
|
18
17
|
|
|
19
18
|
//#region src/primitives.ts
|
|
@@ -257,25 +256,11 @@ function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry,
|
|
|
257
256
|
*/
|
|
258
257
|
function* suggestOptionSync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
259
258
|
if (hidden) return;
|
|
260
|
-
if (context.optionsTerminated) return;
|
|
261
|
-
const waitingForValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
|
|
262
|
-
if (valueParser != null && !waitingForValue && !isTerminalValueState(context.state)) {
|
|
263
|
-
const attached = attachedValuePrefix(context, prefix, optionNames$1);
|
|
264
|
-
if (attached != null) {
|
|
265
|
-
if (attached.value.length === 0 && optionNames$1.includes(prefix)) yield {
|
|
266
|
-
kind: "literal",
|
|
267
|
-
text: prefix,
|
|
268
|
-
...description != null ? { description } : {}
|
|
269
|
-
};
|
|
270
|
-
if (valueParser.suggest != null) for (const suggestion of getSuggestionsWithDependency(valueParser, attached.value, context.dependencyRegistry, context.exec)) yield prefixSuggestion(attached.head, suggestion);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
259
|
const equalsIndex = prefix.indexOf("=");
|
|
275
|
-
if (equalsIndex >= 0
|
|
260
|
+
if (equalsIndex >= 0) {
|
|
276
261
|
const optionPart = prefix.slice(0, equalsIndex);
|
|
277
262
|
const valuePart = prefix.slice(equalsIndex + 1);
|
|
278
|
-
if (optionNames$1.includes(optionPart)
|
|
263
|
+
if (optionNames$1.includes(optionPart)) {
|
|
279
264
|
if (valueParser && valueParser.suggest) {
|
|
280
265
|
const valueSuggestions = getSuggestionsWithDependency(valueParser, valuePart, context.dependencyRegistry, context.exec);
|
|
281
266
|
for (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
|
|
@@ -294,7 +279,7 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, description, con
|
|
|
294
279
|
const expectingValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
|
|
295
280
|
if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) {
|
|
296
281
|
for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
|
|
297
|
-
if (prefix === "-" &&
|
|
282
|
+
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
298
283
|
yield {
|
|
299
284
|
kind: "literal",
|
|
300
285
|
text: optionName$1,
|
|
@@ -356,25 +341,11 @@ async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependenc
|
|
|
356
341
|
*/
|
|
357
342
|
async function* suggestOptionAsync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
358
343
|
if (hidden) return;
|
|
359
|
-
if (context.optionsTerminated) return;
|
|
360
|
-
const waitingForValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
|
|
361
|
-
if (valueParser != null && !waitingForValue && !isTerminalValueState(context.state)) {
|
|
362
|
-
const attached = attachedValuePrefix(context, prefix, optionNames$1);
|
|
363
|
-
if (attached != null) {
|
|
364
|
-
if (attached.value.length === 0 && optionNames$1.includes(prefix)) yield {
|
|
365
|
-
kind: "literal",
|
|
366
|
-
text: prefix,
|
|
367
|
-
...description != null ? { description } : {}
|
|
368
|
-
};
|
|
369
|
-
if (valueParser.suggest != null) for await (const suggestion of getSuggestionsWithDependencyAsync(valueParser, attached.value, context.dependencyRegistry, context.exec)) yield prefixSuggestion(attached.head, suggestion);
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
344
|
const equalsIndex = prefix.indexOf("=");
|
|
374
|
-
if (equalsIndex >= 0
|
|
345
|
+
if (equalsIndex >= 0) {
|
|
375
346
|
const optionPart = prefix.slice(0, equalsIndex);
|
|
376
347
|
const valuePart = prefix.slice(equalsIndex + 1);
|
|
377
|
-
if (optionNames$1.includes(optionPart)
|
|
348
|
+
if (optionNames$1.includes(optionPart)) {
|
|
378
349
|
if (valueParser && valueParser.suggest) {
|
|
379
350
|
const valueSuggestions = getSuggestionsWithDependencyAsync(valueParser, valuePart, context.dependencyRegistry, context.exec);
|
|
380
351
|
for await (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
|
|
@@ -393,7 +364,7 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, descripti
|
|
|
393
364
|
const expectingValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
|
|
394
365
|
if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) {
|
|
395
366
|
for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
|
|
396
|
-
if (prefix === "-" &&
|
|
367
|
+
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
397
368
|
yield {
|
|
398
369
|
kind: "literal",
|
|
399
370
|
text: optionName$1,
|
|
@@ -553,18 +524,10 @@ function option(...args) {
|
|
|
553
524
|
};
|
|
554
525
|
});
|
|
555
526
|
}
|
|
556
|
-
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2
|
|
557
|
-
|
|
558
|
-
prefix: name.startsWith("/") ? `${name}:` : `${name}=`
|
|
559
|
-
}));
|
|
560
|
-
if (valueParser != null && optionNames$1.some((name) => /^-[^-]$/u.test(name) && context.buffer[0].startsWith(name)) && !fullNameOwnsToken(context, context.buffer[0])) {
|
|
561
|
-
for (const name of optionNames$1) if (/^-[^-]$/u.test(name)) prefixes.push({
|
|
562
|
-
optionName: name,
|
|
563
|
-
prefix: name
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
for (const { prefix, optionName: optionName$1 } of prefixes) {
|
|
527
|
+
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) => name.startsWith("/") ? `${name}:` : `${name}=`);
|
|
528
|
+
for (const prefix of prefixes) {
|
|
567
529
|
if (!context.buffer[0].startsWith(prefix)) continue;
|
|
530
|
+
const optionName$1 = prefix.slice(0, -1);
|
|
568
531
|
if (hasParsedOptionValue(context.state, valueParser)) return {
|
|
569
532
|
success: false,
|
|
570
533
|
consumed: 1,
|
|
@@ -603,9 +566,9 @@ function option(...args) {
|
|
|
603
566
|
});
|
|
604
567
|
}
|
|
605
568
|
if (valueParser == null) {
|
|
606
|
-
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/
|
|
569
|
+
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
607
570
|
for (const shortOption of shortOptions) {
|
|
608
|
-
if (!context.buffer[0].startsWith(shortOption)
|
|
571
|
+
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
609
572
|
if (hasParsedOptionValue(context.state, valueParser)) return {
|
|
610
573
|
success: false,
|
|
611
574
|
consumed: 1,
|
|
@@ -619,9 +582,9 @@ function option(...args) {
|
|
|
619
582
|
success: true,
|
|
620
583
|
value: true
|
|
621
584
|
},
|
|
622
|
-
buffer: [`-${context.buffer[0].slice(
|
|
585
|
+
buffer: [`-${context.buffer[0].slice(2)}`, ...context.buffer.slice(1)]
|
|
623
586
|
},
|
|
624
|
-
consumed: [context.buffer[0].slice(0,
|
|
587
|
+
consumed: [context.buffer[0].slice(0, 2)]
|
|
625
588
|
};
|
|
626
589
|
}
|
|
627
590
|
}
|
|
@@ -883,7 +846,7 @@ function flag(...args) {
|
|
|
883
846
|
consumed: context.buffer.slice(0, 1)
|
|
884
847
|
};
|
|
885
848
|
}
|
|
886
|
-
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2
|
|
849
|
+
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) => name.startsWith("/") ? `${name}:` : `${name}=`);
|
|
887
850
|
for (const prefix of prefixes) if (context.buffer[0].startsWith(prefix)) {
|
|
888
851
|
const value = context.buffer[0].slice(prefix.length);
|
|
889
852
|
return {
|
|
@@ -892,9 +855,9 @@ function flag(...args) {
|
|
|
892
855
|
error: message`Flag ${optionName(prefix.slice(0, -1))} does not accept a value, but got: ${value}.`
|
|
893
856
|
};
|
|
894
857
|
}
|
|
895
|
-
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/
|
|
858
|
+
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
896
859
|
for (const shortOption of shortOptions) {
|
|
897
|
-
if (!context.buffer[0].startsWith(shortOption)
|
|
860
|
+
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
898
861
|
if (context.state?.success) return {
|
|
899
862
|
success: false,
|
|
900
863
|
consumed: 1,
|
|
@@ -908,9 +871,9 @@ function flag(...args) {
|
|
|
908
871
|
success: true,
|
|
909
872
|
value: true
|
|
910
873
|
},
|
|
911
|
-
buffer: [`-${context.buffer[0].slice(
|
|
874
|
+
buffer: [`-${context.buffer[0].slice(2)}`, ...context.buffer.slice(1)]
|
|
912
875
|
},
|
|
913
|
-
consumed: [context.buffer[0].slice(0,
|
|
876
|
+
consumed: [context.buffer[0].slice(0, 2)]
|
|
914
877
|
};
|
|
915
878
|
}
|
|
916
879
|
const invalidOption = context.buffer[0];
|
|
@@ -951,7 +914,7 @@ function flag(...args) {
|
|
|
951
914
|
const suggestions = [];
|
|
952
915
|
if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+")) {
|
|
953
916
|
for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
|
|
954
|
-
if (prefix === "-" &&
|
|
917
|
+
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
955
918
|
suggestions.push({
|
|
956
919
|
kind: "literal",
|
|
957
920
|
text: optionName$1,
|
|
@@ -1102,7 +1065,7 @@ function negatableFlag(names, options = {}) {
|
|
|
1102
1065
|
const directValue = valueByName.get(context.buffer[0]);
|
|
1103
1066
|
if (directValue != null) return parseMatchedNegatableFlag(context, context.buffer[0], directValue, context.buffer.slice(0, 1), 1, context.buffer.slice(1), options);
|
|
1104
1067
|
for (const name of optionNames$1) {
|
|
1105
|
-
if (!name.startsWith("--") && !name.startsWith("/") && !name.startsWith("+") && !(name.startsWith("-") && name.length > 2
|
|
1068
|
+
if (!name.startsWith("--") && !name.startsWith("/") && !name.startsWith("+") && !(name.startsWith("-") && name.length > 2)) continue;
|
|
1106
1069
|
const prefix = name.startsWith("/") ? `${name}:` : `${name}=`;
|
|
1107
1070
|
if (context.buffer[0].startsWith(prefix)) {
|
|
1108
1071
|
const value = context.buffer[0].slice(prefix.length);
|
|
@@ -1114,9 +1077,9 @@ function negatableFlag(names, options = {}) {
|
|
|
1114
1077
|
}
|
|
1115
1078
|
}
|
|
1116
1079
|
for (const shortOption of optionNames$1) {
|
|
1117
|
-
if (!shortOption.match(/^-[^-]$/
|
|
1118
|
-
if (!context.buffer[0].startsWith(shortOption)
|
|
1119
|
-
return parseMatchedNegatableFlag(context, shortOption, valueByName.get(shortOption), [context.buffer[0].slice(0,
|
|
1080
|
+
if (!shortOption.match(/^-[^-]$/)) continue;
|
|
1081
|
+
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
1082
|
+
return parseMatchedNegatableFlag(context, shortOption, valueByName.get(shortOption), [context.buffer[0].slice(0, 2)], 1, [`-${context.buffer[0].slice(2)}`, ...context.buffer.slice(1)], options);
|
|
1120
1083
|
}
|
|
1121
1084
|
const invalidOption = context.buffer[0];
|
|
1122
1085
|
if (options.errors?.noMatch) {
|
|
@@ -1151,7 +1114,7 @@ function negatableFlag(names, options = {}) {
|
|
|
1151
1114
|
const suggestions = [];
|
|
1152
1115
|
if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+")) {
|
|
1153
1116
|
for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
|
|
1154
|
-
if (prefix === "-" &&
|
|
1117
|
+
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
1155
1118
|
suggestions.push({
|
|
1156
1119
|
kind: "literal",
|
|
1157
1120
|
text: optionName$1
|
|
@@ -1524,8 +1487,6 @@ function command(name, parser, options = {}) {
|
|
|
1524
1487
|
const isAsync = parser.mode === "async";
|
|
1525
1488
|
const syncInnerParser = parser;
|
|
1526
1489
|
const asyncInnerParser = parser;
|
|
1527
|
-
const commandScope = selectableOptionScope(() => new Set(commandNames));
|
|
1528
|
-
const enteredScope = combinedOptionScope([parser], [name]);
|
|
1529
1490
|
const result = {
|
|
1530
1491
|
[Symbol.for("@optique/core/commandParser")]: true,
|
|
1531
1492
|
mode: parser.mode,
|
|
@@ -1593,7 +1554,6 @@ function command(name, parser, options = {}) {
|
|
|
1593
1554
|
] : baseError
|
|
1594
1555
|
};
|
|
1595
1556
|
}
|
|
1596
|
-
commandScope.select(context, enteredScope);
|
|
1597
1557
|
return {
|
|
1598
1558
|
success: true,
|
|
1599
1559
|
next: {
|
|
@@ -1774,9 +1734,7 @@ function command(name, parser, options = {}) {
|
|
|
1774
1734
|
configurable: true,
|
|
1775
1735
|
enumerable: false
|
|
1776
1736
|
});
|
|
1777
|
-
return fluent(
|
|
1778
|
-
if (normalizeCommandState(context.state) != null) commandScope.select(context, enteredScope);
|
|
1779
|
-
}));
|
|
1737
|
+
return fluent(result);
|
|
1780
1738
|
}
|
|
1781
1739
|
/**
|
|
1782
1740
|
* Creates a parser that collects unrecognized options and passes them through.
|
package/dist/usage-internals.cjs
CHANGED
|
@@ -76,80 +76,7 @@ function extractLeadingCommandNames(usage) {
|
|
|
76
76
|
collectLeadingCandidates(usage, options, commands);
|
|
77
77
|
return commands;
|
|
78
78
|
}
|
|
79
|
-
/** Collects arities along an entered command path. @internal */
|
|
80
|
-
function collectActiveOptionNames(usage, commandPath, names, fromExclusive, includeDirectAfterCommandOptions) {
|
|
81
|
-
if (commandPath.length === 0) {
|
|
82
|
-
collectOptionNamesAtCurrentCommandDepth(usage, names, false);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
const [commandName, ...rest] = commandPath;
|
|
86
|
-
for (let i = 0; i < usage.length; i++) {
|
|
87
|
-
const term = usage[i];
|
|
88
|
-
if (term.type === "command" && term.name === commandName) {
|
|
89
|
-
const remainingUsage = usage.slice(i + 1);
|
|
90
|
-
if (rest.length === 0) collectOptionNamesAtCurrentCommandDepth(remainingUsage, names, !fromExclusive && includeDirectAfterCommandOptions);
|
|
91
|
-
else collectActiveOptionNames(remainingUsage, rest, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
92
|
-
} else if (term.type === "exclusive") for (const branch of term.terms) collectActiveOptionNames(branch, commandPath, names, true, includeDirectAfterCommandOptions);
|
|
93
|
-
else if (term.type === "optional" || term.type === "multiple" || term.type === "sequence") collectActiveOptionNames(term.terms, commandPath, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/** Collects arities without entering further commands. @internal */
|
|
97
|
-
function collectOptionNamesAtCurrentCommandDepth(usage, names, afterMatchedCommand) {
|
|
98
|
-
for (const term of usage) if (collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatchedCommand)) return;
|
|
99
|
-
}
|
|
100
|
-
function collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatchedCommand) {
|
|
101
|
-
switch (term.type) {
|
|
102
|
-
case "command": return !afterMatchedCommand;
|
|
103
|
-
case "option":
|
|
104
|
-
if (term.metavar != null) for (const name of term.names) names.value.add(name);
|
|
105
|
-
else for (const name of term.names) names.flag.add(name);
|
|
106
|
-
return false;
|
|
107
|
-
case "optional":
|
|
108
|
-
case "multiple":
|
|
109
|
-
case "sequence":
|
|
110
|
-
collectOptionNamesAtCurrentCommandDepth(term.terms, names, afterMatchedCommand);
|
|
111
|
-
return false;
|
|
112
|
-
case "exclusive":
|
|
113
|
-
for (const branch of term.terms) collectOptionNamesAtCurrentCommandDepth(branch, names, false);
|
|
114
|
-
return false;
|
|
115
|
-
case "argument":
|
|
116
|
-
case "literal":
|
|
117
|
-
case "passthrough":
|
|
118
|
-
case "ellipsis": return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
/** Collects scoped root arities across sibling commands. @internal */
|
|
122
|
-
function collectRootOptionNames(usage, names, rootLeadingNames) {
|
|
123
|
-
for (const term of usage) collectRootOptionNamesFromTerm(term, names, rootLeadingNames);
|
|
124
|
-
}
|
|
125
|
-
function collectRootOptionNamesFromTerm(term, names, rootLeadingNames) {
|
|
126
|
-
switch (term.type) {
|
|
127
|
-
case "option":
|
|
128
|
-
for (const name of term.names) {
|
|
129
|
-
if (!rootLeadingNames.has(name)) continue;
|
|
130
|
-
if (term.metavar != null) names.value.add(name);
|
|
131
|
-
else names.flag.add(name);
|
|
132
|
-
}
|
|
133
|
-
return;
|
|
134
|
-
case "optional":
|
|
135
|
-
case "multiple":
|
|
136
|
-
case "sequence":
|
|
137
|
-
collectRootOptionNames(term.terms, names, rootLeadingNames);
|
|
138
|
-
return;
|
|
139
|
-
case "exclusive":
|
|
140
|
-
for (const branch of term.terms) collectRootOptionNames(branch, names, rootLeadingNames);
|
|
141
|
-
return;
|
|
142
|
-
case "argument":
|
|
143
|
-
case "command":
|
|
144
|
-
case "literal":
|
|
145
|
-
case "passthrough":
|
|
146
|
-
case "ellipsis": return;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
79
|
|
|
150
80
|
//#endregion
|
|
151
|
-
exports.collectActiveOptionNames = collectActiveOptionNames;
|
|
152
81
|
exports.collectLeadingCandidates = collectLeadingCandidates;
|
|
153
|
-
exports.collectOptionNamesAtCurrentCommandDepth = collectOptionNamesAtCurrentCommandDepth;
|
|
154
|
-
exports.collectRootOptionNames = collectRootOptionNames;
|
|
155
82
|
exports.extractLeadingCommandNames = extractLeadingCommandNames;
|
package/dist/usage-internals.js
CHANGED
|
@@ -76,76 +76,6 @@ function extractLeadingCommandNames(usage) {
|
|
|
76
76
|
collectLeadingCandidates(usage, options, commands);
|
|
77
77
|
return commands;
|
|
78
78
|
}
|
|
79
|
-
/** Collects arities along an entered command path. @internal */
|
|
80
|
-
function collectActiveOptionNames(usage, commandPath, names, fromExclusive, includeDirectAfterCommandOptions) {
|
|
81
|
-
if (commandPath.length === 0) {
|
|
82
|
-
collectOptionNamesAtCurrentCommandDepth(usage, names, false);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
const [commandName, ...rest] = commandPath;
|
|
86
|
-
for (let i = 0; i < usage.length; i++) {
|
|
87
|
-
const term = usage[i];
|
|
88
|
-
if (term.type === "command" && term.name === commandName) {
|
|
89
|
-
const remainingUsage = usage.slice(i + 1);
|
|
90
|
-
if (rest.length === 0) collectOptionNamesAtCurrentCommandDepth(remainingUsage, names, !fromExclusive && includeDirectAfterCommandOptions);
|
|
91
|
-
else collectActiveOptionNames(remainingUsage, rest, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
92
|
-
} else if (term.type === "exclusive") for (const branch of term.terms) collectActiveOptionNames(branch, commandPath, names, true, includeDirectAfterCommandOptions);
|
|
93
|
-
else if (term.type === "optional" || term.type === "multiple" || term.type === "sequence") collectActiveOptionNames(term.terms, commandPath, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/** Collects arities without entering further commands. @internal */
|
|
97
|
-
function collectOptionNamesAtCurrentCommandDepth(usage, names, afterMatchedCommand) {
|
|
98
|
-
for (const term of usage) if (collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatchedCommand)) return;
|
|
99
|
-
}
|
|
100
|
-
function collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatchedCommand) {
|
|
101
|
-
switch (term.type) {
|
|
102
|
-
case "command": return !afterMatchedCommand;
|
|
103
|
-
case "option":
|
|
104
|
-
if (term.metavar != null) for (const name of term.names) names.value.add(name);
|
|
105
|
-
else for (const name of term.names) names.flag.add(name);
|
|
106
|
-
return false;
|
|
107
|
-
case "optional":
|
|
108
|
-
case "multiple":
|
|
109
|
-
case "sequence":
|
|
110
|
-
collectOptionNamesAtCurrentCommandDepth(term.terms, names, afterMatchedCommand);
|
|
111
|
-
return false;
|
|
112
|
-
case "exclusive":
|
|
113
|
-
for (const branch of term.terms) collectOptionNamesAtCurrentCommandDepth(branch, names, false);
|
|
114
|
-
return false;
|
|
115
|
-
case "argument":
|
|
116
|
-
case "literal":
|
|
117
|
-
case "passthrough":
|
|
118
|
-
case "ellipsis": return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
/** Collects scoped root arities across sibling commands. @internal */
|
|
122
|
-
function collectRootOptionNames(usage, names, rootLeadingNames) {
|
|
123
|
-
for (const term of usage) collectRootOptionNamesFromTerm(term, names, rootLeadingNames);
|
|
124
|
-
}
|
|
125
|
-
function collectRootOptionNamesFromTerm(term, names, rootLeadingNames) {
|
|
126
|
-
switch (term.type) {
|
|
127
|
-
case "option":
|
|
128
|
-
for (const name of term.names) {
|
|
129
|
-
if (!rootLeadingNames.has(name)) continue;
|
|
130
|
-
if (term.metavar != null) names.value.add(name);
|
|
131
|
-
else names.flag.add(name);
|
|
132
|
-
}
|
|
133
|
-
return;
|
|
134
|
-
case "optional":
|
|
135
|
-
case "multiple":
|
|
136
|
-
case "sequence":
|
|
137
|
-
collectRootOptionNames(term.terms, names, rootLeadingNames);
|
|
138
|
-
return;
|
|
139
|
-
case "exclusive":
|
|
140
|
-
for (const branch of term.terms) collectRootOptionNames(branch, names, rootLeadingNames);
|
|
141
|
-
return;
|
|
142
|
-
case "argument":
|
|
143
|
-
case "command":
|
|
144
|
-
case "literal":
|
|
145
|
-
case "passthrough":
|
|
146
|
-
case "ellipsis": return;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
79
|
|
|
150
80
|
//#endregion
|
|
151
|
-
export {
|
|
81
|
+
export { collectLeadingCandidates, extractLeadingCommandNames };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/core",
|
|
3
|
-
"version": "1.4.0-dev.
|
|
3
|
+
"version": "1.4.0-dev.2618",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
},
|
|
238
238
|
"sideEffects": false,
|
|
239
239
|
"devDependencies": {
|
|
240
|
-
"@optique/env": "1.4.0-dev.
|
|
240
|
+
"@optique/env": "1.4.0-dev.2618+2cb27efe",
|
|
241
241
|
"@types/node": "^24.0.0",
|
|
242
242
|
"fast-check": "^4.7.0",
|
|
243
243
|
"tsdown": "^0.13.0",
|
package/skills/optique/SKILL.md
CHANGED
|
@@ -11,8 +11,7 @@ description: >
|
|
|
11
11
|
license: MIT
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
Start at <https://optique.dev/llms.txt>
|
|
15
|
-
combinatorial parser model and common pitfalls offline.
|
|
14
|
+
Start at <https://optique.dev/llms.txt> online; these rules also work offline.
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
Core rules
|
|
@@ -30,11 +29,15 @@ Core rules
|
|
|
30
29
|
Pin `colors`/`maxWidth` in tests; defaults use terminal and environment.
|
|
31
30
|
- Compose parsers with `object()`, `tuple()`, `seq()`, `or()`, `merge()`, and
|
|
32
31
|
modifiers. Do not hand-write argument scanners around Optique parsers.
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
- For command/option help headings, set the runner's
|
|
33
|
+
`helpSections: { commands: "Commands", options: "Options" }`.
|
|
34
|
+
It groups untitled entries only on pages with visible commands. See
|
|
35
|
+
<https://optique.dev/cookbook.md#command-and-option-headings-in-help>.
|
|
36
|
+
- Let TypeScript infer results; write a separate result interface only when
|
|
37
|
+
another API boundary requires it.
|
|
38
|
+
- Parsers are usually required. `optional(p)` yields `undefined`, and
|
|
39
|
+
`withDefault(p, value)` supplies a fallback. Use
|
|
40
|
+
`withDefault(flag("--name"), false)` for optional Boolean flags.
|
|
38
41
|
- Use semantic `message` helpers for descriptions and errors. Since 1.3.0,
|
|
39
42
|
customize terminal output with `theme` or `messageFormatter`, preserving
|
|
40
43
|
`initialWidth`, quoting, and width options. Keep canonical errors unthemed.
|
|
@@ -47,8 +50,6 @@ Core rules
|
|
|
47
50
|
`@optique/run/valueparser` for file-system paths. Write a custom
|
|
48
51
|
`{ mode, metavar, parse, format }` value parser only when the catalog does
|
|
49
52
|
not cover the domain.
|
|
50
|
-
- Since 1.4.0, `-p8080`/`-vp8080` accept attached values. Values consume
|
|
51
|
-
the literal suffix (`-p=5` gives `"=5"`); full single-dash names win.
|
|
52
53
|
- Async value parsers like *@optique/git* make containing parsers async.
|
|
53
54
|
Await `run()`/`parse()`/`runParser()` or, for `bindKeyring()`, `runAsync()`.
|
|
54
55
|
- Use `dependency()` when one value parser controls another's valid values.
|
|
@@ -231,9 +232,8 @@ const parser = logLevel();
|
|
|
231
232
|
Common mistakes checklist
|
|
232
233
|
-------------------------
|
|
233
234
|
|
|
234
|
-
-
|
|
235
|
-
|
|
236
|
-
in tests and embedded use.
|
|
235
|
+
- Pass parsers to `run()` for apps; use explicit argument arrays with
|
|
236
|
+
`parse()` in tests and embedded use. Do not pre-parse `process.argv`.
|
|
237
237
|
- Do not treat `or(a, b)` as “zero or more alternatives.” It requires one
|
|
238
238
|
matching branch unless the whole `or()` is wrapped in `optional()` or
|
|
239
239
|
`withDefault()`.
|