@optique/core 1.0.0-dev.1533 → 1.0.0-dev.1547
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 +53 -0
- package/dist/constructs.js +53 -0
- package/dist/facade.cjs +5 -3
- package/dist/facade.js +6 -4
- package/dist/index.cjs +0 -3
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/modifiers.cjs +8 -0
- package/dist/modifiers.js +8 -0
- package/dist/parser.cjs +15 -4
- package/dist/parser.d.cts +38 -0
- package/dist/parser.d.ts +38 -0
- package/dist/parser.js +15 -4
- package/dist/primitives.cjs +19 -0
- package/dist/primitives.js +19 -0
- package/dist/usage.cjs +0 -194
- package/dist/usage.d.cts +1 -75
- package/dist/usage.d.ts +1 -75
- package/dist/usage.js +1 -192
- package/dist/validate.cjs +24 -13
- package/dist/validate.js +24 -13
- package/package.json +1 -1
package/dist/parser.js
CHANGED
|
@@ -52,7 +52,7 @@ function parseSync(parser, args, options) {
|
|
|
52
52
|
};
|
|
53
53
|
const previousBuffer = context.buffer;
|
|
54
54
|
context = result.next;
|
|
55
|
-
if (
|
|
55
|
+
if (isBufferUnchanged(previousBuffer, context.buffer)) return {
|
|
56
56
|
success: false,
|
|
57
57
|
error: message`Unexpected option or argument: ${context.buffer[0]}.`
|
|
58
58
|
};
|
|
@@ -69,6 +69,13 @@ function parseSync(parser, args, options) {
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
|
+
* Returns `true` when the buffer has not changed between iterations,
|
|
73
|
+
* indicating a parser is stalling without consuming input.
|
|
74
|
+
*/
|
|
75
|
+
function isBufferUnchanged(previous, current) {
|
|
76
|
+
return current.length > 0 && current.length === previous.length && current.every((item, i) => item === previous[i]);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
72
79
|
* Parses an array of command-line arguments using the provided combined parser.
|
|
73
80
|
* This function processes the input arguments, applying the parser to each
|
|
74
81
|
* argument until all arguments are consumed or an error occurs.
|
|
@@ -104,7 +111,7 @@ async function parseAsync(parser, args, options) {
|
|
|
104
111
|
};
|
|
105
112
|
const previousBuffer = context.buffer;
|
|
106
113
|
context = result.next;
|
|
107
|
-
if (
|
|
114
|
+
if (isBufferUnchanged(previousBuffer, context.buffer)) return {
|
|
108
115
|
success: false,
|
|
109
116
|
error: message`Unexpected option or argument: ${context.buffer[0]}.`
|
|
110
117
|
};
|
|
@@ -196,7 +203,7 @@ function suggestSync(parser, args, options) {
|
|
|
196
203
|
if (!result.success) return Array.from(parser.suggest(context, prefix));
|
|
197
204
|
const previousBuffer = context.buffer;
|
|
198
205
|
context = result.next;
|
|
199
|
-
if (
|
|
206
|
+
if (isBufferUnchanged(previousBuffer, context.buffer)) return [];
|
|
200
207
|
}
|
|
201
208
|
return Array.from(parser.suggest(context, prefix));
|
|
202
209
|
}
|
|
@@ -239,7 +246,7 @@ async function suggestAsync(parser, args, options) {
|
|
|
239
246
|
}
|
|
240
247
|
const previousBuffer = context.buffer;
|
|
241
248
|
context = result.next;
|
|
242
|
-
if (
|
|
249
|
+
if (isBufferUnchanged(previousBuffer, context.buffer)) return [];
|
|
243
250
|
}
|
|
244
251
|
const suggestions = [];
|
|
245
252
|
for await (const suggestion of parser.suggest(context, prefix)) suggestions.push(suggestion);
|
|
@@ -359,7 +366,9 @@ function getDocPageSyncImpl(parser, args, options) {
|
|
|
359
366
|
while (context.buffer.length > 0) {
|
|
360
367
|
const result = parser.parse(context);
|
|
361
368
|
if (!result.success) break;
|
|
369
|
+
const previousBuffer = context.buffer;
|
|
362
370
|
context = result.next;
|
|
371
|
+
if (isBufferUnchanged(previousBuffer, context.buffer)) break;
|
|
363
372
|
}
|
|
364
373
|
return buildDocPage(parser, context, args);
|
|
365
374
|
}
|
|
@@ -377,7 +386,9 @@ async function getDocPageAsyncImpl(parser, args, options) {
|
|
|
377
386
|
while (context.buffer.length > 0) {
|
|
378
387
|
const result = await parser.parse(context);
|
|
379
388
|
if (!result.success) break;
|
|
389
|
+
const previousBuffer = context.buffer;
|
|
380
390
|
context = result.next;
|
|
391
|
+
if (isBufferUnchanged(previousBuffer, context.buffer)) break;
|
|
381
392
|
}
|
|
382
393
|
return buildDocPage(parser, context, args);
|
|
383
394
|
}
|
package/dist/primitives.cjs
CHANGED
|
@@ -9,6 +9,11 @@ const require_usage_internals = require('./usage-internals.cjs');
|
|
|
9
9
|
const require_valueparser = require('./valueparser.cjs');
|
|
10
10
|
|
|
11
11
|
//#region src/primitives.ts
|
|
12
|
+
/**
|
|
13
|
+
* A shared empty set used as the `leadingNames` value for parsers that
|
|
14
|
+
* do not match any specific name at the first buffer position.
|
|
15
|
+
*/
|
|
16
|
+
const EMPTY_LEADING_NAMES = /* @__PURE__ */ new Set();
|
|
12
17
|
function hasParsedOptionValue(state, valueParser) {
|
|
13
18
|
if (valueParser != null) return require_dependency.isDeferredParseState(state) || require_dependency.isDependencySourceState(state) || state != null && "success" in state && state.success;
|
|
14
19
|
return state != null && "success" in state && state.success && state.value === true;
|
|
@@ -38,6 +43,8 @@ function constant(value) {
|
|
|
38
43
|
$mode: "sync",
|
|
39
44
|
priority: 0,
|
|
40
45
|
usage: [],
|
|
46
|
+
leadingNames: EMPTY_LEADING_NAMES,
|
|
47
|
+
acceptingAnyToken: false,
|
|
41
48
|
initialState: value,
|
|
42
49
|
parse(context) {
|
|
43
50
|
return {
|
|
@@ -93,6 +100,8 @@ function fail() {
|
|
|
93
100
|
$mode: "sync",
|
|
94
101
|
priority: 0,
|
|
95
102
|
usage: [],
|
|
103
|
+
leadingNames: EMPTY_LEADING_NAMES,
|
|
104
|
+
acceptingAnyToken: false,
|
|
96
105
|
initialState: void 0,
|
|
97
106
|
parse(_context) {
|
|
98
107
|
return {
|
|
@@ -338,6 +347,8 @@ function option(...args) {
|
|
|
338
347
|
metavar: valueParser.metavar,
|
|
339
348
|
...options.hidden != null && { hidden: options.hidden }
|
|
340
349
|
}],
|
|
350
|
+
leadingNames: new Set(optionNames$1),
|
|
351
|
+
acceptingAnyToken: false,
|
|
341
352
|
initialState: valueParser == null ? {
|
|
342
353
|
success: true,
|
|
343
354
|
value: false
|
|
@@ -622,6 +633,8 @@ function flag(...args) {
|
|
|
622
633
|
names: optionNames$1,
|
|
623
634
|
...options.hidden != null && { hidden: options.hidden }
|
|
624
635
|
}],
|
|
636
|
+
leadingNames: new Set(optionNames$1),
|
|
637
|
+
acceptingAnyToken: false,
|
|
625
638
|
initialState: void 0,
|
|
626
639
|
parse(context) {
|
|
627
640
|
if (context.optionsTerminated) return {
|
|
@@ -797,6 +810,8 @@ function argument(valueParser, options = {}) {
|
|
|
797
810
|
$stateType: [],
|
|
798
811
|
priority: 5,
|
|
799
812
|
usage: [term],
|
|
813
|
+
leadingNames: EMPTY_LEADING_NAMES,
|
|
814
|
+
acceptingAnyToken: true,
|
|
800
815
|
initialState: void 0,
|
|
801
816
|
parse(context) {
|
|
802
817
|
if (context.buffer.length < 1) return {
|
|
@@ -986,6 +1001,8 @@ function command(name, parser, options = {}) {
|
|
|
986
1001
|
...options.usageLine != null && { usageLine: options.usageLine },
|
|
987
1002
|
...options.hidden != null && { hidden: options.hidden }
|
|
988
1003
|
}, ...parser.usage],
|
|
1004
|
+
leadingNames: new Set([name]),
|
|
1005
|
+
acceptingAnyToken: false,
|
|
989
1006
|
initialState: void 0,
|
|
990
1007
|
parse(context) {
|
|
991
1008
|
if (context.state === void 0) {
|
|
@@ -1180,6 +1197,8 @@ function passThrough(options = {}) {
|
|
|
1180
1197
|
type: "passthrough",
|
|
1181
1198
|
...options.hidden != null && { hidden: options.hidden }
|
|
1182
1199
|
}],
|
|
1200
|
+
leadingNames: EMPTY_LEADING_NAMES,
|
|
1201
|
+
acceptingAnyToken: false,
|
|
1183
1202
|
initialState: [],
|
|
1184
1203
|
parse(context) {
|
|
1185
1204
|
if (context.buffer.length < 1) return {
|
package/dist/primitives.js
CHANGED
|
@@ -9,6 +9,11 @@ import { extractLeadingCommandNames } from "./usage-internals.js";
|
|
|
9
9
|
import { isValueParser } from "./valueparser.js";
|
|
10
10
|
|
|
11
11
|
//#region src/primitives.ts
|
|
12
|
+
/**
|
|
13
|
+
* A shared empty set used as the `leadingNames` value for parsers that
|
|
14
|
+
* do not match any specific name at the first buffer position.
|
|
15
|
+
*/
|
|
16
|
+
const EMPTY_LEADING_NAMES = /* @__PURE__ */ new Set();
|
|
12
17
|
function hasParsedOptionValue(state, valueParser) {
|
|
13
18
|
if (valueParser != null) return isDeferredParseState(state) || isDependencySourceState(state) || state != null && "success" in state && state.success;
|
|
14
19
|
return state != null && "success" in state && state.success && state.value === true;
|
|
@@ -38,6 +43,8 @@ function constant(value) {
|
|
|
38
43
|
$mode: "sync",
|
|
39
44
|
priority: 0,
|
|
40
45
|
usage: [],
|
|
46
|
+
leadingNames: EMPTY_LEADING_NAMES,
|
|
47
|
+
acceptingAnyToken: false,
|
|
41
48
|
initialState: value,
|
|
42
49
|
parse(context) {
|
|
43
50
|
return {
|
|
@@ -93,6 +100,8 @@ function fail() {
|
|
|
93
100
|
$mode: "sync",
|
|
94
101
|
priority: 0,
|
|
95
102
|
usage: [],
|
|
103
|
+
leadingNames: EMPTY_LEADING_NAMES,
|
|
104
|
+
acceptingAnyToken: false,
|
|
96
105
|
initialState: void 0,
|
|
97
106
|
parse(_context) {
|
|
98
107
|
return {
|
|
@@ -338,6 +347,8 @@ function option(...args) {
|
|
|
338
347
|
metavar: valueParser.metavar,
|
|
339
348
|
...options.hidden != null && { hidden: options.hidden }
|
|
340
349
|
}],
|
|
350
|
+
leadingNames: new Set(optionNames$1),
|
|
351
|
+
acceptingAnyToken: false,
|
|
341
352
|
initialState: valueParser == null ? {
|
|
342
353
|
success: true,
|
|
343
354
|
value: false
|
|
@@ -622,6 +633,8 @@ function flag(...args) {
|
|
|
622
633
|
names: optionNames$1,
|
|
623
634
|
...options.hidden != null && { hidden: options.hidden }
|
|
624
635
|
}],
|
|
636
|
+
leadingNames: new Set(optionNames$1),
|
|
637
|
+
acceptingAnyToken: false,
|
|
625
638
|
initialState: void 0,
|
|
626
639
|
parse(context) {
|
|
627
640
|
if (context.optionsTerminated) return {
|
|
@@ -797,6 +810,8 @@ function argument(valueParser, options = {}) {
|
|
|
797
810
|
$stateType: [],
|
|
798
811
|
priority: 5,
|
|
799
812
|
usage: [term],
|
|
813
|
+
leadingNames: EMPTY_LEADING_NAMES,
|
|
814
|
+
acceptingAnyToken: true,
|
|
800
815
|
initialState: void 0,
|
|
801
816
|
parse(context) {
|
|
802
817
|
if (context.buffer.length < 1) return {
|
|
@@ -986,6 +1001,8 @@ function command(name, parser, options = {}) {
|
|
|
986
1001
|
...options.usageLine != null && { usageLine: options.usageLine },
|
|
987
1002
|
...options.hidden != null && { hidden: options.hidden }
|
|
988
1003
|
}, ...parser.usage],
|
|
1004
|
+
leadingNames: new Set([name]),
|
|
1005
|
+
acceptingAnyToken: false,
|
|
989
1006
|
initialState: void 0,
|
|
990
1007
|
parse(context) {
|
|
991
1008
|
if (context.state === void 0) {
|
|
@@ -1180,6 +1197,8 @@ function passThrough(options = {}) {
|
|
|
1180
1197
|
type: "passthrough",
|
|
1181
1198
|
...options.hidden != null && { hidden: options.hidden }
|
|
1182
1199
|
}],
|
|
1200
|
+
leadingNames: EMPTY_LEADING_NAMES,
|
|
1201
|
+
acceptingAnyToken: false,
|
|
1183
1202
|
initialState: [],
|
|
1184
1203
|
parse(context) {
|
|
1185
1204
|
if (context.buffer.length < 1) return {
|
package/dist/usage.cjs
CHANGED
|
@@ -104,197 +104,6 @@ function extractCommandNames(usage, includeHidden) {
|
|
|
104
104
|
return names;
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
107
|
-
* Extracts option names that are reachable at the leading token position
|
|
108
|
-
* (before any command or argument gate).
|
|
109
|
-
*
|
|
110
|
-
* Unlike {@link extractOptionNames}, which traverses the entire usage tree,
|
|
111
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
112
|
-
* `argument`, or `literal` term, because subsequent terms are scoped under
|
|
113
|
-
* that positional token. It still recurses into `optional`, `multiple`,
|
|
114
|
-
* and `exclusive` containers, since they represent alternatives or wrappers
|
|
115
|
-
* at the same position.
|
|
116
|
-
*
|
|
117
|
-
* Known limitation: this function infers token positions from the `usage`
|
|
118
|
-
* tree, which is a display-oriented structure. Combinators like `tuple()`
|
|
119
|
-
* and `object()` sort or flatten usage by priority rather than token order,
|
|
120
|
-
* so the results can be inaccurate—both false positives (e.g., options
|
|
121
|
-
* appearing before commands due to priority sorting) and false negatives
|
|
122
|
-
* (e.g., options after commands that are actually parallel peers).
|
|
123
|
-
* The proper fix is to use `Parser.leadingNames` instead of usage-tree
|
|
124
|
-
* analysis.
|
|
125
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
126
|
-
*
|
|
127
|
-
* @param usage The usage description to extract leading option names from.
|
|
128
|
-
* @param includeHidden Whether to include fully hidden options
|
|
129
|
-
* (`hidden: true`) in the result. Defaults to `false`.
|
|
130
|
-
* @returns A set of option names reachable at the leading token position.
|
|
131
|
-
* @since 1.0.0
|
|
132
|
-
*/
|
|
133
|
-
function extractLeadingOptionNames(usage, includeHidden) {
|
|
134
|
-
const names = /* @__PURE__ */ new Set();
|
|
135
|
-
function collectLeading(terms) {
|
|
136
|
-
if (!terms || !Array.isArray(terms)) return;
|
|
137
|
-
for (const term of terms) switch (term.type) {
|
|
138
|
-
case "option":
|
|
139
|
-
if (!includeHidden && isSuggestionHidden(term.hidden)) break;
|
|
140
|
-
for (const name of term.names) names.add(name);
|
|
141
|
-
break;
|
|
142
|
-
case "command": return;
|
|
143
|
-
case "argument":
|
|
144
|
-
case "literal": return;
|
|
145
|
-
case "optional":
|
|
146
|
-
collectLeading(term.terms);
|
|
147
|
-
break;
|
|
148
|
-
case "multiple":
|
|
149
|
-
collectLeading(term.terms);
|
|
150
|
-
if (term.min > 0 && branchConsumesToken(term.terms)) return;
|
|
151
|
-
break;
|
|
152
|
-
case "exclusive":
|
|
153
|
-
for (const branch of term.terms) collectLeading(branch);
|
|
154
|
-
if (exclusiveConsumesToken(term.terms)) return;
|
|
155
|
-
break;
|
|
156
|
-
default: break;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
collectLeading(usage);
|
|
160
|
-
return names;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Extracts command names that could match as the first positional token.
|
|
164
|
-
*
|
|
165
|
-
* Unlike {@link extractCommandNames}, which traverses the entire usage tree,
|
|
166
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
167
|
-
* `argument`, or `literal` term, because subsequent terms in that array are
|
|
168
|
-
* scoped under that positional token (reachable only after the leading term
|
|
169
|
-
* is consumed). It still recurses into `optional`, `multiple`, and
|
|
170
|
-
* `exclusive` containers, since they represent alternatives or optional
|
|
171
|
-
* wrappers at the same token position.
|
|
172
|
-
*
|
|
173
|
-
* Known limitation: this function has the same usage-tree ordering caveat
|
|
174
|
-
* as {@link extractLeadingOptionNames}.
|
|
175
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
176
|
-
*
|
|
177
|
-
* @param usage The usage description to extract leading command names from.
|
|
178
|
-
* @param includeHidden Whether to include fully hidden commands
|
|
179
|
-
* (`hidden: true`) in the result. Defaults to `false`.
|
|
180
|
-
* @returns A set of command names that could match at the first token position.
|
|
181
|
-
* @since 1.0.0
|
|
182
|
-
*/
|
|
183
|
-
function extractLeadingCommandNames(usage, includeHidden) {
|
|
184
|
-
const names = /* @__PURE__ */ new Set();
|
|
185
|
-
function collectLeading(terms) {
|
|
186
|
-
if (!terms || !Array.isArray(terms)) return;
|
|
187
|
-
for (const term of terms) switch (term.type) {
|
|
188
|
-
case "command":
|
|
189
|
-
if (!includeHidden && isSuggestionHidden(term.hidden)) return;
|
|
190
|
-
names.add(term.name);
|
|
191
|
-
return;
|
|
192
|
-
case "argument":
|
|
193
|
-
case "literal": return;
|
|
194
|
-
case "optional":
|
|
195
|
-
collectLeading(term.terms);
|
|
196
|
-
break;
|
|
197
|
-
case "multiple":
|
|
198
|
-
collectLeading(term.terms);
|
|
199
|
-
if (term.min > 0 && branchConsumesToken(term.terms)) return;
|
|
200
|
-
break;
|
|
201
|
-
case "exclusive":
|
|
202
|
-
for (const branch of term.terms) collectLeading(branch);
|
|
203
|
-
if (exclusiveConsumesToken(term.terms)) return;
|
|
204
|
-
break;
|
|
205
|
-
default: break;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
collectLeading(usage);
|
|
209
|
-
return names;
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Extracts literal values that could match as the first positional token.
|
|
213
|
-
*
|
|
214
|
-
* Unlike {@link extractLiteralValues}, which traverses the entire usage tree,
|
|
215
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
216
|
-
* `argument`, or `literal` term, because subsequent terms in that array are
|
|
217
|
-
* scoped under that positional token. It still recurses into `optional`,
|
|
218
|
-
* `multiple`, and `exclusive` containers.
|
|
219
|
-
*
|
|
220
|
-
* Literals tagged with `optionValue: true` (produced by
|
|
221
|
-
* `appendLiteralToUsage()` when rewriting option metavars for
|
|
222
|
-
* `conditional()` discriminators) are skipped, because they represent
|
|
223
|
-
* option values rather than standalone positional tokens.
|
|
224
|
-
*
|
|
225
|
-
* Known limitation: this function has the same usage-tree ordering caveat
|
|
226
|
-
* as {@link extractLeadingOptionNames}.
|
|
227
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
228
|
-
*
|
|
229
|
-
* @param usage The usage description to extract leading literal values from.
|
|
230
|
-
* @returns A set of literal values that could match at the first token
|
|
231
|
-
* position.
|
|
232
|
-
* @since 1.0.0
|
|
233
|
-
*/
|
|
234
|
-
function extractLeadingLiteralValues(usage) {
|
|
235
|
-
const values = /* @__PURE__ */ new Set();
|
|
236
|
-
function collectLeading(terms) {
|
|
237
|
-
if (!terms || !Array.isArray(terms)) return;
|
|
238
|
-
for (const term of terms) switch (term.type) {
|
|
239
|
-
case "literal":
|
|
240
|
-
if (term.optionValue) break;
|
|
241
|
-
values.add(term.value);
|
|
242
|
-
return;
|
|
243
|
-
case "command":
|
|
244
|
-
case "argument": return;
|
|
245
|
-
case "optional":
|
|
246
|
-
collectLeading(term.terms);
|
|
247
|
-
break;
|
|
248
|
-
case "multiple":
|
|
249
|
-
collectLeading(term.terms);
|
|
250
|
-
if (term.min > 0 && branchConsumesToken(term.terms, true)) return;
|
|
251
|
-
break;
|
|
252
|
-
case "exclusive":
|
|
253
|
-
for (const branch of term.terms) collectLeading(branch);
|
|
254
|
-
if (exclusiveConsumesToken(term.terms, true)) return;
|
|
255
|
-
break;
|
|
256
|
-
default: break;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
collectLeading(usage);
|
|
260
|
-
return values;
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Checks whether every branch of an exclusive term must consume a positional
|
|
264
|
-
* token. When true, terms after the exclusive are at position N+1 and should
|
|
265
|
-
* not be considered "leading".
|
|
266
|
-
*
|
|
267
|
-
* @param skipOptionValueLiterals When `true`, literals tagged with
|
|
268
|
-
* `optionValue` are treated as non-positional. Only
|
|
269
|
-
* `extractLeadingLiteralValues()` passes `true`; the option/command
|
|
270
|
-
* extractors use the default (`false`) so that option+value pairs
|
|
271
|
-
* still act as positional gates.
|
|
272
|
-
*/
|
|
273
|
-
function exclusiveConsumesToken(branches, skipOptionValueLiterals = false) {
|
|
274
|
-
if (branches.length === 0) return false;
|
|
275
|
-
return branches.every((branch) => branchConsumesToken(branch, skipOptionValueLiterals));
|
|
276
|
-
}
|
|
277
|
-
function branchConsumesToken(terms, skipOptionValueLiterals = false) {
|
|
278
|
-
if (!terms || !Array.isArray(terms)) return false;
|
|
279
|
-
for (const term of terms) switch (term.type) {
|
|
280
|
-
case "command":
|
|
281
|
-
case "argument": return true;
|
|
282
|
-
case "literal":
|
|
283
|
-
if (skipOptionValueLiterals && term.optionValue) break;
|
|
284
|
-
return true;
|
|
285
|
-
case "option": break;
|
|
286
|
-
case "optional": break;
|
|
287
|
-
case "multiple":
|
|
288
|
-
if (term.min > 0 && branchConsumesToken(term.terms, skipOptionValueLiterals)) return true;
|
|
289
|
-
break;
|
|
290
|
-
case "exclusive":
|
|
291
|
-
if (exclusiveConsumesToken(term.terms, skipOptionValueLiterals)) return true;
|
|
292
|
-
break;
|
|
293
|
-
default: break;
|
|
294
|
-
}
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
107
|
* Extracts all literal values from a usage description.
|
|
299
108
|
*
|
|
300
109
|
* This function recursively traverses the usage tree and collects all
|
|
@@ -769,9 +578,6 @@ exports.cloneUsage = cloneUsage;
|
|
|
769
578
|
exports.cloneUsageTerm = cloneUsageTerm;
|
|
770
579
|
exports.extractArgumentMetavars = extractArgumentMetavars;
|
|
771
580
|
exports.extractCommandNames = extractCommandNames;
|
|
772
|
-
exports.extractLeadingCommandNames = extractLeadingCommandNames;
|
|
773
|
-
exports.extractLeadingLiteralValues = extractLeadingLiteralValues;
|
|
774
|
-
exports.extractLeadingOptionNames = extractLeadingOptionNames;
|
|
775
581
|
exports.extractLiteralValues = extractLiteralValues;
|
|
776
582
|
exports.extractOptionNames = extractOptionNames;
|
|
777
583
|
exports.formatUsage = formatUsage;
|
package/dist/usage.d.cts
CHANGED
|
@@ -270,80 +270,6 @@ declare function extractOptionNames(usage: Usage, includeHidden?: boolean): Set<
|
|
|
270
270
|
* @since 0.7.0
|
|
271
271
|
*/
|
|
272
272
|
declare function extractCommandNames(usage: Usage, includeHidden?: boolean): Set<string>;
|
|
273
|
-
/**
|
|
274
|
-
* Extracts option names that are reachable at the leading token position
|
|
275
|
-
* (before any command or argument gate).
|
|
276
|
-
*
|
|
277
|
-
* Unlike {@link extractOptionNames}, which traverses the entire usage tree,
|
|
278
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
279
|
-
* `argument`, or `literal` term, because subsequent terms are scoped under
|
|
280
|
-
* that positional token. It still recurses into `optional`, `multiple`,
|
|
281
|
-
* and `exclusive` containers, since they represent alternatives or wrappers
|
|
282
|
-
* at the same position.
|
|
283
|
-
*
|
|
284
|
-
* Known limitation: this function infers token positions from the `usage`
|
|
285
|
-
* tree, which is a display-oriented structure. Combinators like `tuple()`
|
|
286
|
-
* and `object()` sort or flatten usage by priority rather than token order,
|
|
287
|
-
* so the results can be inaccurate—both false positives (e.g., options
|
|
288
|
-
* appearing before commands due to priority sorting) and false negatives
|
|
289
|
-
* (e.g., options after commands that are actually parallel peers).
|
|
290
|
-
* The proper fix is to use `Parser.leadingNames` instead of usage-tree
|
|
291
|
-
* analysis.
|
|
292
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
293
|
-
*
|
|
294
|
-
* @param usage The usage description to extract leading option names from.
|
|
295
|
-
* @param includeHidden Whether to include fully hidden options
|
|
296
|
-
* (`hidden: true`) in the result. Defaults to `false`.
|
|
297
|
-
* @returns A set of option names reachable at the leading token position.
|
|
298
|
-
* @since 1.0.0
|
|
299
|
-
*/
|
|
300
|
-
declare function extractLeadingOptionNames(usage: Usage, includeHidden?: boolean): Set<string>;
|
|
301
|
-
/**
|
|
302
|
-
* Extracts command names that could match as the first positional token.
|
|
303
|
-
*
|
|
304
|
-
* Unlike {@link extractCommandNames}, which traverses the entire usage tree,
|
|
305
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
306
|
-
* `argument`, or `literal` term, because subsequent terms in that array are
|
|
307
|
-
* scoped under that positional token (reachable only after the leading term
|
|
308
|
-
* is consumed). It still recurses into `optional`, `multiple`, and
|
|
309
|
-
* `exclusive` containers, since they represent alternatives or optional
|
|
310
|
-
* wrappers at the same token position.
|
|
311
|
-
*
|
|
312
|
-
* Known limitation: this function has the same usage-tree ordering caveat
|
|
313
|
-
* as {@link extractLeadingOptionNames}.
|
|
314
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
315
|
-
*
|
|
316
|
-
* @param usage The usage description to extract leading command names from.
|
|
317
|
-
* @param includeHidden Whether to include fully hidden commands
|
|
318
|
-
* (`hidden: true`) in the result. Defaults to `false`.
|
|
319
|
-
* @returns A set of command names that could match at the first token position.
|
|
320
|
-
* @since 1.0.0
|
|
321
|
-
*/
|
|
322
|
-
declare function extractLeadingCommandNames(usage: Usage, includeHidden?: boolean): Set<string>;
|
|
323
|
-
/**
|
|
324
|
-
* Extracts literal values that could match as the first positional token.
|
|
325
|
-
*
|
|
326
|
-
* Unlike {@link extractLiteralValues}, which traverses the entire usage tree,
|
|
327
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
328
|
-
* `argument`, or `literal` term, because subsequent terms in that array are
|
|
329
|
-
* scoped under that positional token. It still recurses into `optional`,
|
|
330
|
-
* `multiple`, and `exclusive` containers.
|
|
331
|
-
*
|
|
332
|
-
* Literals tagged with `optionValue: true` (produced by
|
|
333
|
-
* `appendLiteralToUsage()` when rewriting option metavars for
|
|
334
|
-
* `conditional()` discriminators) are skipped, because they represent
|
|
335
|
-
* option values rather than standalone positional tokens.
|
|
336
|
-
*
|
|
337
|
-
* Known limitation: this function has the same usage-tree ordering caveat
|
|
338
|
-
* as {@link extractLeadingOptionNames}.
|
|
339
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
340
|
-
*
|
|
341
|
-
* @param usage The usage description to extract leading literal values from.
|
|
342
|
-
* @returns A set of literal values that could match at the first token
|
|
343
|
-
* position.
|
|
344
|
-
* @since 1.0.0
|
|
345
|
-
*/
|
|
346
|
-
declare function extractLeadingLiteralValues(usage: Usage): Set<string>;
|
|
347
273
|
/**
|
|
348
274
|
* Extracts all literal values from a usage description.
|
|
349
275
|
*
|
|
@@ -520,4 +446,4 @@ interface UsageTermFormatOptions extends UsageFormatOptions {
|
|
|
520
446
|
*/
|
|
521
447
|
declare function formatUsageTerm(term: UsageTerm, options?: UsageTermFormatOptions): string;
|
|
522
448
|
//#endregion
|
|
523
|
-
export { HiddenVisibility, OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, cloneUsage, cloneUsageTerm, extractArgumentMetavars, extractCommandNames,
|
|
449
|
+
export { HiddenVisibility, OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, cloneUsage, cloneUsageTerm, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, formatUsage, formatUsageTerm, isDocHidden, isSuggestionHidden, isUsageHidden, mergeHidden, normalizeUsage };
|
package/dist/usage.d.ts
CHANGED
|
@@ -270,80 +270,6 @@ declare function extractOptionNames(usage: Usage, includeHidden?: boolean): Set<
|
|
|
270
270
|
* @since 0.7.0
|
|
271
271
|
*/
|
|
272
272
|
declare function extractCommandNames(usage: Usage, includeHidden?: boolean): Set<string>;
|
|
273
|
-
/**
|
|
274
|
-
* Extracts option names that are reachable at the leading token position
|
|
275
|
-
* (before any command or argument gate).
|
|
276
|
-
*
|
|
277
|
-
* Unlike {@link extractOptionNames}, which traverses the entire usage tree,
|
|
278
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
279
|
-
* `argument`, or `literal` term, because subsequent terms are scoped under
|
|
280
|
-
* that positional token. It still recurses into `optional`, `multiple`,
|
|
281
|
-
* and `exclusive` containers, since they represent alternatives or wrappers
|
|
282
|
-
* at the same position.
|
|
283
|
-
*
|
|
284
|
-
* Known limitation: this function infers token positions from the `usage`
|
|
285
|
-
* tree, which is a display-oriented structure. Combinators like `tuple()`
|
|
286
|
-
* and `object()` sort or flatten usage by priority rather than token order,
|
|
287
|
-
* so the results can be inaccurate—both false positives (e.g., options
|
|
288
|
-
* appearing before commands due to priority sorting) and false negatives
|
|
289
|
-
* (e.g., options after commands that are actually parallel peers).
|
|
290
|
-
* The proper fix is to use `Parser.leadingNames` instead of usage-tree
|
|
291
|
-
* analysis.
|
|
292
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
293
|
-
*
|
|
294
|
-
* @param usage The usage description to extract leading option names from.
|
|
295
|
-
* @param includeHidden Whether to include fully hidden options
|
|
296
|
-
* (`hidden: true`) in the result. Defaults to `false`.
|
|
297
|
-
* @returns A set of option names reachable at the leading token position.
|
|
298
|
-
* @since 1.0.0
|
|
299
|
-
*/
|
|
300
|
-
declare function extractLeadingOptionNames(usage: Usage, includeHidden?: boolean): Set<string>;
|
|
301
|
-
/**
|
|
302
|
-
* Extracts command names that could match as the first positional token.
|
|
303
|
-
*
|
|
304
|
-
* Unlike {@link extractCommandNames}, which traverses the entire usage tree,
|
|
305
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
306
|
-
* `argument`, or `literal` term, because subsequent terms in that array are
|
|
307
|
-
* scoped under that positional token (reachable only after the leading term
|
|
308
|
-
* is consumed). It still recurses into `optional`, `multiple`, and
|
|
309
|
-
* `exclusive` containers, since they represent alternatives or optional
|
|
310
|
-
* wrappers at the same token position.
|
|
311
|
-
*
|
|
312
|
-
* Known limitation: this function has the same usage-tree ordering caveat
|
|
313
|
-
* as {@link extractLeadingOptionNames}.
|
|
314
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
315
|
-
*
|
|
316
|
-
* @param usage The usage description to extract leading command names from.
|
|
317
|
-
* @param includeHidden Whether to include fully hidden commands
|
|
318
|
-
* (`hidden: true`) in the result. Defaults to `false`.
|
|
319
|
-
* @returns A set of command names that could match at the first token position.
|
|
320
|
-
* @since 1.0.0
|
|
321
|
-
*/
|
|
322
|
-
declare function extractLeadingCommandNames(usage: Usage, includeHidden?: boolean): Set<string>;
|
|
323
|
-
/**
|
|
324
|
-
* Extracts literal values that could match as the first positional token.
|
|
325
|
-
*
|
|
326
|
-
* Unlike {@link extractLiteralValues}, which traverses the entire usage tree,
|
|
327
|
-
* this function stops scanning a terms array after encountering a `command`,
|
|
328
|
-
* `argument`, or `literal` term, because subsequent terms in that array are
|
|
329
|
-
* scoped under that positional token. It still recurses into `optional`,
|
|
330
|
-
* `multiple`, and `exclusive` containers.
|
|
331
|
-
*
|
|
332
|
-
* Literals tagged with `optionValue: true` (produced by
|
|
333
|
-
* `appendLiteralToUsage()` when rewriting option metavars for
|
|
334
|
-
* `conditional()` discriminators) are skipped, because they represent
|
|
335
|
-
* option values rather than standalone positional tokens.
|
|
336
|
-
*
|
|
337
|
-
* Known limitation: this function has the same usage-tree ordering caveat
|
|
338
|
-
* as {@link extractLeadingOptionNames}.
|
|
339
|
-
* See https://github.com/dahlia/optique/issues/735
|
|
340
|
-
*
|
|
341
|
-
* @param usage The usage description to extract leading literal values from.
|
|
342
|
-
* @returns A set of literal values that could match at the first token
|
|
343
|
-
* position.
|
|
344
|
-
* @since 1.0.0
|
|
345
|
-
*/
|
|
346
|
-
declare function extractLeadingLiteralValues(usage: Usage): Set<string>;
|
|
347
273
|
/**
|
|
348
274
|
* Extracts all literal values from a usage description.
|
|
349
275
|
*
|
|
@@ -520,4 +446,4 @@ interface UsageTermFormatOptions extends UsageFormatOptions {
|
|
|
520
446
|
*/
|
|
521
447
|
declare function formatUsageTerm(term: UsageTerm, options?: UsageTermFormatOptions): string;
|
|
522
448
|
//#endregion
|
|
523
|
-
export { HiddenVisibility, OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, cloneUsage, cloneUsageTerm, extractArgumentMetavars, extractCommandNames,
|
|
449
|
+
export { HiddenVisibility, OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, cloneUsage, cloneUsageTerm, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, formatUsage, formatUsageTerm, isDocHidden, isSuggestionHidden, isUsageHidden, mergeHidden, normalizeUsage };
|