@optique/core 1.2.0-dev.2241 → 1.2.0-dev.2242
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/suggestion.cjs +41 -0
- package/dist/suggestion.d.cts +29 -1
- package/dist/suggestion.d.ts +29 -1
- package/dist/suggestion.js +42 -2
- package/dist/valueparser.cjs +24 -4
- package/dist/valueparser.d.cts +20 -0
- package/dist/valueparser.d.ts +20 -0
- package/dist/valueparser.js +25 -5
- package/package.json +10 -2
package/dist/suggestion.cjs
CHANGED
|
@@ -251,6 +251,46 @@ function createErrorWithSuggestions(baseError, invalidInput, usage, type = "both
|
|
|
251
251
|
] : baseError;
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
254
|
+
* Appends a "Did you mean …?" hint to a base error message when the input
|
|
255
|
+
* is close to one of the candidate values.
|
|
256
|
+
*
|
|
257
|
+
* This helper is meant for closed-set value parsers (e.g. `choice()`) that
|
|
258
|
+
* want to surface near-match suggestions without re-implementing distance
|
|
259
|
+
* logic themselves. It wraps {@link findSimilar} and
|
|
260
|
+
* {@link createSuggestionMessage} and returns the `base` message unchanged
|
|
261
|
+
* when no candidates are close enough.
|
|
262
|
+
*
|
|
263
|
+
* @param base The base error message to display.
|
|
264
|
+
* @param input The invalid input the user typed.
|
|
265
|
+
* @param candidates The list of valid candidate strings to suggest from.
|
|
266
|
+
* @param options Optional thresholds; defaults to
|
|
267
|
+
* {@link DEFAULT_FIND_SIMILAR_OPTIONS}.
|
|
268
|
+
* @returns `base` with a "Did you mean …?" line appended when a close
|
|
269
|
+
* candidate is found, or `base` unchanged when none are found.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```typescript
|
|
273
|
+
* const base = message`Invalid color: ${input}.`;
|
|
274
|
+
* appendValueHint(base, input, ["red", "green", "blue"]);
|
|
275
|
+
* // → "Invalid color: redd.\n\nDid you mean `red`?"
|
|
276
|
+
* ```
|
|
277
|
+
*
|
|
278
|
+
* @since 1.2.0
|
|
279
|
+
*/
|
|
280
|
+
function appendValueHint(base, input, candidates, options) {
|
|
281
|
+
const suggestions = findSimilar(input, candidates, options != null ? {
|
|
282
|
+
...DEFAULT_FIND_SIMILAR_OPTIONS,
|
|
283
|
+
...options
|
|
284
|
+
} : void 0);
|
|
285
|
+
const suggestionMsg = createSuggestionMessage(suggestions);
|
|
286
|
+
return suggestionMsg.length > 0 ? [
|
|
287
|
+
...base,
|
|
288
|
+
require_message.lineBreak(),
|
|
289
|
+
require_message.lineBreak(),
|
|
290
|
+
...suggestionMsg
|
|
291
|
+
] : base;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
254
294
|
* Creates a unique key for a suggestion to enable deduplication.
|
|
255
295
|
*
|
|
256
296
|
* For literal suggestions, the text itself is used as the key.
|
|
@@ -313,6 +353,7 @@ function deduplicateSuggestions(suggestions) {
|
|
|
313
353
|
|
|
314
354
|
//#endregion
|
|
315
355
|
exports.DEFAULT_FIND_SIMILAR_OPTIONS = DEFAULT_FIND_SIMILAR_OPTIONS;
|
|
356
|
+
exports.appendValueHint = appendValueHint;
|
|
316
357
|
exports.createErrorWithSuggestions = createErrorWithSuggestions;
|
|
317
358
|
exports.createSuggestionMessage = createSuggestionMessage;
|
|
318
359
|
exports.deduplicateSuggestions = deduplicateSuggestions;
|
package/dist/suggestion.d.cts
CHANGED
|
@@ -154,6 +154,34 @@ declare function expandCommandAliasSuggestions(usage: Usage, suggestions: readon
|
|
|
154
154
|
* @since 0.7.0
|
|
155
155
|
*/
|
|
156
156
|
declare function createErrorWithSuggestions(baseError: Message, invalidInput: string, usage: Usage, type?: "option" | "command" | "both", customFormatter?: (suggestions: readonly string[]) => Message): Message;
|
|
157
|
+
/**
|
|
158
|
+
* Appends a "Did you mean …?" hint to a base error message when the input
|
|
159
|
+
* is close to one of the candidate values.
|
|
160
|
+
*
|
|
161
|
+
* This helper is meant for closed-set value parsers (e.g. `choice()`) that
|
|
162
|
+
* want to surface near-match suggestions without re-implementing distance
|
|
163
|
+
* logic themselves. It wraps {@link findSimilar} and
|
|
164
|
+
* {@link createSuggestionMessage} and returns the `base` message unchanged
|
|
165
|
+
* when no candidates are close enough.
|
|
166
|
+
*
|
|
167
|
+
* @param base The base error message to display.
|
|
168
|
+
* @param input The invalid input the user typed.
|
|
169
|
+
* @param candidates The list of valid candidate strings to suggest from.
|
|
170
|
+
* @param options Optional thresholds; defaults to
|
|
171
|
+
* {@link DEFAULT_FIND_SIMILAR_OPTIONS}.
|
|
172
|
+
* @returns `base` with a "Did you mean …?" line appended when a close
|
|
173
|
+
* candidate is found, or `base` unchanged when none are found.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const base = message`Invalid color: ${input}.`;
|
|
178
|
+
* appendValueHint(base, input, ["red", "green", "blue"]);
|
|
179
|
+
* // → "Invalid color: redd.\n\nDid you mean `red`?"
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @since 1.2.0
|
|
183
|
+
*/
|
|
184
|
+
declare function appendValueHint(base: Message, input: string, candidates: readonly string[], options?: Readonly<Pick<FindSimilarOptions, "maxDistance" | "maxSuggestions">>): Message;
|
|
157
185
|
/**
|
|
158
186
|
* Removes duplicate suggestions from an array while preserving order.
|
|
159
187
|
*
|
|
@@ -185,4 +213,4 @@ declare function createErrorWithSuggestions(baseError: Message, invalidInput: st
|
|
|
185
213
|
*/
|
|
186
214
|
declare function deduplicateSuggestions(suggestions: readonly Suggestion[]): Suggestion[];
|
|
187
215
|
//#endregion
|
|
188
|
-
export { DEFAULT_FIND_SIMILAR_OPTIONS, FindSimilarOptions, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, expandCommandAliasSuggestions, findSimilar, levenshteinDistance };
|
|
216
|
+
export { DEFAULT_FIND_SIMILAR_OPTIONS, FindSimilarOptions, appendValueHint, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, expandCommandAliasSuggestions, findSimilar, levenshteinDistance };
|
package/dist/suggestion.d.ts
CHANGED
|
@@ -154,6 +154,34 @@ declare function expandCommandAliasSuggestions(usage: Usage, suggestions: readon
|
|
|
154
154
|
* @since 0.7.0
|
|
155
155
|
*/
|
|
156
156
|
declare function createErrorWithSuggestions(baseError: Message, invalidInput: string, usage: Usage, type?: "option" | "command" | "both", customFormatter?: (suggestions: readonly string[]) => Message): Message;
|
|
157
|
+
/**
|
|
158
|
+
* Appends a "Did you mean …?" hint to a base error message when the input
|
|
159
|
+
* is close to one of the candidate values.
|
|
160
|
+
*
|
|
161
|
+
* This helper is meant for closed-set value parsers (e.g. `choice()`) that
|
|
162
|
+
* want to surface near-match suggestions without re-implementing distance
|
|
163
|
+
* logic themselves. It wraps {@link findSimilar} and
|
|
164
|
+
* {@link createSuggestionMessage} and returns the `base` message unchanged
|
|
165
|
+
* when no candidates are close enough.
|
|
166
|
+
*
|
|
167
|
+
* @param base The base error message to display.
|
|
168
|
+
* @param input The invalid input the user typed.
|
|
169
|
+
* @param candidates The list of valid candidate strings to suggest from.
|
|
170
|
+
* @param options Optional thresholds; defaults to
|
|
171
|
+
* {@link DEFAULT_FIND_SIMILAR_OPTIONS}.
|
|
172
|
+
* @returns `base` with a "Did you mean …?" line appended when a close
|
|
173
|
+
* candidate is found, or `base` unchanged when none are found.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const base = message`Invalid color: ${input}.`;
|
|
178
|
+
* appendValueHint(base, input, ["red", "green", "blue"]);
|
|
179
|
+
* // → "Invalid color: redd.\n\nDid you mean `red`?"
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @since 1.2.0
|
|
183
|
+
*/
|
|
184
|
+
declare function appendValueHint(base: Message, input: string, candidates: readonly string[], options?: Readonly<Pick<FindSimilarOptions, "maxDistance" | "maxSuggestions">>): Message;
|
|
157
185
|
/**
|
|
158
186
|
* Removes duplicate suggestions from an array while preserving order.
|
|
159
187
|
*
|
|
@@ -185,4 +213,4 @@ declare function createErrorWithSuggestions(baseError: Message, invalidInput: st
|
|
|
185
213
|
*/
|
|
186
214
|
declare function deduplicateSuggestions(suggestions: readonly Suggestion[]): Suggestion[];
|
|
187
215
|
//#endregion
|
|
188
|
-
export { DEFAULT_FIND_SIMILAR_OPTIONS, FindSimilarOptions, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, expandCommandAliasSuggestions, findSimilar, levenshteinDistance };
|
|
216
|
+
export { DEFAULT_FIND_SIMILAR_OPTIONS, FindSimilarOptions, appendValueHint, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, expandCommandAliasSuggestions, findSimilar, levenshteinDistance };
|
package/dist/suggestion.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { message, optionName, text } from "./message.js";
|
|
1
|
+
import { lineBreak, message, optionName, text } from "./message.js";
|
|
2
2
|
import { extractCommandNames, extractOptionNames, isSuggestionHidden } from "./usage.js";
|
|
3
3
|
|
|
4
4
|
//#region src/suggestion.ts
|
|
@@ -251,6 +251,46 @@ function createErrorWithSuggestions(baseError, invalidInput, usage, type = "both
|
|
|
251
251
|
] : baseError;
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
254
|
+
* Appends a "Did you mean …?" hint to a base error message when the input
|
|
255
|
+
* is close to one of the candidate values.
|
|
256
|
+
*
|
|
257
|
+
* This helper is meant for closed-set value parsers (e.g. `choice()`) that
|
|
258
|
+
* want to surface near-match suggestions without re-implementing distance
|
|
259
|
+
* logic themselves. It wraps {@link findSimilar} and
|
|
260
|
+
* {@link createSuggestionMessage} and returns the `base` message unchanged
|
|
261
|
+
* when no candidates are close enough.
|
|
262
|
+
*
|
|
263
|
+
* @param base The base error message to display.
|
|
264
|
+
* @param input The invalid input the user typed.
|
|
265
|
+
* @param candidates The list of valid candidate strings to suggest from.
|
|
266
|
+
* @param options Optional thresholds; defaults to
|
|
267
|
+
* {@link DEFAULT_FIND_SIMILAR_OPTIONS}.
|
|
268
|
+
* @returns `base` with a "Did you mean …?" line appended when a close
|
|
269
|
+
* candidate is found, or `base` unchanged when none are found.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```typescript
|
|
273
|
+
* const base = message`Invalid color: ${input}.`;
|
|
274
|
+
* appendValueHint(base, input, ["red", "green", "blue"]);
|
|
275
|
+
* // → "Invalid color: redd.\n\nDid you mean `red`?"
|
|
276
|
+
* ```
|
|
277
|
+
*
|
|
278
|
+
* @since 1.2.0
|
|
279
|
+
*/
|
|
280
|
+
function appendValueHint(base, input, candidates, options) {
|
|
281
|
+
const suggestions = findSimilar(input, candidates, options != null ? {
|
|
282
|
+
...DEFAULT_FIND_SIMILAR_OPTIONS,
|
|
283
|
+
...options
|
|
284
|
+
} : void 0);
|
|
285
|
+
const suggestionMsg = createSuggestionMessage(suggestions);
|
|
286
|
+
return suggestionMsg.length > 0 ? [
|
|
287
|
+
...base,
|
|
288
|
+
lineBreak(),
|
|
289
|
+
lineBreak(),
|
|
290
|
+
...suggestionMsg
|
|
291
|
+
] : base;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
254
294
|
* Creates a unique key for a suggestion to enable deduplication.
|
|
255
295
|
*
|
|
256
296
|
* For literal suggestions, the text itself is used as the key.
|
|
@@ -312,4 +352,4 @@ function deduplicateSuggestions(suggestions) {
|
|
|
312
352
|
}
|
|
313
353
|
|
|
314
354
|
//#endregion
|
|
315
|
-
export { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, expandCommandAliasSuggestions, findSimilar, levenshteinDistance };
|
|
355
|
+
export { DEFAULT_FIND_SIMILAR_OPTIONS, appendValueHint, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, expandCommandAliasSuggestions, findSimilar, levenshteinDistance };
|
package/dist/valueparser.cjs
CHANGED
|
@@ -139,6 +139,13 @@ function choice(choices, options = {}) {
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
const stringInvalidChoice = stringOptions.errors?.invalidChoice;
|
|
142
|
+
const stringSuggest = stringOptions.suggest;
|
|
143
|
+
if (stringSuggest !== void 0) {
|
|
144
|
+
const isValidString = stringSuggest === "nearest" || stringSuggest === "never";
|
|
145
|
+
const isValidObject = typeof stringSuggest === "object" && stringSuggest !== null;
|
|
146
|
+
const isValidFunction = typeof stringSuggest === "function";
|
|
147
|
+
if (!isValidString && !isValidObject && !isValidFunction) throw new TypeError(`Expected suggest to be "nearest", "never", an object, or a function, but got ${typeof stringSuggest}: ${String(stringSuggest)}.`);
|
|
148
|
+
}
|
|
142
149
|
return {
|
|
143
150
|
mode: "sync",
|
|
144
151
|
metavar: metavar$1,
|
|
@@ -149,7 +156,7 @@ function choice(choices, options = {}) {
|
|
|
149
156
|
const index = normalizedValues.indexOf(normalizedInput);
|
|
150
157
|
if (index < 0) return {
|
|
151
158
|
success: false,
|
|
152
|
-
error: formatStringChoiceError(input, stringChoices, stringInvalidChoice)
|
|
159
|
+
error: formatStringChoiceError(input, stringChoices, stringInvalidChoice, stringSuggest)
|
|
153
160
|
};
|
|
154
161
|
return {
|
|
155
162
|
success: true,
|
|
@@ -256,9 +263,22 @@ function normalizeDecimal(s) {
|
|
|
256
263
|
/**
|
|
257
264
|
* Formats error message for string choice parser.
|
|
258
265
|
*/
|
|
259
|
-
function formatStringChoiceError(input, choices, invalidChoice) {
|
|
260
|
-
|
|
261
|
-
|
|
266
|
+
function formatStringChoiceError(input, choices, invalidChoice, suggest) {
|
|
267
|
+
const base = invalidChoice ? typeof invalidChoice === "function" ? invalidChoice(input, choices) : invalidChoice : formatDefaultChoiceError(input, choices);
|
|
268
|
+
if (suggest == null || suggest === "never") return base;
|
|
269
|
+
if (suggest === "nearest") return require_suggestion.appendValueHint(base, input, choices);
|
|
270
|
+
if (typeof suggest === "function") {
|
|
271
|
+
const hints = suggest(input, choices);
|
|
272
|
+
if (!hints || hints.length === 0) return base;
|
|
273
|
+
const suggestionMsg = require_suggestion.createSuggestionMessage(hints);
|
|
274
|
+
return suggestionMsg.length > 0 ? [
|
|
275
|
+
...base,
|
|
276
|
+
require_message.lineBreak(),
|
|
277
|
+
require_message.lineBreak(),
|
|
278
|
+
...suggestionMsg
|
|
279
|
+
] : base;
|
|
280
|
+
}
|
|
281
|
+
return require_suggestion.appendValueHint(base, input, choices, suggest);
|
|
262
282
|
}
|
|
263
283
|
/**
|
|
264
284
|
* Formats error message for number choice parser.
|
package/dist/valueparser.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NonEmptyString, ensureNonEmptyString, isNonEmptyString } from "./nonempty.cjs";
|
|
2
2
|
import { Message } from "./message.cjs";
|
|
3
|
+
import { FindSimilarOptions } from "./suggestion.cjs";
|
|
3
4
|
import { Mode, ModeIterable, ModeValue, Suggestion } from "./internal/parser.cjs";
|
|
4
5
|
|
|
5
6
|
//#region src/valueparser.d.ts
|
|
@@ -269,6 +270,25 @@ interface ChoiceOptionsString extends ChoiceOptionsBase {
|
|
|
269
270
|
* @default `false`
|
|
270
271
|
*/
|
|
271
272
|
readonly caseInsensitive?: boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Controls whether the error message for an invalid value includes a
|
|
275
|
+
* "Did you mean …?" hint based on Levenshtein distance.
|
|
276
|
+
*
|
|
277
|
+
* - `"nearest"`: append a hint with the closest valid choice(s) using
|
|
278
|
+
* default distance thresholds. Recommended for small-to-medium
|
|
279
|
+
* enumeration sets.
|
|
280
|
+
* - `{ maxDistance?, maxSuggestions? }`: same as `"nearest"` but with
|
|
281
|
+
* custom thresholds.
|
|
282
|
+
* - `"never"`: disable hints; emit the plain "not one of" error message
|
|
283
|
+
* unchanged.
|
|
284
|
+
* - A function `(input, choices) => readonly string[] | undefined`:
|
|
285
|
+
* custom suggestion logic. Return `undefined` to suppress the hint,
|
|
286
|
+
* or a non-empty array of strings to display as suggestions.
|
|
287
|
+
*
|
|
288
|
+
* @default `"never"` (backward-compatible: no hint is appended)
|
|
289
|
+
* @since 1.2.0
|
|
290
|
+
*/
|
|
291
|
+
readonly suggest?: "nearest" | "never" | Readonly<Pick<FindSimilarOptions, "maxDistance" | "maxSuggestions">> | ((input: string, choices: readonly string[]) => readonly string[] | undefined);
|
|
272
292
|
/**
|
|
273
293
|
* Custom error messages for choice parsing failures.
|
|
274
294
|
* @since 0.5.0
|
package/dist/valueparser.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NonEmptyString, ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
|
|
2
2
|
import { Message } from "./message.js";
|
|
3
|
+
import { FindSimilarOptions } from "./suggestion.js";
|
|
3
4
|
import { Mode, ModeIterable, ModeValue, Suggestion } from "./internal/parser.js";
|
|
4
5
|
|
|
5
6
|
//#region src/valueparser.d.ts
|
|
@@ -269,6 +270,25 @@ interface ChoiceOptionsString extends ChoiceOptionsBase {
|
|
|
269
270
|
* @default `false`
|
|
270
271
|
*/
|
|
271
272
|
readonly caseInsensitive?: boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Controls whether the error message for an invalid value includes a
|
|
275
|
+
* "Did you mean …?" hint based on Levenshtein distance.
|
|
276
|
+
*
|
|
277
|
+
* - `"nearest"`: append a hint with the closest valid choice(s) using
|
|
278
|
+
* default distance thresholds. Recommended for small-to-medium
|
|
279
|
+
* enumeration sets.
|
|
280
|
+
* - `{ maxDistance?, maxSuggestions? }`: same as `"nearest"` but with
|
|
281
|
+
* custom thresholds.
|
|
282
|
+
* - `"never"`: disable hints; emit the plain "not one of" error message
|
|
283
|
+
* unchanged.
|
|
284
|
+
* - A function `(input, choices) => readonly string[] | undefined`:
|
|
285
|
+
* custom suggestion logic. Return `undefined` to suppress the hint,
|
|
286
|
+
* or a non-empty array of strings to display as suggestions.
|
|
287
|
+
*
|
|
288
|
+
* @default `"never"` (backward-compatible: no hint is appended)
|
|
289
|
+
* @since 1.2.0
|
|
290
|
+
*/
|
|
291
|
+
readonly suggest?: "nearest" | "never" | Readonly<Pick<FindSimilarOptions, "maxDistance" | "maxSuggestions">> | ((input: string, choices: readonly string[]) => readonly string[] | undefined);
|
|
272
292
|
/**
|
|
273
293
|
* Custom error messages for choice parsing failures.
|
|
274
294
|
* @since 0.5.0
|
package/dist/valueparser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cloneMessage, lineBreak, message, metavar, text, valueSet } from "./message.js";
|
|
2
2
|
import { isDerivedValueParser } from "./internal/dependency.js";
|
|
3
|
-
import { deduplicateSuggestions } from "./suggestion.js";
|
|
3
|
+
import { appendValueHint, createSuggestionMessage, deduplicateSuggestions } from "./suggestion.js";
|
|
4
4
|
import { ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
|
|
5
5
|
|
|
6
6
|
//#region src/valueparser.ts
|
|
@@ -139,6 +139,13 @@ function choice(choices, options = {}) {
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
const stringInvalidChoice = stringOptions.errors?.invalidChoice;
|
|
142
|
+
const stringSuggest = stringOptions.suggest;
|
|
143
|
+
if (stringSuggest !== void 0) {
|
|
144
|
+
const isValidString = stringSuggest === "nearest" || stringSuggest === "never";
|
|
145
|
+
const isValidObject = typeof stringSuggest === "object" && stringSuggest !== null;
|
|
146
|
+
const isValidFunction = typeof stringSuggest === "function";
|
|
147
|
+
if (!isValidString && !isValidObject && !isValidFunction) throw new TypeError(`Expected suggest to be "nearest", "never", an object, or a function, but got ${typeof stringSuggest}: ${String(stringSuggest)}.`);
|
|
148
|
+
}
|
|
142
149
|
return {
|
|
143
150
|
mode: "sync",
|
|
144
151
|
metavar: metavar$1,
|
|
@@ -149,7 +156,7 @@ function choice(choices, options = {}) {
|
|
|
149
156
|
const index = normalizedValues.indexOf(normalizedInput);
|
|
150
157
|
if (index < 0) return {
|
|
151
158
|
success: false,
|
|
152
|
-
error: formatStringChoiceError(input, stringChoices, stringInvalidChoice)
|
|
159
|
+
error: formatStringChoiceError(input, stringChoices, stringInvalidChoice, stringSuggest)
|
|
153
160
|
};
|
|
154
161
|
return {
|
|
155
162
|
success: true,
|
|
@@ -256,9 +263,22 @@ function normalizeDecimal(s) {
|
|
|
256
263
|
/**
|
|
257
264
|
* Formats error message for string choice parser.
|
|
258
265
|
*/
|
|
259
|
-
function formatStringChoiceError(input, choices, invalidChoice) {
|
|
260
|
-
|
|
261
|
-
|
|
266
|
+
function formatStringChoiceError(input, choices, invalidChoice, suggest) {
|
|
267
|
+
const base = invalidChoice ? typeof invalidChoice === "function" ? invalidChoice(input, choices) : invalidChoice : formatDefaultChoiceError(input, choices);
|
|
268
|
+
if (suggest == null || suggest === "never") return base;
|
|
269
|
+
if (suggest === "nearest") return appendValueHint(base, input, choices);
|
|
270
|
+
if (typeof suggest === "function") {
|
|
271
|
+
const hints = suggest(input, choices);
|
|
272
|
+
if (!hints || hints.length === 0) return base;
|
|
273
|
+
const suggestionMsg = createSuggestionMessage(hints);
|
|
274
|
+
return suggestionMsg.length > 0 ? [
|
|
275
|
+
...base,
|
|
276
|
+
lineBreak(),
|
|
277
|
+
lineBreak(),
|
|
278
|
+
...suggestionMsg
|
|
279
|
+
] : base;
|
|
280
|
+
}
|
|
281
|
+
return appendValueHint(base, input, choices, suggest);
|
|
262
282
|
}
|
|
263
283
|
/**
|
|
264
284
|
* Formats error message for number choice parser.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/core",
|
|
3
|
-
"version": "1.2.0-dev.
|
|
3
|
+
"version": "1.2.0-dev.2242",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -179,6 +179,14 @@
|
|
|
179
179
|
"import": "./dist/program.js",
|
|
180
180
|
"require": "./dist/program.cjs"
|
|
181
181
|
},
|
|
182
|
+
"./suggestion": {
|
|
183
|
+
"types": {
|
|
184
|
+
"import": "./dist/suggestion.d.ts",
|
|
185
|
+
"require": "./dist/suggestion.d.cts"
|
|
186
|
+
},
|
|
187
|
+
"import": "./dist/suggestion.js",
|
|
188
|
+
"require": "./dist/suggestion.cjs"
|
|
189
|
+
},
|
|
182
190
|
"./usage": {
|
|
183
191
|
"types": {
|
|
184
192
|
"import": "./dist/usage.d.ts",
|
|
@@ -208,7 +216,7 @@
|
|
|
208
216
|
"fast-check": "^4.7.0",
|
|
209
217
|
"tsdown": "^0.13.0",
|
|
210
218
|
"typescript": "^5.8.3",
|
|
211
|
-
"@optique/env": "1.2.0-dev.
|
|
219
|
+
"@optique/env": "1.2.0-dev.2242+4f7a5e89"
|
|
212
220
|
},
|
|
213
221
|
"scripts": {
|
|
214
222
|
"build": "tsdown",
|