@optique/core 1.1.0-dev.2087 → 1.1.0-dev.2146

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.
Files changed (74) hide show
  1. package/dist/annotation-state.cjs +26 -26
  2. package/dist/annotation-state.d.cts +133 -1
  3. package/dist/annotation-state.d.ts +133 -1
  4. package/dist/annotations.cjs +2 -2
  5. package/dist/constructs.cjs +873 -73
  6. package/dist/constructs.d.cts +72 -1
  7. package/dist/constructs.d.ts +72 -1
  8. package/dist/constructs.js +808 -9
  9. package/dist/dependency-metadata.cjs +12 -12
  10. package/dist/dependency-metadata.d.cts +34 -3
  11. package/dist/dependency-metadata.d.ts +34 -3
  12. package/dist/dependency-runtime.cjs +37 -13
  13. package/dist/dependency-runtime.d.cts +197 -2
  14. package/dist/dependency-runtime.d.ts +197 -2
  15. package/dist/dependency-runtime.js +22 -1
  16. package/dist/dependency.cjs +7 -7
  17. package/dist/displaywidth.d.cts +12 -0
  18. package/dist/displaywidth.d.ts +12 -0
  19. package/dist/doc.cjs +3 -0
  20. package/dist/doc.js +3 -0
  21. package/dist/execution-context.d.cts +23 -0
  22. package/dist/execution-context.d.ts +23 -0
  23. package/dist/extension.cjs +14 -14
  24. package/dist/facade.cjs +49 -37
  25. package/dist/facade.js +34 -22
  26. package/dist/index.cjs +23 -21
  27. package/dist/index.d.cts +3 -3
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +4 -4
  30. package/dist/input-trace.d.cts +2 -1
  31. package/dist/input-trace.d.ts +2 -1
  32. package/dist/internal/annotations.cjs +3 -0
  33. package/dist/internal/annotations.d.cts +47 -5
  34. package/dist/internal/annotations.d.ts +47 -5
  35. package/dist/internal/annotations.js +1 -1
  36. package/dist/internal/command-alias.cjs +16 -0
  37. package/dist/internal/command-alias.js +14 -0
  38. package/dist/internal/dependency.cjs +131 -0
  39. package/dist/internal/dependency.d.cts +311 -2
  40. package/dist/internal/dependency.d.ts +311 -2
  41. package/dist/internal/dependency.js +119 -1
  42. package/dist/internal/parser.cjs +108 -23
  43. package/dist/internal/parser.d.cts +58 -3
  44. package/dist/internal/parser.d.ts +58 -3
  45. package/dist/internal/parser.js +101 -16
  46. package/dist/modifiers.cjs +74 -44
  47. package/dist/modifiers.js +34 -4
  48. package/dist/parser.cjs +11 -11
  49. package/dist/phase2-seed.cjs +2 -2
  50. package/dist/phase2-seed.d.cts +50 -0
  51. package/dist/phase2-seed.d.ts +50 -0
  52. package/dist/primitives.cjs +104 -33
  53. package/dist/primitives.d.cts +10 -0
  54. package/dist/primitives.d.ts +10 -0
  55. package/dist/primitives.js +84 -13
  56. package/dist/suggestion.cjs +72 -2
  57. package/dist/suggestion.d.cts +188 -0
  58. package/dist/suggestion.d.ts +188 -0
  59. package/dist/suggestion.js +71 -3
  60. package/dist/usage-internals.cjs +14 -6
  61. package/dist/usage-internals.js +14 -6
  62. package/dist/usage.cjs +33 -8
  63. package/dist/usage.d.cts +31 -0
  64. package/dist/usage.d.ts +31 -0
  65. package/dist/usage.js +33 -8
  66. package/dist/validate.cjs +1 -0
  67. package/dist/validate.d.cts +99 -0
  68. package/dist/validate.d.ts +99 -0
  69. package/dist/validate.js +1 -1
  70. package/dist/valueparser.cjs +333 -79
  71. package/dist/valueparser.d.cts +197 -1
  72. package/dist/valueparser.d.ts +197 -1
  73. package/dist/valueparser.js +334 -81
  74. package/package.json +19 -4
package/dist/modifiers.js CHANGED
@@ -12,6 +12,11 @@ function isTerminalMultipleItemState(state) {
12
12
  const unwrapped = unwrapMultipleItemState(state).value;
13
13
  return unwrapped != null && typeof unwrapped === "object" && Object.hasOwn(unwrapped, "success") && typeof unwrapped.success === "boolean";
14
14
  }
