@optique/core 1.1.0-dev.2086 → 1.1.0-dev.2096
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 +738 -6
- package/dist/constructs.d.cts +72 -1
- package/dist/constructs.d.ts +72 -1
- package/dist/constructs.js +738 -7
- package/dist/doc.cjs +3 -0
- package/dist/doc.js +3 -0
- package/dist/facade.cjs +3 -1
- package/dist/facade.js +3 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/internal/parser.cjs +78 -15
- package/dist/internal/parser.d.cts +14 -0
- package/dist/internal/parser.d.ts +14 -0
- package/dist/internal/parser.js +78 -15
- package/dist/modifiers.cjs +34 -4
- package/dist/modifiers.js +34 -4
- package/dist/primitives.cjs +30 -0
- package/dist/primitives.js +30 -0
- package/dist/usage-internals.cjs +10 -6
- package/dist/usage-internals.js +10 -6
- package/dist/usage.cjs +24 -7
- package/dist/usage.d.cts +17 -0
- package/dist/usage.d.ts +17 -0
- package/dist/usage.js +24 -7
- package/package.json +1 -1
package/dist/doc.cjs
CHANGED
|
@@ -497,6 +497,9 @@ function maxVisibleAtomicWidth(usage) {
|
|
|
497
497
|
max = Math.max(max, maxVisibleAtomicWidth(branch));
|
|
498
498
|
}
|
|
499
499
|
break;
|
|
500
|
+
case "sequence":
|
|
501
|
+
max = Math.max(max, maxVisibleAtomicWidth(term.terms));
|
|
502
|
+
break;
|
|
500
503
|
case "literal":
|
|
501
504
|
if (term.value !== "") max = Math.max(max, require_displaywidth.getDisplayWidth(term.value));
|
|
502
505
|
break;
|
package/dist/doc.js
CHANGED
|
@@ -497,6 +497,9 @@ function maxVisibleAtomicWidth(usage) {
|
|
|
497
497
|
max = Math.max(max, maxVisibleAtomicWidth(branch));
|
|
498
498
|
}
|
|
499
499
|
break;
|
|
500
|
+
case "sequence":
|
|
501
|
+
max = Math.max(max, maxVisibleAtomicWidth(term.terms));
|
|
502
|
+
break;
|
|
500
503
|
case "literal":
|
|
501
504
|
if (term.value !== "") max = Math.max(max, getDisplayWidth(term.value));
|
|
502
505
|
break;
|
package/dist/facade.cjs
CHANGED
|
@@ -824,6 +824,7 @@ function collectRootOptionNamesFromTerm(term, names, rootLeadingNames) {
|
|
|
824
824
|
return;
|
|
825
825
|
case "optional":
|
|
826
826
|
case "multiple":
|
|
827
|
+
case "sequence":
|
|
827
828
|
collectRootOptionNames(term.terms, names, rootLeadingNames);
|
|
828
829
|
return;
|
|
829
830
|
case "exclusive":
|
|
@@ -849,7 +850,7 @@ function collectActiveOptionNames(usage, commandPath, names, fromExclusive, incl
|
|
|
849
850
|
if (rest.length === 0) collectOptionNamesAtCurrentCommandDepth(remainingUsage, names, !fromExclusive && includeDirectAfterCommandOptions);
|
|
850
851
|
else collectActiveOptionNames(remainingUsage, rest, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
851
852
|
} else if (term.type === "exclusive") for (const branch of term.terms) collectActiveOptionNames(branch, commandPath, names, true, includeDirectAfterCommandOptions);
|
|
852
|
-
else if (term.type === "optional" || term.type === "multiple") collectActiveOptionNames(term.terms, commandPath, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
853
|
+
else if (term.type === "optional" || term.type === "multiple" || term.type === "sequence") collectActiveOptionNames(term.terms, commandPath, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
853
854
|
}
|
|
854
855
|
}
|
|
855
856
|
function isRootOptionToken(token, rootOptionSuggestions) {
|
|
@@ -867,6 +868,7 @@ function collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatch
|
|
|
867
868
|
return false;
|
|
868
869
|
case "optional":
|
|
869
870
|
case "multiple":
|
|
871
|
+
case "sequence":
|
|
870
872
|
collectOptionNamesAtCurrentCommandDepth(term.terms, names, afterMatchedCommand);
|
|
871
873
|
return false;
|
|
872
874
|
case "exclusive":
|
package/dist/facade.js
CHANGED
|
@@ -824,6 +824,7 @@ function collectRootOptionNamesFromTerm(term, names, rootLeadingNames) {
|
|
|
824
824
|
return;
|
|
825
825
|
case "optional":
|
|
826
826
|
case "multiple":
|
|
827
|
+
case "sequence":
|
|
827
828
|
collectRootOptionNames(term.terms, names, rootLeadingNames);
|
|
828
829
|
return;
|
|
829
830
|
case "exclusive":
|
|
@@ -849,7 +850,7 @@ function collectActiveOptionNames(usage, commandPath, names, fromExclusive, incl
|
|
|
849
850
|
if (rest.length === 0) collectOptionNamesAtCurrentCommandDepth(remainingUsage, names, !fromExclusive && includeDirectAfterCommandOptions);
|
|
850
851
|
else collectActiveOptionNames(remainingUsage, rest, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
851
852
|
} else if (term.type === "exclusive") for (const branch of term.terms) collectActiveOptionNames(branch, commandPath, names, true, includeDirectAfterCommandOptions);
|
|
852
|
-
else if (term.type === "optional" || term.type === "multiple") collectActiveOptionNames(term.terms, commandPath, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
853
|
+
else if (term.type === "optional" || term.type === "multiple" || term.type === "sequence") collectActiveOptionNames(term.terms, commandPath, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
853
854
|
}
|
|
854
855
|
}
|
|
855
856
|
function isRootOptionToken(token, rootOptionSuggestions) {
|
|
@@ -867,6 +868,7 @@ function collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatch
|
|
|
867
868
|
return false;
|
|
868
869
|
case "optional":
|
|
869
870
|
case "multiple":
|
|
871
|
+
case "sequence":
|
|
870
872
|
collectOptionNamesAtCurrentCommandDepth(term.terms, names, afterMatchedCommand);
|
|
871
873
|
return false;
|
|
872
874
|
case "exclusive":
|
package/dist/index.cjs
CHANGED
|
@@ -108,6 +108,7 @@ exports.runWith = require_facade.runWith;
|
|
|
108
108
|
exports.runWithAsync = require_facade.runWithAsync;
|
|
109
109
|
exports.runWithSync = require_facade.runWithSync;
|
|
110
110
|
exports.semVer = require_valueparser.semVer;
|
|
111
|
+
exports.seq = require_constructs.seq;
|
|
111
112
|
exports.socketAddress = require_valueparser.socketAddress;
|
|
112
113
|
exports.string = require_valueparser.string;
|
|
113
114
|
exports.suggest = require_parser.suggest;
|
package/dist/index.d.cts
CHANGED
|
@@ -6,10 +6,10 @@ import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, Doc
|
|
|
6
6
|
import { ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, DeferredMap, DomainOptions, EmailOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FloatOptions, HostnameOptions, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, LocaleOptions, MacAddressOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, SocketAddressOptions, SocketAddressValue, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, checkBooleanOption, checkEnumOption, choice, cidr, color, domain, email, fileSize, float, hostname, integer, ip, ipv4, ipv6, isValueParser, json, locale, macAddress, port, portRange, semVer, socketAddress, string, url, uuid } from "./valueparser.cjs";
|
|
7
7
|
import { CombineModes, DocState, ExecutionContext, ExecutionPhase, InferMode, InferValue, Mode, ModeIterable, ModeValue, ParseFrame, Parser, ParserContext, ParserResult, Result, Suggestion, createParserContext, getDocPage, getDocPageAsync, getDocPageSync, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync } from "./internal/parser.cjs";
|
|
8
8
|
import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.cjs";
|
|
9
|
-
import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
|
|
9
|
+
import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, SeqOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, seq, tuple } from "./constructs.cjs";
|
|
10
10
|
import { ParserValuePlaceholder, SourceContext, SourceContextRequest } from "./context.cjs";
|
|
11
11
|
import { AnyDependencySource, CombineMode, CombinedDependencyMode, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, dependency, deriveFrom, deriveFromAsync, deriveFromSync, isDependencySource, isDerivedValueParser } from "./internal/dependency.cjs";
|
|
12
12
|
import { CommandSubConfig, ContextOptionsParam, ExtractRequiredOptions, OptionSubConfig, RunOptions, RunParserError, RunWithOptions, SubstituteParserValue, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync } from "./facade.cjs";
|
|
13
13
|
import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.cjs";
|
|
14
14
|
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, fail, flag, negatableFlag, option, passThrough } from "./primitives.cjs";
|
|
15
|
-
export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredMap, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExecutionContext, ExecutionPhase, ExtractRequiredOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, Result, RunOptions, RunParserError, RunWithOptions, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, SourceContextRequest, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
|
|
15
|
+
export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredMap, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExecutionContext, ExecutionPhase, ExtractRequiredOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, Result, RunOptions, RunParserError, RunWithOptions, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, SeqOptions, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, SourceContextRequest, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, seq, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,10 +6,10 @@ import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, Doc
|
|
|
6
6
|
import { ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, DeferredMap, DomainOptions, EmailOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FloatOptions, HostnameOptions, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, LocaleOptions, MacAddressOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, SocketAddressOptions, SocketAddressValue, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, checkBooleanOption, checkEnumOption, choice, cidr, color, domain, email, fileSize, float, hostname, integer, ip, ipv4, ipv6, isValueParser, json, locale, macAddress, port, portRange, semVer, socketAddress, string, url, uuid } from "./valueparser.js";
|
|
7
7
|
import { CombineModes, DocState, ExecutionContext, ExecutionPhase, InferMode, InferValue, Mode, ModeIterable, ModeValue, ParseFrame, Parser, ParserContext, ParserResult, Result, Suggestion, createParserContext, getDocPage, getDocPageAsync, getDocPageSync, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync } from "./internal/parser.js";
|
|
8
8
|
import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.js";
|
|
9
|
-
import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
9
|
+
import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, SeqOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, seq, tuple } from "./constructs.js";
|
|
10
10
|
import { ParserValuePlaceholder, SourceContext, SourceContextRequest } from "./context.js";
|
|
11
11
|
import { AnyDependencySource, CombineMode, CombinedDependencyMode, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, dependency, deriveFrom, deriveFromAsync, deriveFromSync, isDependencySource, isDerivedValueParser } from "./internal/dependency.js";
|
|
12
12
|
import { CommandSubConfig, ContextOptionsParam, ExtractRequiredOptions, OptionSubConfig, RunOptions, RunParserError, RunWithOptions, SubstituteParserValue, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync } from "./facade.js";
|
|
13
13
|
import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
|
|
14
14
|
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, fail, flag, negatableFlag, option, passThrough } from "./primitives.js";
|
|
15
|
-
export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredMap, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExecutionContext, ExecutionPhase, ExtractRequiredOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, Result, RunOptions, RunParserError, RunWithOptions, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, SourceContextRequest, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
|
|
15
|
+
export { type Annotations, AnyDependencySource, ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, ChoiceOptionsBase, ChoiceOptionsNumber, ChoiceOptionsString, CidrOptions, CidrValue, Color, ColorFormat, ColorOptions, CombineMode, CombineModes, CombinedDependencyMode, CommandErrorOptions, CommandOptions, CommandSubConfig, ConditionalErrorOptions, ConditionalOptions, ContextOptionsParam, DeferredMap, DependencyMode, DependencySource, DependencyValue, DependencyValues, DeriveAsyncOptions, DeriveFromAsyncOptions, DeriveFromOptions, DeriveFromSyncOptions, DeriveOptions, DeriveSyncOptions, DerivedValueParser, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, DomainOptions, DuplicateOptionError, EmailOptions, ExecutionContext, ExecutionPhase, ExtractRequiredOptions, FileSizeOptions, FileSizeOptionsBigInt, FileSizeOptionsNumber, FileSizeUnit, FlagErrorOptions, FlagOptions, FloatOptions, GroupOptions, HiddenVisibility, HostnameOptions, InferMode, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, IpOptions, Ipv4Options, Ipv6Options, Json, JsonOptions, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, MacAddressOptions, MergeOptions, type Message, type MessageFormatOptions, type MessageTerm, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NegatableFlagErrorOptions, NegatableFlagNameList, NegatableFlagNames, NegatableFlagOptions, NegatableFlagState, NoMatchContext, NonEmptyString, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OptionState, OptionSubConfig, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, ParserValuePlaceholder, PassThroughFormat, PassThroughOptions, PortOptionsBigInt, PortOptionsNumber, PortRangeOptionsBigInt, PortRangeOptionsNumber, PortRangeValueBigInt, PortRangeValueNumber, Result, RunOptions, RunParserError, RunWithOptions, SemVer, SemVerOptionsObject, SemVerOptionsString, SemVerString, SeqOptions, ShellCompletion, ShowChoicesOptions, ShowDefaultOptions, SocketAddressOptions, SocketAddressValue, SourceContext, SourceContextRequest, StringOptions, SubstituteParserValue, Suggestion, TupleOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, type ValueSetOptions, WithDefaultError, WithDefaultOptions, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, seq, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
|
package/dist/index.js
CHANGED
|
@@ -5,11 +5,11 @@ import { cloneUsage, cloneUsageTerm, extractArgumentMetavars, extractCommandName
|
|
|
5
5
|
import { cloneDocEntry, deduplicateDocEntries, deduplicateDocFragments, formatDocPage, isDocEntryHidden } from "./doc.js";
|
|
6
6
|
import { dependency, deriveFrom, deriveFromAsync, deriveFromSync, isDependencySource, isDerivedValueParser } from "./internal/dependency.js";
|
|
7
7
|
import { createParserContext, getDocPage, getDocPageAsync, getDocPageSync, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync } from "./internal/parser.js";
|
|
8
|
-
import { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
8
|
+
import { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, seq, tuple } from "./constructs.js";
|
|
9
9
|
import { WithDefaultError, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
|
|
10
10
|
import { ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
|
|
11
11
|
import { checkBooleanOption, checkEnumOption, choice, cidr, color, domain, email, fileSize, float, hostname, integer, ip, ipv4, ipv6, isValueParser, json, locale, macAddress, port, portRange, semVer, socketAddress, string, url, uuid } from "./valueparser.js";
|
|
12
12
|
import { argument, command, constant, fail, flag, negatableFlag, option, passThrough } from "./primitives.js";
|
|
13
13
|
import { RunParserError, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync } from "./facade.js";
|
|
14
14
|
|
|
15
|
-
export { DuplicateOptionError, RunParserError, WithDefaultError, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
|
|
15
|
+
export { DuplicateOptionError, RunParserError, WithDefaultError, argument, bash, checkBooleanOption, checkEnumOption, choice, cidr, cloneDocEntry, cloneUsage, cloneUsageTerm, color, command, commandLine, concat, conditional, constant, createParserContext, deduplicateDocEntries, deduplicateDocFragments, dependency, deriveFrom, deriveFromAsync, deriveFromSync, domain, email, ensureNonEmptyString, envVar, extractArgumentMetavars, extractCommandNames, extractLiteralValues, extractOptionNames, fail, fileSize, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getAnnotations, getDocPage, getDocPageAsync, getDocPageSync, group, hostname, integer, ip, ipv4, ipv6, isDependencySource, isDerivedValueParser, isDocEntryHidden, isDocHidden, isNonEmptyString, isSuggestionHidden, isUsageHidden, isValueParser, json, lineBreak, link, locale, longestMatch, macAddress, map, merge, mergeHidden, message, metavar, multiple, negatableFlag, nonEmpty, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, parseAsync, parseSync, passThrough, port, portRange, pwsh, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync, semVer, seq, socketAddress, string, suggest, suggestAsync, suggestSync, text, tuple, url, uuid, value, valueSet, values, withDefault, zsh };
|
package/dist/internal/parser.cjs
CHANGED
|
@@ -501,14 +501,63 @@ function findCommandInExclusive(term, commandName) {
|
|
|
501
501
|
if (term.type !== "exclusive") return null;
|
|
502
502
|
for (const termGroup of term.terms) {
|
|
503
503
|
const firstTerm = termGroup[0];
|
|
504
|
-
if (firstTerm
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
504
|
+
if (firstTerm == null) continue;
|
|
505
|
+
const found = findCommandInCurrentUsageTerm(firstTerm, commandName, termGroup.slice(1));
|
|
506
|
+
if (found) return found;
|
|
507
|
+
}
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Searches for a command inside an ordered usage sequence and returns the
|
|
512
|
+
* usage from the matched command onward. This lets contextual command
|
|
513
|
+
* documentation enter sequence terms while dropping sequence prefixes that
|
|
514
|
+
* were skipped by parsing, such as optional positionals before a subcommand.
|
|
515
|
+
*
|
|
516
|
+
* @param usage The usage terms to search.
|
|
517
|
+
* @param commandName The command name to find.
|
|
518
|
+
* @returns The contextual usage terms if found, null otherwise.
|
|
519
|
+
*/
|
|
520
|
+
function findCommandInUsageSequence(usage, commandName) {
|
|
521
|
+
for (let index = 0; index < usage.length; index++) {
|
|
522
|
+
const found = findCommandInCurrentUsageTerm(usage[index], commandName, usage.slice(index + 1));
|
|
523
|
+
if (found) return found;
|
|
524
|
+
}
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Searches the current usage term for a command and appends the trailing
|
|
529
|
+
* usage terms that remain valid after that current term.
|
|
530
|
+
*
|
|
531
|
+
* @param term The current usage term to search.
|
|
532
|
+
* @param commandName The command name to find.
|
|
533
|
+
* @param trailingUsage Usage terms that follow the current term.
|
|
534
|
+
* @returns The contextual usage terms if found, null otherwise.
|
|
535
|
+
*/
|
|
536
|
+
function findCommandInCurrentUsageTerm(term, commandName, trailingUsage) {
|
|
537
|
+
if (term.type === "command" && term.name === commandName) return [term, ...trailingUsage];
|
|
538
|
+
if (term.type === "exclusive") {
|
|
539
|
+
const found = findCommandInExclusive(term, commandName);
|
|
540
|
+
if (found) return [...found, ...trailingUsage];
|
|
541
|
+
} else if (term.type === "sequence") {
|
|
542
|
+
const found = findCommandInUsageSequence(term.terms, commandName);
|
|
543
|
+
if (found) return [...found, ...trailingUsage];
|
|
509
544
|
}
|
|
510
545
|
return null;
|
|
511
546
|
}
|
|
547
|
+
function recordMatchedCommandArgIndices(consumed, previousCommandPath, nextCommandPath, consumedOffset, indices) {
|
|
548
|
+
const previousLength = previousCommandPath?.length ?? 0;
|
|
549
|
+
const next = nextCommandPath ?? [];
|
|
550
|
+
if (next.length <= previousLength || consumed.length < 1) return;
|
|
551
|
+
let searchEnd = consumed.length;
|
|
552
|
+
for (let index = next.length - 1; index >= previousLength; index--) {
|
|
553
|
+
if (searchEnd <= 0) break;
|
|
554
|
+
const commandName = next[index];
|
|
555
|
+
const localIndex = consumed.lastIndexOf(commandName, searchEnd - 1);
|
|
556
|
+
if (localIndex < 0) continue;
|
|
557
|
+
indices.add(consumedOffset + localIndex);
|
|
558
|
+
searchEnd = localIndex;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
512
561
|
/**
|
|
513
562
|
* Generates a documentation page for a synchronous parser.
|
|
514
563
|
*
|
|
@@ -579,14 +628,18 @@ function getDocPageSyncImpl(parser, args, options) {
|
|
|
579
628
|
state: initialState,
|
|
580
629
|
optionsTerminated: false
|
|
581
630
|
}, exec);
|
|
631
|
+
const matchedCommandArgIndices = /* @__PURE__ */ new Set();
|
|
582
632
|
while (context.buffer.length > 0) {
|
|
583
633
|
const result = parser.parse(context);
|
|
584
634
|
if (!result.success) break;
|
|
635
|
+
const previousCommandPath = context.exec?.commandPath;
|
|
585
636
|
const previousBuffer = context.buffer;
|
|
586
637
|
context = result.next;
|
|
638
|
+
const consumedCount = previousBuffer.length - context.buffer.length;
|
|
639
|
+
recordMatchedCommandArgIndices(previousBuffer.slice(0, consumedCount), previousCommandPath, context.exec?.commandPath, args.length - previousBuffer.length, matchedCommandArgIndices);
|
|
587
640
|
if (isBufferUnchanged(previousBuffer, context.buffer)) break;
|
|
588
641
|
}
|
|
589
|
-
return buildDocPage(parser, context, args);
|
|
642
|
+
return buildDocPage(parser, context, args, matchedCommandArgIndices);
|
|
590
643
|
}
|
|
591
644
|
/**
|
|
592
645
|
* Internal async implementation of getDocPage.
|
|
@@ -604,20 +657,24 @@ async function getDocPageAsyncImpl(parser, args, options) {
|
|
|
604
657
|
state: initialState,
|
|
605
658
|
optionsTerminated: false
|
|
606
659
|
}, exec);
|
|
660
|
+
const matchedCommandArgIndices = /* @__PURE__ */ new Set();
|
|
607
661
|
while (context.buffer.length > 0) {
|
|
608
662
|
const result = await parser.parse(context);
|
|
609
663
|
if (!result.success) break;
|
|
664
|
+
const previousCommandPath = context.exec?.commandPath;
|
|
610
665
|
const previousBuffer = context.buffer;
|
|
611
666
|
context = result.next;
|
|
667
|
+
const consumedCount = previousBuffer.length - context.buffer.length;
|
|
668
|
+
recordMatchedCommandArgIndices(previousBuffer.slice(0, consumedCount), previousCommandPath, context.exec?.commandPath, args.length - previousBuffer.length, matchedCommandArgIndices);
|
|
612
669
|
if (isBufferUnchanged(previousBuffer, context.buffer)) break;
|
|
613
670
|
}
|
|
614
|
-
return buildDocPage(parser, context, args);
|
|
671
|
+
return buildDocPage(parser, context, args, matchedCommandArgIndices);
|
|
615
672
|
}
|
|
616
673
|
/**
|
|
617
674
|
* Builds a DocPage from the parser and context.
|
|
618
675
|
* Shared by both sync and async implementations.
|
|
619
676
|
*/
|
|
620
|
-
function buildDocPage(parser, context, args) {
|
|
677
|
+
function buildDocPage(parser, context, args, matchedCommandArgIndices) {
|
|
621
678
|
let effectiveArgs = args;
|
|
622
679
|
let { brief, description, fragments, footer } = parser.getDocFragments({
|
|
623
680
|
kind: "available",
|
|
@@ -675,19 +732,25 @@ function buildDocPage(parser, context, args) {
|
|
|
675
732
|
usage.splice(usageIndex + 1, usage.length - (usageIndex + 1), ...normalizedCustomUsageLine);
|
|
676
733
|
};
|
|
677
734
|
let i = 0;
|
|
735
|
+
const consumedArgsCount = Math.max(0, effectiveArgs.length - context.buffer.length);
|
|
736
|
+
const commandArgIndices = args.length > 0 ? matchedCommandArgIndices : null;
|
|
678
737
|
for (let argIndex = 0; argIndex < effectiveArgs.length; argIndex++) {
|
|
679
738
|
const arg = effectiveArgs[argIndex];
|
|
680
739
|
if (i >= usage.length) break;
|
|
681
740
|
let term = usage[i];
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
741
|
+
const canSearchCommand = commandArgIndices == null || commandArgIndices.has(argIndex);
|
|
742
|
+
if (!canSearchCommand) continue;
|
|
743
|
+
let found = null;
|
|
744
|
+
for (let searchIndex = i; searchIndex < usage.length; searchIndex++) {
|
|
745
|
+
found = findCommandInCurrentUsageTerm(usage[searchIndex], arg, usage.slice(searchIndex + 1));
|
|
746
|
+
if (found != null) break;
|
|
747
|
+
}
|
|
748
|
+
if (found) {
|
|
749
|
+
usage.splice(i, usage.length - i, ...found);
|
|
750
|
+
term = usage[i];
|
|
688
751
|
}
|
|
689
752
|
maybeApplyCommandUsageLine(term, arg, argIndex === effectiveArgs.length - 1, i);
|
|
690
|
-
i++;
|
|
753
|
+
if (found != null || term.type !== "sequence" || argIndex >= consumedArgsCount) i++;
|
|
691
754
|
}
|
|
692
755
|
if (effectiveArgs.length === 0 && usage.length > 0) {
|
|
693
756
|
const first = usage[0];
|
|
@@ -143,6 +143,20 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
143
143
|
* @since 1.0.0
|
|
144
144
|
*/
|
|
145
145
|
readonly acceptingAnyToken: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Returns whether this parser can be skipped at the current state without
|
|
148
|
+
* consuming more CLI input or evaluating completion-time defaults.
|
|
149
|
+
*
|
|
150
|
+
* Sequential combinators use this as a lightweight boundary predicate. It
|
|
151
|
+
* must be synchronous and side-effect free. Custom parsers that omit this
|
|
152
|
+
* method are treated as not skippable.
|
|
153
|
+
*
|
|
154
|
+
* @param state The current parser state.
|
|
155
|
+
* @param exec Optional shared execution context.
|
|
156
|
+
* @returns `true` when parsing may advance past this parser.
|
|
157
|
+
* @since 1.1.0
|
|
158
|
+
*/
|
|
159
|
+
canSkip?(state: TState, exec?: ExecutionContext): boolean;
|
|
146
160
|
/**
|
|
147
161
|
* The initial state for this parser. This is used to initialize the
|
|
148
162
|
* state when parsing starts.
|
|
@@ -143,6 +143,20 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
143
143
|
* @since 1.0.0
|
|
144
144
|
*/
|
|
145
145
|
readonly acceptingAnyToken: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Returns whether this parser can be skipped at the current state without
|
|
148
|
+
* consuming more CLI input or evaluating completion-time defaults.
|
|
149
|
+
*
|
|
150
|
+
* Sequential combinators use this as a lightweight boundary predicate. It
|
|
151
|
+
* must be synchronous and side-effect free. Custom parsers that omit this
|
|
152
|
+
* method are treated as not skippable.
|
|
153
|
+
*
|
|
154
|
+
* @param state The current parser state.
|
|
155
|
+
* @param exec Optional shared execution context.
|
|
156
|
+
* @returns `true` when parsing may advance past this parser.
|
|
157
|
+
* @since 1.1.0
|
|
158
|
+
*/
|
|
159
|
+
canSkip?(state: TState, exec?: ExecutionContext): boolean;
|
|
146
160
|
/**
|
|
147
161
|
* The initial state for this parser. This is used to initialize the
|
|
148
162
|
* state when parsing starts.
|
package/dist/internal/parser.js
CHANGED
|
@@ -501,14 +501,63 @@ function findCommandInExclusive(term, commandName) {
|
|
|
501
501
|
if (term.type !== "exclusive") return null;
|
|
502
502
|
for (const termGroup of term.terms) {
|
|
503
503
|
const firstTerm = termGroup[0];
|
|
504
|
-
if (firstTerm
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
504
|
+
if (firstTerm == null) continue;
|
|
505
|
+
const found = findCommandInCurrentUsageTerm(firstTerm, commandName, termGroup.slice(1));
|
|
506
|
+
if (found) return found;
|
|
507
|
+
}
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Searches for a command inside an ordered usage sequence and returns the
|
|
512
|
+
* usage from the matched command onward. This lets contextual command
|
|
513
|
+
* documentation enter sequence terms while dropping sequence prefixes that
|
|
514
|
+
* were skipped by parsing, such as optional positionals before a subcommand.
|
|
515
|
+
*
|
|
516
|
+
* @param usage The usage terms to search.
|
|
517
|
+
* @param commandName The command name to find.
|
|
518
|
+
* @returns The contextual usage terms if found, null otherwise.
|
|
519
|
+
*/
|
|
520
|
+
function findCommandInUsageSequence(usage, commandName) {
|
|
521
|
+
for (let index = 0; index < usage.length; index++) {
|
|
522
|
+
const found = findCommandInCurrentUsageTerm(usage[index], commandName, usage.slice(index + 1));
|
|
523
|
+
if (found) return found;
|
|
524
|
+
}
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Searches the current usage term for a command and appends the trailing
|
|
529
|
+
* usage terms that remain valid after that current term.
|
|
530
|
+
*
|
|
531
|
+
* @param term The current usage term to search.
|
|
532
|
+
* @param commandName The command name to find.
|
|
533
|
+
* @param trailingUsage Usage terms that follow the current term.
|
|
534
|
+
* @returns The contextual usage terms if found, null otherwise.
|
|
535
|
+
*/
|
|
536
|
+
function findCommandInCurrentUsageTerm(term, commandName, trailingUsage) {
|
|
537
|
+
if (term.type === "command" && term.name === commandName) return [term, ...trailingUsage];
|
|
538
|
+
if (term.type === "exclusive") {
|
|
539
|
+
const found = findCommandInExclusive(term, commandName);
|
|
540
|
+
if (found) return [...found, ...trailingUsage];
|
|
541
|
+
} else if (term.type === "sequence") {
|
|
542
|
+
const found = findCommandInUsageSequence(term.terms, commandName);
|
|
543
|
+
if (found) return [...found, ...trailingUsage];
|
|
509
544
|
}
|
|
510
545
|
return null;
|
|
511
546
|
}
|
|
547
|
+
function recordMatchedCommandArgIndices(consumed, previousCommandPath, nextCommandPath, consumedOffset, indices) {
|
|
548
|
+
const previousLength = previousCommandPath?.length ?? 0;
|
|
549
|
+
const next = nextCommandPath ?? [];
|
|
550
|
+
if (next.length <= previousLength || consumed.length < 1) return;
|
|
551
|
+
let searchEnd = consumed.length;
|
|
552
|
+
for (let index = next.length - 1; index >= previousLength; index--) {
|
|
553
|
+
if (searchEnd <= 0) break;
|
|
554
|
+
const commandName = next[index];
|
|
555
|
+
const localIndex = consumed.lastIndexOf(commandName, searchEnd - 1);
|
|
556
|
+
if (localIndex < 0) continue;
|
|
557
|
+
indices.add(consumedOffset + localIndex);
|
|
558
|
+
searchEnd = localIndex;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
512
561
|
/**
|
|
513
562
|
* Generates a documentation page for a synchronous parser.
|
|
514
563
|
*
|
|
@@ -579,14 +628,18 @@ function getDocPageSyncImpl(parser, args, options) {
|
|
|
579
628
|
state: initialState,
|
|
580
629
|
optionsTerminated: false
|
|
581
630
|
}, exec);
|
|
631
|
+
const matchedCommandArgIndices = /* @__PURE__ */ new Set();
|
|
582
632
|
while (context.buffer.length > 0) {
|
|
583
633
|
const result = parser.parse(context);
|
|
584
634
|
if (!result.success) break;
|
|
635
|
+
const previousCommandPath = context.exec?.commandPath;
|
|
585
636
|
const previousBuffer = context.buffer;
|
|
586
637
|
context = result.next;
|
|
638
|
+
const consumedCount = previousBuffer.length - context.buffer.length;
|
|
639
|
+
recordMatchedCommandArgIndices(previousBuffer.slice(0, consumedCount), previousCommandPath, context.exec?.commandPath, args.length - previousBuffer.length, matchedCommandArgIndices);
|
|
587
640
|
if (isBufferUnchanged(previousBuffer, context.buffer)) break;
|
|
588
641
|
}
|
|
589
|
-
return buildDocPage(parser, context, args);
|
|
642
|
+
return buildDocPage(parser, context, args, matchedCommandArgIndices);
|
|
590
643
|
}
|
|
591
644
|
/**
|
|
592
645
|
* Internal async implementation of getDocPage.
|
|
@@ -604,20 +657,24 @@ async function getDocPageAsyncImpl(parser, args, options) {
|
|
|
604
657
|
state: initialState,
|
|
605
658
|
optionsTerminated: false
|
|
606
659
|
}, exec);
|
|
660
|
+
const matchedCommandArgIndices = /* @__PURE__ */ new Set();
|
|
607
661
|
while (context.buffer.length > 0) {
|
|
608
662
|
const result = await parser.parse(context);
|
|
609
663
|
if (!result.success) break;
|
|
664
|
+
const previousCommandPath = context.exec?.commandPath;
|
|
610
665
|
const previousBuffer = context.buffer;
|
|
611
666
|
context = result.next;
|
|
667
|
+
const consumedCount = previousBuffer.length - context.buffer.length;
|
|
668
|
+
recordMatchedCommandArgIndices(previousBuffer.slice(0, consumedCount), previousCommandPath, context.exec?.commandPath, args.length - previousBuffer.length, matchedCommandArgIndices);
|
|
612
669
|
if (isBufferUnchanged(previousBuffer, context.buffer)) break;
|
|
613
670
|
}
|
|
614
|
-
return buildDocPage(parser, context, args);
|
|
671
|
+
return buildDocPage(parser, context, args, matchedCommandArgIndices);
|
|
615
672
|
}
|
|
616
673
|
/**
|
|
617
674
|
* Builds a DocPage from the parser and context.
|
|
618
675
|
* Shared by both sync and async implementations.
|
|
619
676
|
*/
|
|
620
|
-
function buildDocPage(parser, context, args) {
|
|
677
|
+
function buildDocPage(parser, context, args, matchedCommandArgIndices) {
|
|
621
678
|
let effectiveArgs = args;
|
|
622
679
|
let { brief, description, fragments, footer } = parser.getDocFragments({
|
|
623
680
|
kind: "available",
|
|
@@ -675,19 +732,25 @@ function buildDocPage(parser, context, args) {
|
|
|
675
732
|
usage.splice(usageIndex + 1, usage.length - (usageIndex + 1), ...normalizedCustomUsageLine);
|
|
676
733
|
};
|
|
677
734
|
let i = 0;
|
|
735
|
+
const consumedArgsCount = Math.max(0, effectiveArgs.length - context.buffer.length);
|
|
736
|
+
const commandArgIndices = args.length > 0 ? matchedCommandArgIndices : null;
|
|
678
737
|
for (let argIndex = 0; argIndex < effectiveArgs.length; argIndex++) {
|
|
679
738
|
const arg = effectiveArgs[argIndex];
|
|
680
739
|
if (i >= usage.length) break;
|
|
681
740
|
let term = usage[i];
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
741
|
+
const canSearchCommand = commandArgIndices == null || commandArgIndices.has(argIndex);
|
|
742
|
+
if (!canSearchCommand) continue;
|
|
743
|
+
let found = null;
|
|
744
|
+
for (let searchIndex = i; searchIndex < usage.length; searchIndex++) {
|
|
745
|
+
found = findCommandInCurrentUsageTerm(usage[searchIndex], arg, usage.slice(searchIndex + 1));
|
|
746
|
+
if (found != null) break;
|
|
747
|
+
}
|
|
748
|
+
if (found) {
|
|
749
|
+
usage.splice(i, usage.length - i, ...found);
|
|
750
|
+
term = usage[i];
|
|
688
751
|
}
|
|
689
752
|
maybeApplyCommandUsageLine(term, arg, argIndex === effectiveArgs.length - 1, i);
|
|
690
|
-
i++;
|
|
753
|
+
if (found != null || term.type !== "sequence" || argIndex >= consumedArgsCount) i++;
|
|
691
754
|
}
|
|
692
755
|
if (effectiveArgs.length === 0 && usage.length > 0) {
|
|
693
756
|
const first = usage[0];
|
package/dist/modifiers.cjs
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, require_execution_context.withChildExecPath(exec, itemIndex)) !== true);
|
|
929
945
|
const parseSync = (context) => {
|
|
930
946
|
const currentItemState = context.state.at(-1);
|
|
931
|
-
const
|
|
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
|
|
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
|
|
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 require_mode_dispatch.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
|
|
1537
|
+
initialState,
|
|
1538
|
+
...typeof parser.canSkip === "function" ? { canSkip(state, exec) {
|
|
1539
|
+
const unwrappedState = require_annotations.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 ? [{
|