@optique/core 1.4.0-dev.2638 → 1.4.0-dev.2661
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 +261 -41
- package/dist/constructs.js +261 -41
- 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
|
@@ -9,6 +9,7 @@ const require_annotation_state = require('./annotation-state.cjs');
|
|
|
9
9
|
const require_execution_context = require('./execution-context.cjs');
|
|
10
10
|
const require_usage_internals = require('./usage-internals.cjs');
|
|
11
11
|
const require_short_option = require('./short-option.cjs');
|
|
12
|
+
const require_passthrough = require('./internal/passthrough.cjs');
|
|
12
13
|
const require_command_alias = require('./internal/command-alias.cjs');
|
|
13
14
|
const require_phase2_seed = require('./phase2-seed.cjs');
|
|
14
15
|
const require_dependency_metadata = require('./dependency-metadata.cjs');
|
|
@@ -155,6 +156,7 @@ function constant(value) {
|
|
|
155
156
|
};
|
|
156
157
|
}
|
|
157
158
|
};
|
|
159
|
+
require_passthrough.defineKnownCompletion(result, (state) => require_annotation_state.normalizeInjectedAnnotationState(state));
|
|
158
160
|
Object.defineProperty(result, "placeholder", {
|
|
159
161
|
value,
|
|
160
162
|
configurable: true,
|
|
@@ -633,10 +635,15 @@ function option(...args) {
|
|
|
633
635
|
}
|
|
634
636
|
const invalidOption = context.buffer[0];
|
|
635
637
|
if (options.errors?.noMatch) {
|
|
638
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
639
|
+
success: false,
|
|
640
|
+
consumed: 0,
|
|
641
|
+
error: options.errors.noMatch
|
|
642
|
+
};
|
|
636
643
|
const candidates = /* @__PURE__ */ new Set();
|
|
637
644
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
638
645
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
639
|
-
const errorMessage =
|
|
646
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
640
647
|
return {
|
|
641
648
|
success: false,
|
|
642
649
|
consumed: 0,
|
|
@@ -922,10 +929,15 @@ function flag(...args) {
|
|
|
922
929
|
}
|
|
923
930
|
const invalidOption = context.buffer[0];
|
|
924
931
|
if (options.errors?.noMatch) {
|
|
932
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
933
|
+
success: false,
|
|
934
|
+
consumed: 0,
|
|
935
|
+
error: options.errors.noMatch
|
|
936
|
+
};
|
|
925
937
|
const candidates = /* @__PURE__ */ new Set();
|
|
926
938
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
927
939
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
928
|
-
const errorMessage =
|
|
940
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
929
941
|
return {
|
|
930
942
|
success: false,
|
|
931
943
|
consumed: 0,
|
|
@@ -1234,7 +1246,7 @@ function argument(valueParser, options = {}) {
|
|
|
1234
1246
|
const syncValueParser = valueParser;
|
|
1235
1247
|
const dependencyMetadata = require_dependency_metadata.extractDependencyMetadata(valueParser);
|
|
1236
1248
|
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}`;
|
|
1237
|
-
const optionPattern =
|
|
1249
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1238
1250
|
const term = {
|
|
1239
1251
|
type: "argument",
|
|
1240
1252
|
metavar: valueParser.metavar,
|
|
@@ -1261,14 +1273,15 @@ function argument(valueParser, options = {}) {
|
|
|
1261
1273
|
};
|
|
1262
1274
|
let i = 0;
|
|
1263
1275
|
let optionsTerminated = context.optionsTerminated;
|
|
1264
|
-
if (!optionsTerminated) {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1276
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1277
|
+
optionsTerminated = true;
|
|
1278
|
+
i++;
|
|
1279
|
+
} else {
|
|
1280
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1281
|
+
if (optionMatch != null) return {
|
|
1269
1282
|
success: false,
|
|
1270
1283
|
consumed: i,
|
|
1271
|
-
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(
|
|
1284
|
+
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(optionMatch[1])}.`
|
|
1272
1285
|
};
|
|
1273
1286
|
}
|
|
1274
1287
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1781,6 +1794,22 @@ function command(name, parser, options = {}) {
|
|
|
1781
1794
|
configurable: true,
|
|
1782
1795
|
enumerable: false
|
|
1783
1796
|
});
|
|
1797
|
+
require_passthrough.definePassThroughPriority(result, [parser], (state, token) => {
|
|
1798
|
+
const active = normalizeCommandState(state);
|
|
1799
|
+
if (active == null) return void 0;
|
|
1800
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1801
|
+
return require_passthrough.getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1802
|
+
});
|
|
1803
|
+
require_passthrough.defineOptionMatch(result, (state, token) => {
|
|
1804
|
+
const active = normalizeCommandState(state);
|
|
1805
|
+
if (active == null) return void 0;
|
|
1806
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1807
|
+
const match = require_passthrough.getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1808
|
+
return match == null ? void 0 : {
|
|
1809
|
+
...match,
|
|
1810
|
+
continuesCommand: true
|
|
1811
|
+
};
|
|
1812
|
+
});
|
|
1784
1813
|
return require_modifiers.fluent(require_short_option.scopeParser(result, commandScope.source, (context) => {
|
|
1785
1814
|
if (normalizeCommandState(context.state) != null) commandScope.select(context, enteredScope);
|
|
1786
1815
|
}));
|
|
@@ -1856,6 +1885,8 @@ function passThrough(options = {}) {
|
|
|
1856
1885
|
consumed: 0,
|
|
1857
1886
|
error: require_message.message`No input to pass through.`
|
|
1858
1887
|
};
|
|
1888
|
+
const failure = require_passthrough.getPassThroughFailure(context, this?.priority ?? -10);
|
|
1889
|
+
if (failure != null) return failure.failure;
|
|
1859
1890
|
const token = context.buffer[0];
|
|
1860
1891
|
if (format === "greedy") {
|
|
1861
1892
|
const captured = [...context.buffer];
|
|
@@ -1967,6 +1998,11 @@ function passThrough(options = {}) {
|
|
|
1967
1998
|
return `passThrough(${format})`;
|
|
1968
1999
|
}
|
|
1969
2000
|
};
|
|
2001
|
+
require_passthrough.definePassThroughPriority(result, [result], (_state, token) => {
|
|
2002
|
+
if (token == null || format === "greedy") return result.priority;
|
|
2003
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
2004
|
+
return accepts ? result.priority : void 0;
|
|
2005
|
+
});
|
|
1970
2006
|
return require_modifiers.fluent(result);
|
|
1971
2007
|
}
|
|
1972
2008
|
|
package/dist/primitives.js
CHANGED
|
@@ -9,6 +9,7 @@ import { getWrappedChildParseState, getWrappedChildState, isAnnotationWrappedIni
|
|
|
9
9
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
10
10
|
import { extractLeadingCommandNames } from "./usage-internals.js";
|
|
11
11
|
import { attachedValuePrefix, combinedOptionScope, fullNameOwnsToken, prefixSuggestion, scopeParser, selectableOptionScope } from "./short-option.js";
|
|
12
|
+
import { defineKnownCompletion, defineOptionMatch, definePassThroughPriority, getOptionMatch, getPassThroughFailure, getPassThroughPriority } from "./internal/passthrough.js";
|
|
12
13
|
import { hiddenCommandAliasesKey } from "./internal/command-alias.js";
|
|
13
14
|
import { completeOrExtractPhase2Seed, extractPhase2SeedKey } from "./phase2-seed.js";
|
|
14
15
|
import { extractDependencyMetadata } from "./dependency-metadata.js";
|
|
@@ -155,6 +156,7 @@ function constant(value) {
|
|
|
155
156
|
};
|
|
156
157
|
}
|
|
157
158
|
};
|
|
159
|
+
defineKnownCompletion(result, (state) => normalizeInjectedAnnotationState(state));
|
|
158
160
|
Object.defineProperty(result, "placeholder", {
|
|
159
161
|
value,
|
|
160
162
|
configurable: true,
|
|
@@ -633,10 +635,15 @@ function option(...args) {
|
|
|
633
635
|
}
|
|
634
636
|
const invalidOption = context.buffer[0];
|
|
635
637
|
if (options.errors?.noMatch) {
|
|
638
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
639
|
+
success: false,
|
|
640
|
+
consumed: 0,
|
|
641
|
+
error: options.errors.noMatch
|
|
642
|
+
};
|
|
636
643
|
const candidates = /* @__PURE__ */ new Set();
|
|
637
644
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
638
645
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
639
|
-
const errorMessage =
|
|
646
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
640
647
|
return {
|
|
641
648
|
success: false,
|
|
642
649
|
consumed: 0,
|
|
@@ -922,10 +929,15 @@ function flag(...args) {
|
|
|
922
929
|
}
|
|
923
930
|
const invalidOption = context.buffer[0];
|
|
924
931
|
if (options.errors?.noMatch) {
|
|
932
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
933
|
+
success: false,
|
|
934
|
+
consumed: 0,
|
|
935
|
+
error: options.errors.noMatch
|
|
936
|
+
};
|
|
925
937
|
const candidates = /* @__PURE__ */ new Set();
|
|
926
938
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
927
939
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
928
|
-
const errorMessage =
|
|
940
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
929
941
|
return {
|
|
930
942
|
success: false,
|
|
931
943
|
consumed: 0,
|
|
@@ -1234,7 +1246,7 @@ function argument(valueParser, options = {}) {
|
|
|
1234
1246
|
const syncValueParser = valueParser;
|
|
1235
1247
|
const dependencyMetadata = extractDependencyMetadata(valueParser);
|
|
1236
1248
|
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${metavar(valueParser.metavar)}: ${error}`;
|
|
1237
|
-
const optionPattern =
|
|
1249
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1238
1250
|
const term = {
|
|
1239
1251
|
type: "argument",
|
|
1240
1252
|
metavar: valueParser.metavar,
|
|
@@ -1261,14 +1273,15 @@ function argument(valueParser, options = {}) {
|
|
|
1261
1273
|
};
|
|
1262
1274
|
let i = 0;
|
|
1263
1275
|
let optionsTerminated = context.optionsTerminated;
|
|
1264
|
-
if (!optionsTerminated) {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1276
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1277
|
+
optionsTerminated = true;
|
|
1278
|
+
i++;
|
|
1279
|
+
} else {
|
|
1280
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1281
|
+
if (optionMatch != null) return {
|
|
1269
1282
|
success: false,
|
|
1270
1283
|
consumed: i,
|
|
1271
|
-
error: message`Expected an argument, but got an option: ${optionName(
|
|
1284
|
+
error: message`Expected an argument, but got an option: ${optionName(optionMatch[1])}.`
|
|
1272
1285
|
};
|
|
1273
1286
|
}
|
|
1274
1287
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1781,6 +1794,22 @@ function command(name, parser, options = {}) {
|
|
|
1781
1794
|
configurable: true,
|
|
1782
1795
|
enumerable: false
|
|
1783
1796
|
});
|
|
1797
|
+
definePassThroughPriority(result, [parser], (state, token) => {
|
|
1798
|
+
const active = normalizeCommandState(state);
|
|
1799
|
+
if (active == null) return void 0;
|
|
1800
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1801
|
+
return getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1802
|
+
});
|
|
1803
|
+
defineOptionMatch(result, (state, token) => {
|
|
1804
|
+
const active = normalizeCommandState(state);
|
|
1805
|
+
if (active == null) return void 0;
|
|
1806
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1807
|
+
const match = getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1808
|
+
return match == null ? void 0 : {
|
|
1809
|
+
...match,
|
|
1810
|
+
continuesCommand: true
|
|
1811
|
+
};
|
|
1812
|
+
});
|
|
1784
1813
|
return fluent(scopeParser(result, commandScope.source, (context) => {
|
|
1785
1814
|
if (normalizeCommandState(context.state) != null) commandScope.select(context, enteredScope);
|
|
1786
1815
|
}));
|
|
@@ -1856,6 +1885,8 @@ function passThrough(options = {}) {
|
|
|
1856
1885
|
consumed: 0,
|
|
1857
1886
|
error: message`No input to pass through.`
|
|
1858
1887
|
};
|
|
1888
|
+
const failure = getPassThroughFailure(context, this?.priority ?? -10);
|
|
1889
|
+
if (failure != null) return failure.failure;
|
|
1859
1890
|
const token = context.buffer[0];
|
|
1860
1891
|
if (format === "greedy") {
|
|
1861
1892
|
const captured = [...context.buffer];
|
|
@@ -1967,6 +1998,11 @@ function passThrough(options = {}) {
|
|
|
1967
1998
|
return `passThrough(${format})`;
|
|
1968
1999
|
}
|
|
1969
2000
|
};
|
|
2001
|
+
definePassThroughPriority(result, [result], (_state, token) => {
|
|
2002
|
+
if (token == null || format === "greedy") return result.priority;
|
|
2003
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
2004
|
+
return accepts ? result.priority : void 0;
|
|
2005
|
+
});
|
|
1970
2006
|
return fluent(result);
|
|
1971
2007
|
}
|
|
1972
2008
|
|
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.4.0-dev.
|
|
3
|
+
"version": "1.4.0-dev.2661",
|
|
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.4.0-dev.
|
|
240
|
+
"@optique/env": "1.4.0-dev.2661+04e7de36",
|
|
241
241
|
"@types/node": "^24.0.0",
|
|
242
242
|
"fast-check": "^4.7.0",
|
|
243
243
|
"tsdown": "^0.13.0",
|