15
+ function isMatchedCommandParserState(parser, state) {
16
+ if (Reflect.get(parser, Symbol.for("@optique/core/commandParser")) !== true) return false;
17
+ const unwrapped = unwrapMultipleItemState(state).value;
18
+ return Array.isArray(unwrapped) && unwrapped.length === 2 && unwrapped[0] === "matched" && typeof unwrapped[1] === "string";
19
+ }
15
20
  function isUnstartedMultipleItemState(state, originalState) {
16
21
  const unwrappedState = unwrapMultipleItemState(state);
17
22
  if (unwrappedState.value == null) return true;
@@ -320,6 +325,11 @@ function optional(parser) {
320
325
  leadingNames: parser.leadingNames,
321
326
  acceptingAnyToken: false,
322
327
  initialState: void 0,
328
+ canSkip(state, exec) {
329
+ if (!Array.isArray(state)) return true;
330
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
331
+ return parser.canSkip?.(innerState, exec) === true;
332
+ },
323
333
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser), parser) } : {},
324
334
  getSuggestRuntimeNodes(state, path) {
325
335
  if (optionalParser.dependencyMetadata?.source != null) return [{
@@ -488,6 +498,11 @@ function withDefault(parser, defaultValue, options) {
488
498
  leadingNames: parser.leadingNames,
489
499
  acceptingAnyToken: false,
490
500
  initialState: void 0,
501
+ canSkip(state, exec) {
502
+ if (!Array.isArray(state)) return true;
503
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
504
+ return parser.canSkip?.(innerState, exec) === true;
505
+ },
491
506
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser), parser) } : {},
492
507
  getSuggestRuntimeNodes(state, path) {
493
508
  if (withDefaultParser.dependencyMetadata?.source != null) return [{
@@ -926,9 +941,11 @@ function multiple(parser, options = {}) {
926
941
  parser,
927
942
  state
928
943
  }] : []);
944
+ const canExtendMultipleItem = (state, itemIndex, exec) => state != null && !isTerminalMultipleItemState(state) && (isMatchedCommandParserState(parser, state) || parser.canSkip?.(state, withChildExecPath(exec, itemIndex)) !== true);
929
945
  const parseSync = (context) => {
930
946
  const currentItemState = context.state.at(-1);
931
- const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
947
+ const currentItemIndex = context.state.length - 1;
948
+ const canExtendCurrent = canExtendMultipleItem(currentItemState, currentItemIndex, context.exec);
932
949
  const canOpenFreshItem = context.state.length < max;
933
950
  if (!canExtendCurrent && !canOpenFreshItem) return {
934
951
  success: true,
@@ -1008,7 +1025,8 @@ function multiple(parser, options = {}) {
1008
1025
  };
1009
1026
  const parseAsync = async (context) => {
1010
1027
  const currentItemState = context.state.at(-1);
1011
- const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
1028
+ const currentItemIndex = context.state.length - 1;
1029
+ const canExtendCurrent = canExtendMultipleItem(currentItemState, currentItemIndex, context.exec);
1012
1030
  const canOpenFreshItem = context.state.length < max;
1013
1031
  if (!canExtendCurrent && !canOpenFreshItem) return {
1014
1032
  success: true,
@@ -1099,6 +1117,11 @@ function multiple(parser, options = {}) {
1099
1117
  leadingNames: parser.leadingNames,
1100
1118
  acceptingAnyToken: min > 0 && (parser.acceptingAnyToken ?? false),
1101
1119
  initialState: [],
1120
+ canSkip(state, exec) {
1121
+ if (state.length < min) return false;
1122
+ const currentItemState = state.at(-1);
1123
+ return !canExtendMultipleItem(currentItemState, state.length - 1, exec);
1124
+ },
1102
1125
  getSuggestRuntimeNodes(state, path) {
1103
1126
  const innerNodes = state.flatMap((item, i) => [...getInnerSuggestRuntimeNodes(item, [...path, i])]);
1104
1127
  return resultParser.dependencyMetadata?.source != null ? [{
@@ -1198,7 +1221,8 @@ function multiple(parser, options = {}) {
1198
1221
  },
1199
1222
  suggest(context, prefix) {
1200
1223
  const currentItemState = context.state.at(-1);
1201
- const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
1224
+ const currentItemIndex = context.state.length - 1;
1225
+ const canExtendCurrent = canExtendMultipleItem(currentItemState, currentItemIndex, context.exec);
1202
1226
  const canOpenNew = context.state.length < max;
1203
1227
  if (!canExtendCurrent && !canOpenNew) return dispatchIterableByMode(parser.mode, function* () {}, async function* () {});
1204
1228
  const itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
@@ -1484,6 +1508,7 @@ function multiple(parser, options = {}) {
1484
1508
  */
1485
1509
  function nonEmpty(parser) {
1486
1510
  const syncParser = parser;
1511
+ const initialState = parser.initialState;
1487
1512
  const processNonEmptyResult = (result) => {
1488
1513
  if (!result.success) return result;
1489
1514
  if (result.consumed.length === 0) return {
@@ -1509,7 +1534,12 @@ function nonEmpty(parser) {
1509
1534
  usage: parser.usage,
1510
1535
  leadingNames: parser.leadingNames,
1511
1536
  acceptingAnyToken: parser.acceptingAnyToken,
1512
- initialState: parser.initialState,
1537
+ initialState,
1538
+ ...typeof parser.canSkip === "function" ? { canSkip(state, exec) {
1539
+ const unwrappedState = unwrapInjectedAnnotationWrapper(state);
1540
+ if (unwrappedState === initialState) return false;
1541
+ return parser.canSkip?.(unwrappedState, exec) === true;
1542
+ } } : {},
1513
1543
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: parser.shouldDeferCompletion.bind(parser) } : {},
1514
1544
  getSuggestRuntimeNodes(state, path) {
1515
1545
  return parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
package/dist/parser.cjs CHANGED
@@ -1,12 +1,12 @@
1
- const require_parser = require('./internal/parser.cjs');
1
+ const require_internal_parser = require('./internal/parser.cjs');
2
2
 
3
- exports.createParserContext = require_parser.createParserContext;
4
- exports.getDocPage = require_parser.getDocPage;
5
- exports.getDocPageAsync = require_parser.getDocPageAsync;
6
- exports.getDocPageSync = require_parser.getDocPageSync;
7
- exports.parse = require_parser.parse;
8
- exports.parseAsync = require_parser.parseAsync;
9
- exports.parseSync = require_parser.parseSync;
10
- exports.suggest = require_parser.suggest;
11
- exports.suggestAsync = require_parser.suggestAsync;
12
- exports.suggestSync = require_parser.suggestSync;
3
+ exports.createParserContext = require_internal_parser.createParserContext;
4
+ exports.getDocPage = require_internal_parser.getDocPage;
5
+ exports.getDocPageAsync = require_internal_parser.getDocPageAsync;
6
+ exports.getDocPageSync = require_internal_parser.getDocPageSync;
7
+ exports.parse = require_internal_parser.parse;
8
+ exports.parseAsync = require_internal_parser.parseAsync;
9
+ exports.parseSync = require_internal_parser.parseSync;
10
+ exports.suggest = require_internal_parser.suggest;
11
+ exports.suggestAsync = require_internal_parser.suggestAsync;
12
+ exports.suggestSync = require_internal_parser.suggestSync;
@@ -1,4 +1,4 @@
1
- const require_annotations = require('./internal/annotations.cjs');
1
+ const require_internal_annotations = require('./internal/annotations.cjs');
2
2
  const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
3
3
 
4
4
  //#region src/phase2-seed.ts
@@ -15,7 +15,7 @@ const extractPhase2SeedKey = Symbol("@optique/core/extractPhase2Seed");
15
15
  */
16
16
  function phase2SeedFromValueResult(result) {
17
17
  return {
18
- value: require_annotations.unwrapInjectedAnnotationWrapper(result.value),
18
+ value: require_internal_annotations.unwrapInjectedAnnotationWrapper(result.value),
19
19
  ...result.deferred ? { deferred: true } : {},
20
20
  ...result.deferredKeys != null ? { deferredKeys: result.deferredKeys } : {}
21
21
  };
@@ -0,0 +1,50 @@
1
+ import { DeferredMap, ValueParserResult } from "./valueparser.cjs";
2
+ import { ExecutionContext, Mode, ModeValue, Parser } from "./internal/parser.cjs";
3
+
4
+ //#region src/phase2-seed.d.ts
5
+
6
+ /**
7
+ * Best-effort parser value used for phase-two context collection.
8
+ *
9
+ * @internal
10
+ */
11
+ interface Phase2Seed<T = unknown> {
12
+ readonly value: T;
13
+ readonly deferred?: true;
14
+ readonly deferredKeys?: DeferredMap;
15
+ }
16
+ /**
17
+ * Internal hook for extracting a best-effort phase-two seed from parser state.
18
+ *
19
+ * @internal
20
+ */
21
+ type Phase2SeedExtractor<M extends Mode = Mode, TState = unknown, TValue = unknown> = (state: TState, exec?: ExecutionContext) => ModeValue<M, Phase2Seed<TValue> | null>;
22
+ /**
23
+ * Internal parser hook key for phase-two seed extraction.
24
+ *
25
+ * @internal
26
+ */
27
+ declare const extractPhase2SeedKey: unique symbol;
28
+ /**
29
+ * Converts a successful complete() result into a phase-two seed.
30
+ *
31
+ * @internal
32
+ */
33
+ declare function phase2SeedFromValueResult<T>(result: Extract<ValueParserResult<T>, {
34
+ readonly success: true;
35
+ }>): Phase2Seed<T>;
36
+ /**
37
+ * Invokes a parser's internal phase-two seed hook when present.
38
+ *
39
+ * @internal
40
+ */
41
+ declare function extractPhase2Seed<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, state: TState, exec?: ExecutionContext): ModeValue<M, Phase2Seed<TValue> | null>;
42
+ /**
43
+ * Attempts to complete a parser and falls back to the internal phase-two
44
+ * seed hook when completion returns an unsuccessful result.
45
+ *
46
+ * @internal
47
+ */
48
+ declare function completeOrExtractPhase2Seed<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, state: TState, exec?: ExecutionContext): ModeValue<M, Phase2Seed<TValue> | null>;
49
+ //#endregion
50
+ export { Phase2Seed, Phase2SeedExtractor, completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult };
@@ -0,0 +1,50 @@
1
+ import { DeferredMap, ValueParserResult } from "./valueparser.js";
2
+ import { ExecutionContext, Mode, ModeValue, Parser } from "./internal/parser.js";
3
+
4
+ //#region src/phase2-seed.d.ts
5
+
6
+ /**
7
+ * Best-effort parser value used for phase-two context collection.
8
+ *
9
+ * @internal
10
+ */
11
+ interface Phase2Seed<T = unknown> {
12
+ readonly value: T;
13
+ readonly deferred?: true;
14
+ readonly deferredKeys?: DeferredMap;
15
+ }
16
+ /**
17
+ * Internal hook for extracting a best-effort phase-two seed from parser state.
18
+ *
19
+ * @internal
20
+ */
21
+ type Phase2SeedExtractor<M extends Mode = Mode, TState = unknown, TValue = unknown> = (state: TState, exec?: ExecutionContext) => ModeValue<M, Phase2Seed<TValue> | null>;
22
+ /**
23
+ * Internal parser hook key for phase-two seed extraction.
24
+ *
25
+ * @internal
26
+ */
27
+ declare const extractPhase2SeedKey: unique symbol;
28
+ /**
29
+ * Converts a successful complete() result into a phase-two seed.
30
+ *
31
+ * @internal
32
+ */
33
+ declare function phase2SeedFromValueResult<T>(result: Extract<ValueParserResult<T>, {
34
+ readonly success: true;
35
+ }>): Phase2Seed<T>;
36
+ /**
37
+ * Invokes a parser's internal phase-two seed hook when present.
38
+ *
39
+ * @internal
40
+ */
41
+ declare function extractPhase2Seed<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, state: TState, exec?: ExecutionContext): ModeValue<M, Phase2Seed<TValue> | null>;
42
+ /**
43
+ * Attempts to complete a parser and falls back to the internal phase-two
44
+ * seed hook when completion returns an unsuccessful result.
45
+ *
46
+ * @internal
47
+ */
48
+ declare function completeOrExtractPhase2Seed<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, state: TState, exec?: ExecutionContext): ModeValue<M, Phase2Seed<TValue> | null>;
49
+ //#endregion
50
+ export { Phase2Seed, Phase2SeedExtractor, completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult };
@@ -1,11 +1,12 @@
1
- const require_annotations = require('./internal/annotations.cjs');
1
+ const require_internal_annotations = require('./internal/annotations.cjs');
2
2
  const require_message = require('./message.cjs');
3
3
  const require_validate = require('./validate.cjs');
4
4
  const require_usage = require('./usage.cjs');
5
5
  const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
6
- const require_dependency = require('./internal/dependency.cjs');
6
+ const require_internal_dependency = require('./internal/dependency.cjs');
7
7
  const require_dependency_runtime = require('./dependency-runtime.cjs');
8
8
  const require_annotation_state = require('./annotation-state.cjs');
9
+ const require_command_alias = require('./internal/command-alias.cjs');
9
10
  const require_execution_context = require('./execution-context.cjs');
10
11
  const require_phase2_seed = require('./phase2-seed.cjs');
11
12
  const require_suggestion = require('./suggestion.cjs');
@@ -23,6 +24,9 @@ function hasParsedOptionValue(state, valueParser) {
23
24
  if (valueParser != null) return state != null && typeof state === "object" && "success" in state && typeof state.success === "boolean";
24
25
  return state != null && "success" in state && state.success && state.value === true;
25
26
  }
27
+ function isTerminalValueState(state) {
28
+ return state != null && typeof state === "object" && "success" in state && typeof state.success === "boolean";
29
+ }
26
30
  /**
27
31
  * Helper function to create the stored state for an option or argument value.
28
32
  *
@@ -43,8 +47,8 @@ function buildTraceEntry(kind, rawInput, consumed, valueParser, parseResult, opt
43
47
  ...optionNames$1 != null ? { optionNames: optionNames$1 } : {},
44
48
  metavar: valueParser.metavar
45
49
  };
46
- if (require_dependency.isDerivedValueParser(valueParser)) {
47
- const defaults = require_dependency.getSnapshottedDefaultDependencyValues(parseResult);
50
+ if (require_internal_dependency.isDerivedValueParser(valueParser)) {
51
+ const defaults = require_internal_dependency.getSnapshottedDefaultDependencyValues(parseResult);
48
52
  if (defaults != null) return {
49
53
  ...entry,
50
54
  defaultDependencyValues: defaults
@@ -117,6 +121,9 @@ function constant(value) {
117
121
  leadingNames: EMPTY_LEADING_NAMES,
118
122
  acceptingAnyToken: false,
119
123
  initialState: value,
124
+ canSkip() {
125
+ return true;
126
+ },
120
127
  parse(context) {
121
128
  return {
122
129
  success: true,
@@ -174,6 +181,9 @@ function fail() {
174
181
  leadingNames: EMPTY_LEADING_NAMES,
175
182
  acceptingAnyToken: false,
176
183
  initialState: void 0,
184
+ canSkip() {
185
+ return false;
186
+ },
177
187
  parse(_context) {
178
188
  return {
179
189
  success: false,
@@ -202,13 +212,13 @@ function fail() {
202
212
  */
203
213
  function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry, exec) {
204
214
  if (!valueParser.suggest) return;
205
- if (require_dependency.isDerivedValueParser(valueParser) && require_dependency.suggestWithDependency in valueParser) {
215
+ if (require_internal_dependency.isDerivedValueParser(valueParser) && require_internal_dependency.suggestWithDependency in valueParser) {
206
216
  const derived = valueParser;
207
- const suggestWithDep = derived[require_dependency.suggestWithDependency];
217
+ const suggestWithDep = derived[require_internal_dependency.suggestWithDependency];
208
218
  if (suggestWithDep && dependencyRegistry) {
209
219
  const dependencyRuntime = exec?.dependencyRuntime;
210
- const depIds = require_dependency.getDependencyIds(derived);
211
- const defaultsFn = require_dependency.getDefaultValuesFunction(derived);
220
+ const depIds = require_internal_dependency.getDependencyIds(derived);
221
+ const defaultsFn = require_internal_dependency.getDefaultValuesFunction(derived);
212
222
  const defaults = defaultsFn?.();
213
223
  const dependencyValues = [];
214
224
  let hasAnyValue = false;
@@ -286,13 +296,13 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
286
296
  */
287
297
  async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependencyRegistry, exec) {
288
298
  if (!valueParser.suggest) return;
289
- if (require_dependency.isDerivedValueParser(valueParser) && require_dependency.suggestWithDependency in valueParser) {
299
+ if (require_internal_dependency.isDerivedValueParser(valueParser) && require_internal_dependency.suggestWithDependency in valueParser) {
290
300
  const derived = valueParser;
291
- const suggestWithDep = derived[require_dependency.suggestWithDependency];
301
+ const suggestWithDep = derived[require_internal_dependency.suggestWithDependency];
292
302
  if (suggestWithDep && dependencyRegistry) {
293
303
  const dependencyRuntime = exec?.dependencyRuntime;
294
- const depIds = require_dependency.getDependencyIds(derived);
295
- const defaultsFn = require_dependency.getDefaultValuesFunction(derived);
304
+ const depIds = require_internal_dependency.getDependencyIds(derived);
305
+ const defaultsFn = require_internal_dependency.getDefaultValuesFunction(derived);
296
306
  const defaults = defaultsFn?.();
297
307
  const dependencyValues = [];
298
308
  let hasAnyValue = false;
@@ -431,6 +441,9 @@ function option(...args) {
431
441
  success: true,
432
442
  value: false
433
443
  } : void 0,
444
+ canSkip(state) {
445
+ return valueParser == null || isTerminalValueState(state);
446
+ },
434
447
  parse(context) {
435
448
  if (context.optionsTerminated) return {
436
449
  success: false,
@@ -678,7 +691,7 @@ function option(...args) {
678
691
  configurable: true,
679
692
  enumerable: false
680
693
  });
681
- else if (!require_dependency.isDerivedValueParser(valueParser)) {
694
+ else if (!require_internal_dependency.isDerivedValueParser(valueParser)) {
682
695
  const vp = valueParser;
683
696
  const wrapParseResult = (parsed) => parsed.success ? parsed : {
684
697
  success: false,
@@ -686,6 +699,7 @@ function option(...args) {
686
699
  };
687
700
  Object.defineProperty(result, "validateValue", {
688
701
  value(v) {
702
+ if (typeof vp.validate === "function") return require_mode_dispatch.wrapForMode(mode, wrapParseResult(vp.validate(v)));
689
703
  let stringified;
690
704
  try {
691
705
  stringified = vp.format(v);
@@ -782,6 +796,9 @@ function flag(...args) {
782
796
  leadingNames: new Set(optionNames$1),
783
797
  acceptingAnyToken: false,
784
798
  initialState: void 0,
799
+ canSkip(state) {
800
+ return isTerminalValueState(state);
801
+ },
785
802
  parse(context) {
786
803
  if (context.optionsTerminated) return {
787
804
  success: false,
@@ -1013,6 +1030,9 @@ function negatableFlag(names, options = {}) {
1013
1030
  leadingNames: new Set(optionNames$1),
1014
1031
  acceptingAnyToken: false,
1015
1032
  initialState: void 0,
1033
+ canSkip(state) {
1034
+ return state != null;
1035
+ },
1016
1036
  parse(context) {
1017
1037
  if (context.optionsTerminated) return {
1018
1038
  success: false,
@@ -1177,6 +1197,9 @@ function argument(valueParser, options = {}) {
1177
1197
  leadingNames: EMPTY_LEADING_NAMES,
1178
1198
  acceptingAnyToken: true,
1179
1199
  initialState: void 0,
1200
+ canSkip(state) {
1201
+ return isTerminalValueState(state);
1202
+ },
1180
1203
  parse(context) {
1181
1204
  const localState = require_annotation_state.normalizeInjectedAnnotationState(context.state);
1182
1205
  if (context.buffer.length < 1) return {
@@ -1303,7 +1326,7 @@ function argument(valueParser, options = {}) {
1303
1326
  enumerable: false
1304
1327
  });
1305
1328
  }
1306
- if (!require_dependency.isDerivedValueParser(valueParser)) {
1329
+ if (!require_internal_dependency.isDerivedValueParser(valueParser)) {
1307
1330
  const vp = valueParser;
1308
1331
  const vpMode = valueParser.mode;
1309
1332
  const wrapParseResult = (parsed) => parsed.success ? parsed : {
@@ -1312,6 +1335,7 @@ function argument(valueParser, options = {}) {
1312
1335
  };
1313
1336
  Object.defineProperty(result, "validateValue", {
1314
1337
  value(v) {
1338
+ if (typeof vp.validate === "function") return require_mode_dispatch.wrapForMode(vpMode, wrapParseResult(vp.validate(v)));
1315
1339
  let stringified;
1316
1340
  try {
1317
1341
  stringified = vp.format(v);
@@ -1359,7 +1383,7 @@ function getCommandChildState(commandState, childState, parser) {
1359
1383
  return require_annotation_state.getWrappedChildState(commandState, childState, parser);
1360
1384
  }
1361
1385
  function createCommandState(sourceState, state) {
1362
- return require_annotations.annotateFreshArray(sourceState, state);
1386
+ return require_internal_annotations.annotateFreshArray(sourceState, state);
1363
1387
  }
1364
1388
  function appendCommandPath(exec, name) {
1365
1389
  if (exec == null) return void 0;
@@ -1368,25 +1392,56 @@ function appendCommandPath(exec, name) {
1368
1392
  commandPath: [...exec.commandPath ?? [], name]
1369
1393
  };
1370
1394
  }
1371
- function* suggestCommandSync(context, prefix, name, parser, options) {
1395
+ function getCommandNames(name, options) {
1396
+ return [
1397
+ name,
1398
+ ...getVisibleCommandAliases(options),
1399
+ ...getHiddenCommandAliases(options)
1400
+ ];
1401
+ }
1402
+ function getVisibleCommandAliases(options) {
1403
+ const aliases = options.aliases;
1404
+ if (aliases == null) return [];
1405
+ if (!isNonEmptyStringArray(aliases)) throw new TypeError("Command aliases must be a non-empty array of strings.");
1406
+ return aliases;
1407
+ }
1408
+ function getHiddenCommandAliases(options) {
1409
+ const hiddenAliases = options[require_command_alias.hiddenCommandAliasesKey];
1410
+ if (hiddenAliases == null) return [];
1411
+ if (!isNonEmptyStringArray(hiddenAliases)) throw new TypeError("Hidden command aliases must be a non-empty array of strings.");
1412
+ return hiddenAliases;
1413
+ }
1414
+ function isNonEmptyStringArray(value) {
1415
+ if (!Array.isArray(value) || value.length === 0) return false;
1416
+ for (let i = 0; i < value.length; i++) if (typeof value[i] !== "string") return false;
1417
+ return true;
1418
+ }
1419
+ function validateUniqueCommandNames(names) {
1420
+ const seen = /* @__PURE__ */ new Set();
1421
+ for (const name of names) {
1422
+ if (seen.has(name)) throw new TypeError(`Command has a duplicate name: "${name}".`);
1423
+ seen.add(name);
1424
+ }
1425
+ }
1426
+ function* suggestCommandSync(context, prefix, name, aliases, parser, options) {
1372
1427
  if (require_usage.isSuggestionHidden(options.hidden)) return;
1373
1428
  const state = normalizeCommandState(context.state);
1374
1429
  if (state === void 0) {
1375
- if (name.startsWith(prefix)) yield {
1430
+ for (const commandName of [name, ...aliases]) if (commandName.startsWith(prefix)) yield {
1376
1431
  kind: "literal",
1377
- text: name,
1432
+ text: commandName,
1378
1433
  ...options.description && { description: options.description }
1379
1434
  };
1380
1435
  } else if (state[0] === "matched") yield* parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, parser.initialState, parser), parser.usage), prefix);
1381
1436
  else if (state[0] === "parsing") yield* parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, state[1], parser), parser.usage), prefix);
1382
1437
  }
1383
- async function* suggestCommandAsync(context, prefix, name, parser, options) {
1438
+ async function* suggestCommandAsync(context, prefix, name, aliases, parser, options) {
1384
1439
  if (require_usage.isSuggestionHidden(options.hidden)) return;
1385
1440
  const state = normalizeCommandState(context.state);
1386
1441
  if (state === void 0) {
1387
- if (name.startsWith(prefix)) yield {
1442
+ for (const commandName of [name, ...aliases]) if (commandName.startsWith(prefix)) yield {
1388
1443
  kind: "literal",
1389
- text: name,
1444
+ text: commandName,
1390
1445
  ...options.description && { description: options.description }
1391
1446
  };
1392
1447
  } else if (state[0] === "matched") {
@@ -1414,7 +1469,11 @@ async function* suggestCommandAsync(context, prefix, name, parser, options) {
1414
1469
  * embedded whitespace, or contains control characters.
1415
1470
  */
1416
1471
  function command(name, parser, options = {}) {
1417
- require_validate.validateCommandNames([name], "Command");
1472
+ const commandNames = getCommandNames(name, options);
1473
+ const aliases = getVisibleCommandAliases(options);
1474
+ const hiddenAliases = getHiddenCommandAliases(options);
1475
+ require_validate.validateCommandNames(commandNames, "Command");
1476
+ validateUniqueCommandNames(commandNames);
1418
1477
  const isAsync = parser.mode === "async";
1419
1478
  const syncInnerParser = parser;
1420
1479
  const asyncInnerParser = parser;
@@ -1427,12 +1486,20 @@ function command(name, parser, options = {}) {
1427
1486
  usage: [{
1428
1487
  type: "command",
1429
1488
  name,
1489
+ ...aliases.length > 0 && { aliases },
1490
+ ...hiddenAliases.length > 0 && { hiddenAliases },
1430
1491
  ...options.usageLine != null && { usageLine: options.usageLine },
1431
1492
  ...options.hidden != null && { hidden: options.hidden }
1432
1493
  }, ...parser.usage],
1433
- leadingNames: new Set([name]),
1494
+ leadingNames: new Set(commandNames),
1434
1495
  acceptingAnyToken: false,
1435
1496
  initialState: void 0,
1497
+ canSkip(state, exec) {
1498
+ const normalizedState = normalizeCommandState(state);
1499
+ if (normalizedState === void 0) return false;
1500
+ if (normalizedState[0] === "matched") return parser.canSkip?.(getCommandChildState(state, parser.initialState, parser), require_execution_context.withChildExecPath(exec, name)) === true;
1501
+ return parser.canSkip?.(getCommandChildState(state, normalizedState[1], parser), require_execution_context.withChildExecPath(exec, name)) === true;
1502
+ },
1436
1503
  getSuggestRuntimeNodes(state, path) {
1437
1504
  const normalizedState = normalizeCommandState(state);
1438
1505
  if (normalizedState === void 0) return [];
@@ -1447,10 +1514,11 @@ function command(name, parser, options = {}) {
1447
1514
  parse(context) {
1448
1515
  const state = normalizeCommandState(context.state);
1449
1516
  if (state === void 0) {
1450
- if (context.buffer.length < 1 || context.buffer[0] !== name) {
1517
+ if (context.buffer.length < 1 || !commandNames.includes(context.buffer[0])) {
1451
1518
  const actual = context.buffer.length > 0 ? context.buffer[0] : null;
1452
1519
  const leadingCmds = require_usage_internals.extractLeadingCommandNames(context.usage);
1453
- const suggestions = actual ? require_suggestion.findSimilar(actual, leadingCmds, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS) : [];
1520
+ const rawSuggestions = actual ? require_suggestion.findSimilar(actual, leadingCmds, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS) : [];
1521
+ const suggestions = require_suggestion.expandCommandAliasSuggestions(context.usage, rawSuggestions);
1454
1522
  if (options.errors?.notMatched) {
1455
1523
  const errorMessage = options.errors.notMatched;
1456
1524
  return {
@@ -1581,8 +1649,8 @@ function command(name, parser, options = {}) {
1581
1649
  return require_mode_dispatch.wrapForMode(parser.mode, null);
1582
1650
  },
1583
1651
  suggest(context, prefix) {
1584
- if (isAsync) return suggestCommandAsync(context, prefix, name, parser, options);
1585
- return suggestCommandSync(context, prefix, name, parser, options);
1652
+ if (isAsync) return suggestCommandAsync(context, prefix, name, aliases, parser, options);
1653
+ return suggestCommandSync(context, prefix, name, aliases, parser, options);
1586
1654
  },
1587
1655
  getDocFragments(state, defaultValue) {
1588
1656
  const commandState = state.kind === "available" ? normalizeCommandState(state.state) : void 0;
@@ -1696,6 +1764,9 @@ function passThrough(options = {}) {
1696
1764
  leadingNames: EMPTY_LEADING_NAMES,
1697
1765
  acceptingAnyToken: false,
1698
1766
  initialState: [],
1767
+ canSkip() {
1768
+ return true;
1769
+ },
1699
1770
  parse(context) {
1700
1771
  if (context.buffer.length < 1) return {
1701
1772
  success: false,
@@ -1710,7 +1781,7 @@ function passThrough(options = {}) {
1710
1781
  next: {
1711
1782
  ...context,
1712
1783
  buffer: [],
1713
- state: require_annotations.annotateFreshArray(context.state, [...context.state, ...captured])
1784
+ state: require_internal_annotations.annotateFreshArray(context.state, [...context.state, ...captured])
1714
1785
  },
1715
1786
  consumed: captured
1716
1787
  };
@@ -1731,7 +1802,7 @@ function passThrough(options = {}) {
1731
1802
  next: {
1732
1803
  ...context,
1733
1804
  buffer: context.buffer.slice(1),
1734
- state: require_annotations.annotateFreshArray(context.state, [...context.state, token])
1805
+ state: require_internal_annotations.annotateFreshArray(context.state, [...context.state, token])
1735
1806
  },
1736
1807
  consumed: [token]
1737
1808
  };
@@ -1747,7 +1818,7 @@ function passThrough(options = {}) {
1747
1818
  next: {
1748
1819
  ...context,
1749
1820
  buffer: context.buffer.slice(1),
1750
- state: require_annotations.annotateFreshArray(context.state, [...context.state, token])
1821
+ state: require_internal_annotations.annotateFreshArray(context.state, [...context.state, token])
1751
1822
  },
1752
1823
  consumed: [token]
1753
1824
  };
@@ -1757,7 +1828,7 @@ function passThrough(options = {}) {
1757
1828
  next: {
1758
1829
  ...context,
1759
1830
  buffer: context.buffer.slice(2),
1760
- state: require_annotations.annotateFreshArray(context.state, [
1831
+ state: require_internal_annotations.annotateFreshArray(context.state, [
1761
1832
  ...context.state,
1762
1833
  token,
1763
1834
  nextToken
@@ -1770,7 +1841,7 @@ function passThrough(options = {}) {
1770
1841
  next: {
1771
1842
  ...context,
1772
1843
  buffer: context.buffer.slice(1),
1773
- state: require_annotations.annotateFreshArray(context.state, [...context.state, token])
1844
+ state: require_internal_annotations.annotateFreshArray(context.state, [...context.state, token])
1774
1845
  },
1775
1846
  consumed: [token]
1776
1847
  };
@@ -1782,7 +1853,7 @@ function passThrough(options = {}) {
1782
1853
  };
1783
1854
  },
1784
1855
  complete(state, _exec) {
1785
- if (require_annotations.getAnnotations(state) == null) return {
1856
+ if (require_internal_annotations.getAnnotations(state) == null) return {
1786
1857
  success: true,
1787
1858
  value: state
1788
1859
  };
@@ -448,6 +448,16 @@ interface CommandOptions {
448
448
  * @since 0.9.0
449
449
  */
450
450
  readonly hidden?: HiddenVisibility;
451
+ /**
452
+ * Additional names that invoke this command.
453
+ *
454
+ * Aliases are functional at runtime and are suggested by shell completion,
455
+ * but are hidden from usage and documentation output. The `name` parameter
456
+ * passed to {@link command} remains the canonical display name.
457
+ *
458
+ * @since 1.1.0
459
+ */
460
+ readonly aliases?: readonly [string, ...string[]];
451
461
  /**
452
462
  * Error messages customization.
453
463
  * @since 0.5.0
@@ -448,6 +448,16 @@ interface CommandOptions {
448
448
  * @since 0.9.0
449
449
  */
450
450
  readonly hidden?: HiddenVisibility;
451
+ /**
452
+ * Additional names that invoke this command.
453
+ *
454
+ * Aliases are functional at runtime and are suggested by shell completion,
455
+ * but are hidden from usage and documentation output. The `name` parameter
456
+ * passed to {@link command} remains the canonical display name.
457
+ *
458
+ * @since 1.1.0
459
+ */
460
+ readonly aliases?: readonly [string, ...string[]];
451
461
  /**
452
462
  * Error messages customization.
453
463
  * @since 0.5.0