@optique/core 1.3.1 → 1.3.2
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 +45 -9
- package/dist/primitives.js +45 -9
- 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');
|
|
@@ -151,6 +152,7 @@ function constant(value) {
|
|
|
151
152
|
return { fragments: [] };
|
|
152
153
|
}
|
|
153
154
|
};
|
|
155
|
+
require_passthrough.defineKnownCompletion(result, (state) => require_annotation_state.normalizeInjectedAnnotationState(state));
|
|
154
156
|
Object.defineProperty(result, "placeholder", {
|
|
155
157
|
value,
|
|
156
158
|
configurable: true,
|
|
@@ -590,10 +592,15 @@ function option(...args) {
|
|
|
590
592
|
}
|
|
591
593
|
const invalidOption = context.buffer[0];
|
|
592
594
|
if (options.errors?.noMatch) {
|
|
595
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
596
|
+
success: false,
|
|
597
|
+
consumed: 0,
|
|
598
|
+
error: options.errors.noMatch
|
|
599
|
+
};
|
|
593
600
|
const candidates = /* @__PURE__ */ new Set();
|
|
594
601
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
595
602
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
596
|
-
const errorMessage =
|
|
603
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
597
604
|
return {
|
|
598
605
|
success: false,
|
|
599
606
|
consumed: 0,
|
|
@@ -878,10 +885,15 @@ function flag(...args) {
|
|
|
878
885
|
}
|
|
879
886
|
const invalidOption = context.buffer[0];
|
|
880
887
|
if (options.errors?.noMatch) {
|
|
888
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
889
|
+
success: false,
|
|
890
|
+
consumed: 0,
|
|
891
|
+
error: options.errors.noMatch
|
|
892
|
+
};
|
|
881
893
|
const candidates = /* @__PURE__ */ new Set();
|
|
882
894
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
883
895
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
884
|
-
const errorMessage =
|
|
896
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
885
897
|
return {
|
|
886
898
|
success: false,
|
|
887
899
|
consumed: 0,
|
|
@@ -1190,7 +1202,7 @@ function argument(valueParser, options = {}) {
|
|
|
1190
1202
|
const syncValueParser = valueParser;
|
|
1191
1203
|
const dependencyMetadata = require_dependency_metadata.extractDependencyMetadata(valueParser);
|
|
1192
1204
|
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}`;
|
|
1193
|
-
const optionPattern =
|
|
1205
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1194
1206
|
const term = {
|
|
1195
1207
|
type: "argument",
|
|
1196
1208
|
metavar: valueParser.metavar,
|
|
@@ -1217,14 +1229,15 @@ function argument(valueParser, options = {}) {
|
|
|
1217
1229
|
};
|
|
1218
1230
|
let i = 0;
|
|
1219
1231
|
let optionsTerminated = context.optionsTerminated;
|
|
1220
|
-
if (!optionsTerminated) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1232
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1233
|
+
optionsTerminated = true;
|
|
1234
|
+
i++;
|
|
1235
|
+
} else {
|
|
1236
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1237
|
+
if (optionMatch != null) return {
|
|
1225
1238
|
success: false,
|
|
1226
1239
|
consumed: i,
|
|
1227
|
-
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(
|
|
1240
|
+
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(optionMatch[1])}.`
|
|
1228
1241
|
};
|
|
1229
1242
|
}
|
|
1230
1243
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1734,6 +1747,22 @@ function command(name, parser, options = {}) {
|
|
|
1734
1747
|
configurable: true,
|
|
1735
1748
|
enumerable: false
|
|
1736
1749
|
});
|
|
1750
|
+
require_passthrough.definePassThroughPriority(result, [parser], (state, token) => {
|
|
1751
|
+
const active = normalizeCommandState(state);
|
|
1752
|
+
if (active == null) return void 0;
|
|
1753
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1754
|
+
return require_passthrough.getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1755
|
+
});
|
|
1756
|
+
require_passthrough.defineOptionMatch(result, (state, token) => {
|
|
1757
|
+
const active = normalizeCommandState(state);
|
|
1758
|
+
if (active == null) return void 0;
|
|
1759
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1760
|
+
const match = require_passthrough.getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1761
|
+
return match == null ? void 0 : {
|
|
1762
|
+
...match,
|
|
1763
|
+
continuesCommand: true
|
|
1764
|
+
};
|
|
1765
|
+
});
|
|
1737
1766
|
return require_modifiers.fluent(result);
|
|
1738
1767
|
}
|
|
1739
1768
|
/**
|
|
@@ -1807,6 +1836,8 @@ function passThrough(options = {}) {
|
|
|
1807
1836
|
consumed: 0,
|
|
1808
1837
|
error: require_message.message`No input to pass through.`
|
|
1809
1838
|
};
|
|
1839
|
+
const failure = require_passthrough.getPassThroughFailure(context, this?.priority ?? -10);
|
|
1840
|
+
if (failure != null) return failure.failure;
|
|
1810
1841
|
const token = context.buffer[0];
|
|
1811
1842
|
if (format === "greedy") {
|
|
1812
1843
|
const captured = [...context.buffer];
|
|
@@ -1918,6 +1949,11 @@ function passThrough(options = {}) {
|
|
|
1918
1949
|
return `passThrough(${format})`;
|
|
1919
1950
|
}
|
|
1920
1951
|
};
|
|
1952
|
+
require_passthrough.definePassThroughPriority(result, [result], (_state, token) => {
|
|
1953
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1954
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1955
|
+
return accepts ? result.priority : void 0;
|
|
1956
|
+
});
|
|
1921
1957
|
return require_modifiers.fluent(result);
|
|
1922
1958
|
}
|
|
1923
1959
|
|
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 { effectfulSchedulingNodesKey, exclusiveSourceScopeKey, includeSourceFailureChain, recordDerivedRawInput, replayDerivedParser, replayDerivedParserAsync, sourceCollectionExpansionKey } 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";
|
|
@@ -151,6 +152,7 @@ function constant(value) {
|
|
|
151
152
|
return { fragments: [] };
|
|
152
153
|
}
|
|
153
154
|
};
|
|
155
|
+
defineKnownCompletion(result, (state) => normalizeInjectedAnnotationState(state));
|
|
154
156
|
Object.defineProperty(result, "placeholder", {
|
|
155
157
|
value,
|
|
156
158
|
configurable: true,
|
|
@@ -590,10 +592,15 @@ function option(...args) {
|
|
|
590
592
|
}
|
|
591
593
|
const invalidOption = context.buffer[0];
|
|
592
594
|
if (options.errors?.noMatch) {
|
|
595
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
596
|
+
success: false,
|
|
597
|
+
consumed: 0,
|
|
598
|
+
error: options.errors.noMatch
|
|
599
|
+
};
|
|
593
600
|
const candidates = /* @__PURE__ */ new Set();
|
|
594
601
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
595
602
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
596
|
-
const errorMessage =
|
|
603
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
597
604
|
return {
|
|
598
605
|
success: false,
|
|
599
606
|
consumed: 0,
|
|
@@ -878,10 +885,15 @@ function flag(...args) {
|
|
|
878
885
|
}
|
|
879
886
|
const invalidOption = context.buffer[0];
|
|
880
887
|
if (options.errors?.noMatch) {
|
|
888
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
889
|
+
success: false,
|
|
890
|
+
consumed: 0,
|
|
891
|
+
error: options.errors.noMatch
|
|
892
|
+
};
|
|
881
893
|
const candidates = /* @__PURE__ */ new Set();
|
|
882
894
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
883
895
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
884
|
-
const errorMessage =
|
|
896
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
885
897
|
return {
|
|
886
898
|
success: false,
|
|
887
899
|
consumed: 0,
|
|
@@ -1190,7 +1202,7 @@ function argument(valueParser, options = {}) {
|
|
|
1190
1202
|
const syncValueParser = valueParser;
|
|
1191
1203
|
const dependencyMetadata = extractDependencyMetadata(valueParser);
|
|
1192
1204
|
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${metavar(valueParser.metavar)}: ${error}`;
|
|
1193
|
-
const optionPattern =
|
|
1205
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1194
1206
|
const term = {
|
|
1195
1207
|
type: "argument",
|
|
1196
1208
|
metavar: valueParser.metavar,
|
|
@@ -1217,14 +1229,15 @@ function argument(valueParser, options = {}) {
|
|
|
1217
1229
|
};
|
|
1218
1230
|
let i = 0;
|
|
1219
1231
|
let optionsTerminated = context.optionsTerminated;
|
|
1220
|
-
if (!optionsTerminated) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1232
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1233
|
+
optionsTerminated = true;
|
|
1234
|
+
i++;
|
|
1235
|
+
} else {
|
|
1236
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1237
|
+
if (optionMatch != null) return {
|
|
1225
1238
|
success: false,
|
|
1226
1239
|
consumed: i,
|
|
1227
|
-
error: message`Expected an argument, but got an option: ${optionName(
|
|
1240
|
+
error: message`Expected an argument, but got an option: ${optionName(optionMatch[1])}.`
|
|
1228
1241
|
};
|
|
1229
1242
|
}
|
|
1230
1243
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1734,6 +1747,22 @@ function command(name, parser, options = {}) {
|
|
|
1734
1747
|
configurable: true,
|
|
1735
1748
|
enumerable: false
|
|
1736
1749
|
});
|
|
1750
|
+
definePassThroughPriority(result, [parser], (state, token) => {
|
|
1751
|
+
const active = normalizeCommandState(state);
|
|
1752
|
+
if (active == null) return void 0;
|
|
1753
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1754
|
+
return getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1755
|
+
});
|
|
1756
|
+
defineOptionMatch(result, (state, token) => {
|
|
1757
|
+
const active = normalizeCommandState(state);
|
|
1758
|
+
if (active == null) return void 0;
|
|
1759
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1760
|
+
const match = getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1761
|
+
return match == null ? void 0 : {
|
|
1762
|
+
...match,
|
|
1763
|
+
continuesCommand: true
|
|
1764
|
+
};
|
|
1765
|
+
});
|
|
1737
1766
|
return fluent(result);
|
|
1738
1767
|
}
|
|
1739
1768
|
/**
|
|
@@ -1807,6 +1836,8 @@ function passThrough(options = {}) {
|
|
|
1807
1836
|
consumed: 0,
|
|
1808
1837
|
error: message`No input to pass through.`
|
|
1809
1838
|
};
|
|
1839
|
+
const failure = getPassThroughFailure(context, this?.priority ?? -10);
|
|
1840
|
+
if (failure != null) return failure.failure;
|
|
1810
1841
|
const token = context.buffer[0];
|
|
1811
1842
|
if (format === "greedy") {
|
|
1812
1843
|
const captured = [...context.buffer];
|
|
@@ -1918,6 +1949,11 @@ function passThrough(options = {}) {
|
|
|
1918
1949
|
return `passThrough(${format})`;
|
|
1919
1950
|
}
|
|
1920
1951
|
};
|
|
1952
|
+
definePassThroughPriority(result, [result], (_state, token) => {
|
|
1953
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1954
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1955
|
+
return accepts ? result.priority : void 0;
|
|
1956
|
+
});
|
|
1921
1957
|
return fluent(result);
|
|
1922
1958
|
}
|
|
1923
1959
|
|
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.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
},
|
|
238
238
|
"sideEffects": false,
|
|
239
239
|
"devDependencies": {
|
|
240
|
-
"@optique/env": "1.3.
|
|
240
|
+
"@optique/env": "1.3.2",
|
|
241
241
|
"@types/node": "^24.0.0",
|
|
242
242
|
"fast-check": "^4.7.0",
|
|
243
243
|
"tsdown": "^0.13.0",
|