@optique/core 1.1.8 → 1.1.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 +47 -10
- package/dist/primitives.js +47 -10
- 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');
|
|
@@ -144,6 +145,7 @@ function constant(value) {
|
|
|
144
145
|
return { fragments: [] };
|
|
145
146
|
}
|
|
146
147
|
};
|
|
148
|
+
require_passthrough.defineKnownCompletion(result, (state) => require_annotation_state.normalizeInjectedAnnotationState(state));
|
|
147
149
|
Object.defineProperty(result, "placeholder", {
|
|
148
150
|
value,
|
|
149
151
|
configurable: true,
|
|
@@ -583,10 +585,15 @@ function option(...args) {
|
|
|
583
585
|
}
|
|
584
586
|
const invalidOption = context.buffer[0];
|
|
585
587
|
if (options.errors?.noMatch) {
|
|
588
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
589
|
+
success: false,
|
|
590
|
+
consumed: 0,
|
|
591
|
+
error: options.errors.noMatch
|
|
592
|
+
};
|
|
586
593
|
const candidates = /* @__PURE__ */ new Set();
|
|
587
594
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
588
595
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
589
|
-
const errorMessage =
|
|
596
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
590
597
|
return {
|
|
591
598
|
success: false,
|
|
592
599
|
consumed: 0,
|
|
@@ -871,10 +878,15 @@ function flag(...args) {
|
|
|
871
878
|
}
|
|
872
879
|
const invalidOption = context.buffer[0];
|
|
873
880
|
if (options.errors?.noMatch) {
|
|
881
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
882
|
+
success: false,
|
|
883
|
+
consumed: 0,
|
|
884
|
+
error: options.errors.noMatch
|
|
885
|
+
};
|
|
874
886
|
const candidates = /* @__PURE__ */ new Set();
|
|
875
887
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
876
888
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
877
|
-
const errorMessage =
|
|
889
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
878
890
|
return {
|
|
879
891
|
success: false,
|
|
880
892
|
consumed: 0,
|
|
@@ -1183,7 +1195,7 @@ function argument(valueParser, options = {}) {
|
|
|
1183
1195
|
const syncValueParser = valueParser;
|
|
1184
1196
|
const dependencyMetadata = require_dependency_metadata.extractDependencyMetadata(valueParser);
|
|
1185
1197
|
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}`;
|
|
1186
|
-
const optionPattern =
|
|
1198
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1187
1199
|
const term = {
|
|
1188
1200
|
type: "argument",
|
|
1189
1201
|
metavar: valueParser.metavar,
|
|
@@ -1210,14 +1222,15 @@ function argument(valueParser, options = {}) {
|
|
|
1210
1222
|
};
|
|
1211
1223
|
let i = 0;
|
|
1212
1224
|
let optionsTerminated = context.optionsTerminated;
|
|
1213
|
-
if (!optionsTerminated) {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1225
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1226
|
+
optionsTerminated = true;
|
|
1227
|
+
i++;
|
|
1228
|
+
} else {
|
|
1229
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1230
|
+
if (optionMatch != null) return {
|
|
1218
1231
|
success: false,
|
|
1219
1232
|
consumed: i,
|
|
1220
|
-
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(
|
|
1233
|
+
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(optionMatch[1])}.`
|
|
1221
1234
|
};
|
|
1222
1235
|
}
|
|
1223
1236
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1703,6 +1716,22 @@ function command(name, parser, options = {}) {
|
|
|
1703
1716
|
configurable: true,
|
|
1704
1717
|
enumerable: false
|
|
1705
1718
|
});
|
|
1719
|
+
require_passthrough.definePassThroughPriority(result, [parser], (state, token) => {
|
|
1720
|
+
const active = normalizeCommandState(state);
|
|
1721
|
+
if (active == null) return void 0;
|
|
1722
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1723
|
+
return require_passthrough.getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1724
|
+
});
|
|
1725
|
+
require_passthrough.defineOptionMatch(result, (state, token) => {
|
|
1726
|
+
const active = normalizeCommandState(state);
|
|
1727
|
+
if (active == null) return void 0;
|
|
1728
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1729
|
+
const match = require_passthrough.getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1730
|
+
return match == null ? void 0 : {
|
|
1731
|
+
...match,
|
|
1732
|
+
continuesCommand: true
|
|
1733
|
+
};
|
|
1734
|
+
});
|
|
1706
1735
|
return result;
|
|
1707
1736
|
}
|
|
1708
1737
|
/**
|
|
@@ -1755,7 +1784,7 @@ function passThrough(options = {}) {
|
|
|
1755
1784
|
const format = options.format ?? "equalsOnly";
|
|
1756
1785
|
const optionPattern = /^-[a-z0-9-]|^--[a-z0-9-]+/i;
|
|
1757
1786
|
const equalsOptionPattern = /^--[a-z0-9-]+=/i;
|
|
1758
|
-
|
|
1787
|
+
const result = {
|
|
1759
1788
|
$valueType: [],
|
|
1760
1789
|
$stateType: [],
|
|
1761
1790
|
mode: "sync",
|
|
@@ -1776,6 +1805,8 @@ function passThrough(options = {}) {
|
|
|
1776
1805
|
consumed: 0,
|
|
1777
1806
|
error: require_message.message`No input to pass through.`
|
|
1778
1807
|
};
|
|
1808
|
+
const failure = require_passthrough.getPassThroughFailure(context, this?.priority ?? -10);
|
|
1809
|
+
if (failure != null) return failure.failure;
|
|
1779
1810
|
const token = context.buffer[0];
|
|
1780
1811
|
if (format === "greedy") {
|
|
1781
1812
|
const captured = [...context.buffer];
|
|
@@ -1887,6 +1918,12 @@ function passThrough(options = {}) {
|
|
|
1887
1918
|
return `passThrough(${format})`;
|
|
1888
1919
|
}
|
|
1889
1920
|
};
|
|
1921
|
+
require_passthrough.definePassThroughPriority(result, [result], (_state, token) => {
|
|
1922
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1923
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1924
|
+
return accepts ? result.priority : void 0;
|
|
1925
|
+
});
|
|
1926
|
+
return result;
|
|
1890
1927
|
}
|
|
1891
1928
|
|
|
1892
1929
|
//#endregion
|
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";
|
|
@@ -144,6 +145,7 @@ function constant(value) {
|
|
|
144
145
|
return { fragments: [] };
|
|
145
146
|
}
|
|
146
147
|
};
|
|
148
|
+
defineKnownCompletion(result, (state) => normalizeInjectedAnnotationState(state));
|
|
147
149
|
Object.defineProperty(result, "placeholder", {
|
|
148
150
|
value,
|
|
149
151
|
configurable: true,
|
|
@@ -583,10 +585,15 @@ function option(...args) {
|
|
|
583
585
|
}
|
|
584
586
|
const invalidOption = context.buffer[0];
|
|
585
587
|
if (options.errors?.noMatch) {
|
|
588
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
589
|
+
success: false,
|
|
590
|
+
consumed: 0,
|
|
591
|
+
error: options.errors.noMatch
|
|
592
|
+
};
|
|
586
593
|
const candidates = /* @__PURE__ */ new Set();
|
|
587
594
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
588
595
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
589
|
-
const errorMessage =
|
|
596
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
590
597
|
return {
|
|
591
598
|
success: false,
|
|
592
599
|
consumed: 0,
|
|
@@ -871,10 +878,15 @@ function flag(...args) {
|
|
|
871
878
|
}
|
|
872
879
|
const invalidOption = context.buffer[0];
|
|
873
880
|
if (options.errors?.noMatch) {
|
|
881
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
882
|
+
success: false,
|
|
883
|
+
consumed: 0,
|
|
884
|
+
error: options.errors.noMatch
|
|
885
|
+
};
|
|
874
886
|
const candidates = /* @__PURE__ */ new Set();
|
|
875
887
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
876
888
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
877
|
-
const errorMessage =
|
|
889
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
878
890
|
return {
|
|
879
891
|
success: false,
|
|
880
892
|
consumed: 0,
|
|
@@ -1183,7 +1195,7 @@ function argument(valueParser, options = {}) {
|
|
|
1183
1195
|
const syncValueParser = valueParser;
|
|
1184
1196
|
const dependencyMetadata = extractDependencyMetadata(valueParser);
|
|
1185
1197
|
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${metavar(valueParser.metavar)}: ${error}`;
|
|
1186
|
-
const optionPattern =
|
|
1198
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1187
1199
|
const term = {
|
|
1188
1200
|
type: "argument",
|
|
1189
1201
|
metavar: valueParser.metavar,
|
|
@@ -1210,14 +1222,15 @@ function argument(valueParser, options = {}) {
|
|
|
1210
1222
|
};
|
|
1211
1223
|
let i = 0;
|
|
1212
1224
|
let optionsTerminated = context.optionsTerminated;
|
|
1213
|
-
if (!optionsTerminated) {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1225
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1226
|
+
optionsTerminated = true;
|
|
1227
|
+
i++;
|
|
1228
|
+
} else {
|
|
1229
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1230
|
+
if (optionMatch != null) return {
|
|
1218
1231
|
success: false,
|
|
1219
1232
|
consumed: i,
|
|
1220
|
-
error: message`Expected an argument, but got an option: ${optionName(
|
|
1233
|
+
error: message`Expected an argument, but got an option: ${optionName(optionMatch[1])}.`
|
|
1221
1234
|
};
|
|
1222
1235
|
}
|
|
1223
1236
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1703,6 +1716,22 @@ function command(name, parser, options = {}) {
|
|
|
1703
1716
|
configurable: true,
|
|
1704
1717
|
enumerable: false
|
|
1705
1718
|
});
|
|
1719
|
+
definePassThroughPriority(result, [parser], (state, token) => {
|
|
1720
|
+
const active = normalizeCommandState(state);
|
|
1721
|
+
if (active == null) return void 0;
|
|
1722
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1723
|
+
return getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1724
|
+
});
|
|
1725
|
+
defineOptionMatch(result, (state, token) => {
|
|
1726
|
+
const active = normalizeCommandState(state);
|
|
1727
|
+
if (active == null) return void 0;
|
|
1728
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1729
|
+
const match = getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1730
|
+
return match == null ? void 0 : {
|
|
1731
|
+
...match,
|
|
1732
|
+
continuesCommand: true
|
|
1733
|
+
};
|
|
1734
|
+
});
|
|
1706
1735
|
return result;
|
|
1707
1736
|
}
|
|
1708
1737
|
/**
|
|
@@ -1755,7 +1784,7 @@ function passThrough(options = {}) {
|
|
|
1755
1784
|
const format = options.format ?? "equalsOnly";
|
|
1756
1785
|
const optionPattern = /^-[a-z0-9-]|^--[a-z0-9-]+/i;
|
|
1757
1786
|
const equalsOptionPattern = /^--[a-z0-9-]+=/i;
|
|
1758
|
-
|
|
1787
|
+
const result = {
|
|
1759
1788
|
$valueType: [],
|
|
1760
1789
|
$stateType: [],
|
|
1761
1790
|
mode: "sync",
|
|
@@ -1776,6 +1805,8 @@ function passThrough(options = {}) {
|
|
|
1776
1805
|
consumed: 0,
|
|
1777
1806
|
error: message`No input to pass through.`
|
|
1778
1807
|
};
|
|
1808
|
+
const failure = getPassThroughFailure(context, this?.priority ?? -10);
|
|
1809
|
+
if (failure != null) return failure.failure;
|
|
1779
1810
|
const token = context.buffer[0];
|
|
1780
1811
|
if (format === "greedy") {
|
|
1781
1812
|
const captured = [...context.buffer];
|
|
@@ -1887,6 +1918,12 @@ function passThrough(options = {}) {
|
|
|
1887
1918
|
return `passThrough(${format})`;
|
|
1888
1919
|
}
|
|
1889
1920
|
};
|
|
1921
|
+
definePassThroughPriority(result, [result], (_state, token) => {
|
|
1922
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1923
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1924
|
+
return accepts ? result.priority : void 0;
|
|
1925
|
+
});
|
|
1926
|
+
return result;
|
|
1890
1927
|
}
|
|
1891
1928
|
|
|
1892
1929
|
//#endregion
|
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.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -196,7 +196,7 @@
|
|
|
196
196
|
},
|
|
197
197
|
"sideEffects": false,
|
|
198
198
|
"devDependencies": {
|
|
199
|
-
"@optique/env": "1.1.
|
|
199
|
+
"@optique/env": "1.1.9",
|
|
200
200
|
"@types/node": "^24.0.0",
|
|
201
201
|
"fast-check": "^4.7.0",
|
|
202
202
|
"tsdown": "^0.13.0",
|