@optique/core 1.2.7 → 1.2.9
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 +260 -40
- package/dist/constructs.js +260 -40
- package/dist/extension.cjs +17 -0
- package/dist/extension.d.cts +13 -1
- package/dist/extension.d.ts +13 -1
- package/dist/extension.js +17 -1
- package/dist/internal/passthrough.cjs +230 -0
- package/dist/internal/passthrough.js +213 -0
- package/dist/modifiers.cjs +22 -0
- package/dist/modifiers.js +22 -0
- package/dist/primitives.cjs +52 -18
- package/dist/primitives.js +52 -18
- package/dist/suggestion.cjs +3 -1
- package/dist/suggestion.js +3 -1
- package/package.json +2 -2
package/dist/primitives.cjs
CHANGED
|
@@ -6,6 +6,7 @@ const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
|
|
|
6
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_passthrough = require('./internal/passthrough.cjs');
|
|
9
10
|
const require_command_alias = require('./internal/command-alias.cjs');
|
|
10
11
|
const require_execution_context = require('./execution-context.cjs');
|
|
11
12
|
const require_phase2_seed = require('./phase2-seed.cjs');
|
|
@@ -145,6 +146,7 @@ function constant(value) {
|
|
|
145
146
|
return { fragments: [] };
|
|
146
147
|
}
|
|
147
148
|
};
|
|
149
|
+
require_passthrough.defineKnownCompletion(result, (state) => require_annotation_state.normalizeInjectedAnnotationState(state));
|
|
148
150
|
Object.defineProperty(result, "placeholder", {
|
|
149
151
|
value,
|
|
150
152
|
configurable: true,
|
|
@@ -521,19 +523,17 @@ function option(...args) {
|
|
|
521
523
|
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) => name.startsWith("/") ? `${name}:` : `${name}=`);
|
|
522
524
|
for (const prefix of prefixes) {
|
|
523
525
|
if (!context.buffer[0].startsWith(prefix)) continue;
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
};
|
|
531
|
-
}
|
|
526
|
+
const optionName$1 = prefix.slice(0, -1);
|
|
527
|
+
if (hasParsedOptionValue(context.state, valueParser)) return {
|
|
528
|
+
success: false,
|
|
529
|
+
consumed: 1,
|
|
530
|
+
error: options.errors?.duplicate ? typeof options.errors.duplicate === "function" ? options.errors.duplicate(prefix) : options.errors.duplicate : require_message.message`${require_message.optionName(optionName$1)} cannot be used multiple times.`
|
|
531
|
+
};
|
|
532
532
|
const rawInput = context.buffer[0].slice(prefix.length);
|
|
533
533
|
if (valueParser == null) return {
|
|
534
534
|
success: false,
|
|
535
535
|
consumed: 1,
|
|
536
|
-
error: options.errors?.unexpectedValue ? typeof options.errors.unexpectedValue === "function" ? options.errors.unexpectedValue(rawInput) : options.errors.unexpectedValue : require_message.message`Option ${require_message.optionName(
|
|
536
|
+
error: options.errors?.unexpectedValue ? typeof options.errors.unexpectedValue === "function" ? options.errors.unexpectedValue(rawInput) : options.errors.unexpectedValue : require_message.message`Option ${require_message.optionName(optionName$1)} is a Boolean flag, but got a value: ${rawInput}.`
|
|
537
537
|
};
|
|
538
538
|
return require_mode_dispatch.dispatchByMode(mode, () => {
|
|
539
539
|
const parseResult = syncValueParser.parse(rawInput);
|
|
@@ -586,10 +586,15 @@ function option(...args) {
|
|
|
586
586
|
}
|
|
587
587
|
const invalidOption = context.buffer[0];
|
|
588
588
|
if (options.errors?.noMatch) {
|
|
589
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
590
|
+
success: false,
|
|
591
|
+
consumed: 0,
|
|
592
|
+
error: options.errors.noMatch
|
|
593
|
+
};
|
|
589
594
|
const candidates = /* @__PURE__ */ new Set();
|
|
590
595
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
591
596
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
592
|
-
const errorMessage =
|
|
597
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
593
598
|
return {
|
|
594
599
|
success: false,
|
|
595
600
|
consumed: 0,
|
|
@@ -874,10 +879,15 @@ function flag(...args) {
|
|
|
874
879
|
}
|
|
875
880
|
const invalidOption = context.buffer[0];
|
|
876
881
|
if (options.errors?.noMatch) {
|
|
882
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
883
|
+
success: false,
|
|
884
|
+
consumed: 0,
|
|
885
|
+
error: options.errors.noMatch
|
|
886
|
+
};
|
|
877
887
|
const candidates = /* @__PURE__ */ new Set();
|
|
878
888
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
879
889
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
880
|
-
const errorMessage =
|
|
890
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
881
891
|
return {
|
|
882
892
|
success: false,
|
|
883
893
|
consumed: 0,
|
|
@@ -1186,7 +1196,7 @@ function argument(valueParser, options = {}) {
|
|
|
1186
1196
|
const syncValueParser = valueParser;
|
|
1187
1197
|
const dependencyMetadata = require_dependency_metadata.extractDependencyMetadata(valueParser);
|
|
1188
1198
|
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${error}`;
|
|
1189
|
-
const optionPattern =
|
|
1199
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1190
1200
|
const term = {
|
|
1191
1201
|
type: "argument",
|
|
1192
1202
|
metavar: valueParser.metavar,
|
|
@@ -1213,14 +1223,15 @@ function argument(valueParser, options = {}) {
|
|
|
1213
1223
|
};
|
|
1214
1224
|
let i = 0;
|
|
1215
1225
|
let optionsTerminated = context.optionsTerminated;
|
|
1216
|
-
if (!optionsTerminated) {
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1226
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1227
|
+
optionsTerminated = true;
|
|
1228
|
+
i++;
|
|
1229
|
+
} else {
|
|
1230
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1231
|
+
if (optionMatch != null) return {
|
|
1221
1232
|
success: false,
|
|
1222
1233
|
consumed: i,
|
|
1223
|
-
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(
|
|
1234
|
+
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(optionMatch[1])}.`
|
|
1224
1235
|
};
|
|
1225
1236
|
}
|
|
1226
1237
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1706,6 +1717,22 @@ function command(name, parser, options = {}) {
|
|
|
1706
1717
|
configurable: true,
|
|
1707
1718
|
enumerable: false
|
|
1708
1719
|
});
|
|
1720
|
+
require_passthrough.definePassThroughPriority(result, [parser], (state, token) => {
|
|
1721
|
+
const active = normalizeCommandState(state);
|
|
1722
|
+
if (active == null) return void 0;
|
|
1723
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1724
|
+
return require_passthrough.getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1725
|
+
});
|
|
1726
|
+
require_passthrough.defineOptionMatch(result, (state, token) => {
|
|
1727
|
+
const active = normalizeCommandState(state);
|
|
1728
|
+
if (active == null) return void 0;
|
|
1729
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1730
|
+
const match = require_passthrough.getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1731
|
+
return match == null ? void 0 : {
|
|
1732
|
+
...match,
|
|
1733
|
+
continuesCommand: true
|
|
1734
|
+
};
|
|
1735
|
+
});
|
|
1709
1736
|
return require_modifiers.fluent(result);
|
|
1710
1737
|
}
|
|
1711
1738
|
/**
|
|
@@ -1779,6 +1806,8 @@ function passThrough(options = {}) {
|
|
|
1779
1806
|
consumed: 0,
|
|
1780
1807
|
error: require_message.message`No input to pass through.`
|
|
1781
1808
|
};
|
|
1809
|
+
const failure = require_passthrough.getPassThroughFailure(context, this?.priority ?? -10);
|
|
1810
|
+
if (failure != null) return failure.failure;
|
|
1782
1811
|
const token = context.buffer[0];
|
|
1783
1812
|
if (format === "greedy") {
|
|
1784
1813
|
const captured = [...context.buffer];
|
|
@@ -1890,6 +1919,11 @@ function passThrough(options = {}) {
|
|
|
1890
1919
|
return `passThrough(${format})`;
|
|
1891
1920
|
}
|
|
1892
1921
|
};
|
|
1922
|
+
require_passthrough.definePassThroughPriority(result, [result], (_state, token) => {
|
|
1923
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1924
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1925
|
+
return accepts ? result.priority : void 0;
|
|
1926
|
+
});
|
|
1893
1927
|
return require_modifiers.fluent(result);
|
|
1894
1928
|
}
|
|
1895
1929
|
|
package/dist/primitives.js
CHANGED
|
@@ -6,6 +6,7 @@ import { dispatchByMode, dispatchIterableByMode, wrapForMode } from "./internal/
|
|
|
6
6
|
import { getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDerivedValueParser, suggestWithDependency } from "./internal/dependency.js";
|
|
7
7
|
import { replayDerivedParser, replayDerivedParserAsync } from "./dependency-runtime.js";
|
|
8
8
|
import { getWrappedChildParseState, getWrappedChildState, isAnnotationWrappedInitialState, normalizeInjectedAnnotationState } from "./annotation-state.js";
|
|
9
|
+
import { defineKnownCompletion, defineOptionMatch, definePassThroughPriority, getOptionMatch, getPassThroughFailure, getPassThroughPriority } from "./internal/passthrough.js";
|
|
9
10
|
import { hiddenCommandAliasesKey } from "./internal/command-alias.js";
|
|
10
11
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
11
12
|
import { completeOrExtractPhase2Seed, extractPhase2SeedKey } from "./phase2-seed.js";
|
|
@@ -145,6 +146,7 @@ function constant(value) {
|
|
|
145
146
|
return { fragments: [] };
|
|
146
147
|
}
|
|
147
148
|
};
|
|
149
|
+
defineKnownCompletion(result, (state) => normalizeInjectedAnnotationState(state));
|
|
148
150
|
Object.defineProperty(result, "placeholder", {
|
|
149
151
|
value,
|
|
150
152
|
configurable: true,
|
|
@@ -521,19 +523,17 @@ function option(...args) {
|
|
|
521
523
|
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) => name.startsWith("/") ? `${name}:` : `${name}=`);
|
|
522
524
|
for (const prefix of prefixes) {
|
|
523
525
|
if (!context.buffer[0].startsWith(prefix)) continue;
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
};
|
|
531
|
-
}
|
|
526
|
+
const optionName$1 = prefix.slice(0, -1);
|
|
527
|
+
if (hasParsedOptionValue(context.state, valueParser)) return {
|
|
528
|
+
success: false,
|
|
529
|
+
consumed: 1,
|
|
530
|
+
error: options.errors?.duplicate ? typeof options.errors.duplicate === "function" ? options.errors.duplicate(prefix) : options.errors.duplicate : message`${optionName(optionName$1)} cannot be used multiple times.`
|
|
531
|
+
};
|
|
532
532
|
const rawInput = context.buffer[0].slice(prefix.length);
|
|
533
533
|
if (valueParser == null) return {
|
|
534
534
|
success: false,
|
|
535
535
|
consumed: 1,
|
|
536
|
-
error: options.errors?.unexpectedValue ? typeof options.errors.unexpectedValue === "function" ? options.errors.unexpectedValue(rawInput) : options.errors.unexpectedValue : message`Option ${optionName(
|
|
536
|
+
error: options.errors?.unexpectedValue ? typeof options.errors.unexpectedValue === "function" ? options.errors.unexpectedValue(rawInput) : options.errors.unexpectedValue : message`Option ${optionName(optionName$1)} is a Boolean flag, but got a value: ${rawInput}.`
|
|
537
537
|
};
|
|
538
538
|
return dispatchByMode(mode, () => {
|
|
539
539
|
const parseResult = syncValueParser.parse(rawInput);
|
|
@@ -586,10 +586,15 @@ function option(...args) {
|
|
|
586
586
|
}
|
|
587
587
|
const invalidOption = context.buffer[0];
|
|
588
588
|
if (options.errors?.noMatch) {
|
|
589
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
590
|
+
success: false,
|
|
591
|
+
consumed: 0,
|
|
592
|
+
error: options.errors.noMatch
|
|
593
|
+
};
|
|
589
594
|
const candidates = /* @__PURE__ */ new Set();
|
|
590
595
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
591
596
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
592
|
-
const errorMessage =
|
|
597
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
593
598
|
return {
|
|
594
599
|
success: false,
|
|
595
600
|
consumed: 0,
|
|
@@ -874,10 +879,15 @@ function flag(...args) {
|
|
|
874
879
|
}
|
|
875
880
|
const invalidOption = context.buffer[0];
|
|
876
881
|
if (options.errors?.noMatch) {
|
|
882
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
883
|
+
success: false,
|
|
884
|
+
consumed: 0,
|
|
885
|
+
error: options.errors.noMatch
|
|
886
|
+
};
|
|
877
887
|
const candidates = /* @__PURE__ */ new Set();
|
|
878
888
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
879
889
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
880
|
-
const errorMessage =
|
|
890
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
881
891
|
return {
|
|
882
892
|
success: false,
|
|
883
893
|
consumed: 0,
|
|
@@ -1186,7 +1196,7 @@ function argument(valueParser, options = {}) {
|
|
|
1186
1196
|
const syncValueParser = valueParser;
|
|
1187
1197
|
const dependencyMetadata = extractDependencyMetadata(valueParser);
|
|
1188
1198
|
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${metavar(valueParser.metavar)}: ${error}`;
|
|
1189
|
-
const optionPattern =
|
|
1199
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1190
1200
|
const term = {
|
|
1191
1201
|
type: "argument",
|
|
1192
1202
|
metavar: valueParser.metavar,
|
|
@@ -1213,14 +1223,15 @@ function argument(valueParser, options = {}) {
|
|
|
1213
1223
|
};
|
|
1214
1224
|
let i = 0;
|
|
1215
1225
|
let optionsTerminated = context.optionsTerminated;
|
|
1216
|
-
if (!optionsTerminated) {
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1226
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1227
|
+
optionsTerminated = true;
|
|
1228
|
+
i++;
|
|
1229
|
+
} else {
|
|
1230
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1231
|
+
if (optionMatch != null) return {
|
|
1221
1232
|
success: false,
|
|
1222
1233
|
consumed: i,
|
|
1223
|
-
error: message`Expected an argument, but got an option: ${optionName(
|
|
1234
|
+
error: message`Expected an argument, but got an option: ${optionName(optionMatch[1])}.`
|
|
1224
1235
|
};
|
|
1225
1236
|
}
|
|
1226
1237
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1706,6 +1717,22 @@ function command(name, parser, options = {}) {
|
|
|
1706
1717
|
configurable: true,
|
|
1707
1718
|
enumerable: false
|
|
1708
1719
|
});
|
|
1720
|
+
definePassThroughPriority(result, [parser], (state, token) => {
|
|
1721
|
+
const active = normalizeCommandState(state);
|
|
1722
|
+
if (active == null) return void 0;
|
|
1723
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1724
|
+
return getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1725
|
+
});
|
|
1726
|
+
defineOptionMatch(result, (state, token) => {
|
|
1727
|
+
const active = normalizeCommandState(state);
|
|
1728
|
+
if (active == null) return void 0;
|
|
1729
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1730
|
+
const match = getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1731
|
+
return match == null ? void 0 : {
|
|
1732
|
+
...match,
|
|
1733
|
+
continuesCommand: true
|
|
1734
|
+
};
|
|
1735
|
+
});
|
|
1709
1736
|
return fluent(result);
|
|
1710
1737
|
}
|
|
1711
1738
|
/**
|
|
@@ -1779,6 +1806,8 @@ function passThrough(options = {}) {
|
|
|
1779
1806
|
consumed: 0,
|
|
1780
1807
|
error: message`No input to pass through.`
|
|
1781
1808
|
};
|
|
1809
|
+
const failure = getPassThroughFailure(context, this?.priority ?? -10);
|
|
1810
|
+
if (failure != null) return failure.failure;
|
|
1782
1811
|
const token = context.buffer[0];
|
|
1783
1812
|
if (format === "greedy") {
|
|
1784
1813
|
const captured = [...context.buffer];
|
|
@@ -1890,6 +1919,11 @@ function passThrough(options = {}) {
|
|
|
1890
1919
|
return `passThrough(${format})`;
|
|
1891
1920
|
}
|
|
1892
1921
|
};
|
|
1922
|
+
definePassThroughPriority(result, [result], (_state, token) => {
|
|
1923
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1924
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1925
|
+
return accepts ? result.priority : void 0;
|
|
1926
|
+
});
|
|
1893
1927
|
return fluent(result);
|
|
1894
1928
|
}
|
|
1895
1929
|
|
package/dist/suggestion.cjs
CHANGED
|
@@ -86,8 +86,10 @@ function findSimilar(input, candidates, options = {}) {
|
|
|
86
86
|
const normalizedCandidate = caseSensitive ? candidate : candidate.toLowerCase();
|
|
87
87
|
if (seen.has(candidate)) continue;
|
|
88
88
|
seen.add(candidate);
|
|
89
|
+
if (normalizedInput === normalizedCandidate) return [candidate];
|
|
90
|
+
const minimumDistance = Math.abs(normalizedInput.length - normalizedCandidate.length);
|
|
91
|
+
if (minimumDistance > maxDistance || minimumDistance / input.length > maxDistanceRatio) continue;
|
|
89
92
|
const distance = levenshteinDistance(normalizedInput, normalizedCandidate);
|
|
90
|
-
if (distance === 0) return [candidate];
|
|
91
93
|
const distanceRatio = distance / input.length;
|
|
92
94
|
if (distance <= maxDistance && distanceRatio <= maxDistanceRatio) matches.push({
|
|
93
95
|
candidate,
|
package/dist/suggestion.js
CHANGED
|
@@ -86,8 +86,10 @@ function findSimilar(input, candidates, options = {}) {
|
|
|
86
86
|
const normalizedCandidate = caseSensitive ? candidate : candidate.toLowerCase();
|
|
87
87
|
if (seen.has(candidate)) continue;
|
|
88
88
|
seen.add(candidate);
|
|
89
|
+
if (normalizedInput === normalizedCandidate) return [candidate];
|
|
90
|
+
const minimumDistance = Math.abs(normalizedInput.length - normalizedCandidate.length);
|
|
91
|
+
if (minimumDistance > maxDistance || minimumDistance / input.length > maxDistanceRatio) continue;
|
|
89
92
|
const distance = levenshteinDistance(normalizedInput, normalizedCandidate);
|
|
90
|
-
if (distance === 0) return [candidate];
|
|
91
93
|
const distanceRatio = distance / input.length;
|
|
92
94
|
if (distance <= maxDistance && distanceRatio <= maxDistanceRatio) matches.push({
|
|
93
95
|
candidate,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
},
|
|
222
222
|
"sideEffects": false,
|
|
223
223
|
"devDependencies": {
|
|
224
|
-
"@optique/env": "1.2.
|
|
224
|
+
"@optique/env": "1.2.9",
|
|
225
225
|
"@types/node": "^24.0.0",
|
|
226
226
|
"fast-check": "^4.7.0",
|
|
227
227
|
"tsdown": "^0.13.0",
|