@optique/core 0.7.0-dev.128 → 0.7.0-dev.130
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 +3 -3
- package/dist/constructs.d.cts +33 -0
- package/dist/constructs.d.ts +33 -0
- package/dist/constructs.js +3 -3
- package/dist/primitives.cjs +27 -1
- package/dist/primitives.d.cts +23 -1
- package/dist/primitives.d.ts +23 -1
- package/dist/primitives.js +28 -2
- package/dist/suggestion.cjs +24 -13
- package/dist/suggestion.js +22 -13
- package/package.json +1 -1
package/dist/constructs.cjs
CHANGED
|
@@ -44,7 +44,7 @@ function or(...args) {
|
|
|
44
44
|
const token = context.buffer[0];
|
|
45
45
|
const defaultMsg = require_message.message`Unexpected option or subcommand: ${require_message.optionName(token)}.`;
|
|
46
46
|
if (options?.errors?.unexpectedInput != null) return typeof options.errors.unexpectedInput === "function" ? options.errors.unexpectedInput(token) : options.errors.unexpectedInput;
|
|
47
|
-
return require_suggestion.createErrorWithSuggestions(defaultMsg, token, context.usage, "both");
|
|
47
|
+
return require_suggestion.createErrorWithSuggestions(defaultMsg, token, context.usage, "both", options?.errors?.suggestions);
|
|
48
48
|
})()
|
|
49
49
|
};
|
|
50
50
|
const orderedParsers = parsers.map((p, i) => [p, i]);
|
|
@@ -180,7 +180,7 @@ function longestMatch(...args) {
|
|
|
180
180
|
const token = context.buffer[0];
|
|
181
181
|
const defaultMsg = require_message.message`Unexpected option or subcommand: ${require_message.optionName(token)}.`;
|
|
182
182
|
if (options?.errors?.unexpectedInput != null) return typeof options.errors.unexpectedInput === "function" ? options.errors.unexpectedInput(token) : options.errors.unexpectedInput;
|
|
183
|
-
return require_suggestion.createErrorWithSuggestions(defaultMsg, token, context.usage, "both");
|
|
183
|
+
return require_suggestion.createErrorWithSuggestions(defaultMsg, token, context.usage, "both", options?.errors?.suggestions);
|
|
184
184
|
})()
|
|
185
185
|
};
|
|
186
186
|
for (let i = 0; i < parsers.length; i++) {
|
|
@@ -304,7 +304,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
304
304
|
const customMessage = options.errors?.unexpectedInput;
|
|
305
305
|
if (customMessage) return typeof customMessage === "function" ? customMessage(token) : customMessage;
|
|
306
306
|
const baseError = require_message.message`Unexpected option or argument: ${token}.`;
|
|
307
|
-
return require_suggestion.createErrorWithSuggestions(baseError, token, context.usage, "both");
|
|
307
|
+
return require_suggestion.createErrorWithSuggestions(baseError, token, context.usage, "both", options.errors?.suggestions);
|
|
308
308
|
})() : options.errors?.endOfInput ?? require_message.message`Expected an option or argument, but got end of input.`
|
|
309
309
|
};
|
|
310
310
|
let currentContext = context;
|
package/dist/constructs.d.cts
CHANGED
|
@@ -27,6 +27,17 @@ interface OrErrorOptions {
|
|
|
27
27
|
* Can be a static message or a function that receives the unexpected token.
|
|
28
28
|
*/
|
|
29
29
|
unexpectedInput?: Message | ((token: string) => Message);
|
|
30
|
+
/**
|
|
31
|
+
* Custom function to format suggestion messages.
|
|
32
|
+
* If provided, this will be used instead of the default "Did you mean?"
|
|
33
|
+
* formatting. The function receives an array of similar valid options/commands
|
|
34
|
+
* and should return a formatted message to append to the error.
|
|
35
|
+
*
|
|
36
|
+
* @param suggestions Array of similar valid option/command names
|
|
37
|
+
* @returns Formatted message to append to the error (can be empty array for no suggestions)
|
|
38
|
+
* @since 0.7.0
|
|
39
|
+
*/
|
|
40
|
+
suggestions?: (suggestions: readonly string[]) => Message;
|
|
30
41
|
}
|
|
31
42
|
/**
|
|
32
43
|
* Creates a parser that combines two mutually exclusive parsers into one.
|
|
@@ -302,6 +313,17 @@ interface LongestMatchErrorOptions {
|
|
|
302
313
|
* Can be a static message or a function that receives the unexpected token.
|
|
303
314
|
*/
|
|
304
315
|
unexpectedInput?: Message | ((token: string) => Message);
|
|
316
|
+
/**
|
|
317
|
+
* Custom function to format suggestion messages.
|
|
318
|
+
* If provided, this will be used instead of the default "Did you mean?"
|
|
319
|
+
* formatting. The function receives an array of similar valid options/commands
|
|
320
|
+
* and should return a formatted message to append to the error.
|
|
321
|
+
*
|
|
322
|
+
* @param suggestions Array of similar valid option/command names
|
|
323
|
+
* @returns Formatted message to append to the error (can be empty array for no suggestions)
|
|
324
|
+
* @since 0.7.0
|
|
325
|
+
*/
|
|
326
|
+
suggestions?: (suggestions: readonly string[]) => Message;
|
|
305
327
|
}
|
|
306
328
|
/**
|
|
307
329
|
* Creates a parser that combines two mutually exclusive parsers into one,
|
|
@@ -427,6 +449,17 @@ interface ObjectErrorOptions {
|
|
|
427
449
|
* Error message when end of input is reached unexpectedly.
|
|
428
450
|
*/
|
|
429
451
|
readonly endOfInput?: Message;
|
|
452
|
+
/**
|
|
453
|
+
* Custom function to format suggestion messages.
|
|
454
|
+
* If provided, this will be used instead of the default "Did you mean?"
|
|
455
|
+
* formatting. The function receives an array of similar valid options/commands
|
|
456
|
+
* and should return a formatted message to append to the error.
|
|
457
|
+
*
|
|
458
|
+
* @param suggestions Array of similar valid option/command names
|
|
459
|
+
* @returns Formatted message to append to the error (can be empty array for no suggestions)
|
|
460
|
+
* @since 0.7.0
|
|
461
|
+
*/
|
|
462
|
+
readonly suggestions?: (suggestions: readonly string[]) => Message;
|
|
430
463
|
}
|
|
431
464
|
/**
|
|
432
465
|
* Creates a parser that combines multiple parsers into a single object parser.
|
package/dist/constructs.d.ts
CHANGED
|
@@ -27,6 +27,17 @@ interface OrErrorOptions {
|
|
|
27
27
|
* Can be a static message or a function that receives the unexpected token.
|
|
28
28
|
*/
|
|
29
29
|
unexpectedInput?: Message | ((token: string) => Message);
|
|
30
|
+
/**
|
|
31
|
+
* Custom function to format suggestion messages.
|
|
32
|
+
* If provided, this will be used instead of the default "Did you mean?"
|
|
33
|
+
* formatting. The function receives an array of similar valid options/commands
|
|
34
|
+
* and should return a formatted message to append to the error.
|
|
35
|
+
*
|
|
36
|
+
* @param suggestions Array of similar valid option/command names
|
|
37
|
+
* @returns Formatted message to append to the error (can be empty array for no suggestions)
|
|
38
|
+
* @since 0.7.0
|
|
39
|
+
*/
|
|
40
|
+
suggestions?: (suggestions: readonly string[]) => Message;
|
|
30
41
|
}
|
|
31
42
|
/**
|
|
32
43
|
* Creates a parser that combines two mutually exclusive parsers into one.
|
|
@@ -302,6 +313,17 @@ interface LongestMatchErrorOptions {
|
|
|
302
313
|
* Can be a static message or a function that receives the unexpected token.
|
|
303
314
|
*/
|
|
304
315
|
unexpectedInput?: Message | ((token: string) => Message);
|
|
316
|
+
/**
|
|
317
|
+
* Custom function to format suggestion messages.
|
|
318
|
+
* If provided, this will be used instead of the default "Did you mean?"
|
|
319
|
+
* formatting. The function receives an array of similar valid options/commands
|
|
320
|
+
* and should return a formatted message to append to the error.
|
|
321
|
+
*
|
|
322
|
+
* @param suggestions Array of similar valid option/command names
|
|
323
|
+
* @returns Formatted message to append to the error (can be empty array for no suggestions)
|
|
324
|
+
* @since 0.7.0
|
|
325
|
+
*/
|
|
326
|
+
suggestions?: (suggestions: readonly string[]) => Message;
|
|
305
327
|
}
|
|
306
328
|
/**
|
|
307
329
|
* Creates a parser that combines two mutually exclusive parsers into one,
|
|
@@ -427,6 +449,17 @@ interface ObjectErrorOptions {
|
|
|
427
449
|
* Error message when end of input is reached unexpectedly.
|
|
428
450
|
*/
|
|
429
451
|
readonly endOfInput?: Message;
|
|
452
|
+
/**
|
|
453
|
+
* Custom function to format suggestion messages.
|
|
454
|
+
* If provided, this will be used instead of the default "Did you mean?"
|
|
455
|
+
* formatting. The function receives an array of similar valid options/commands
|
|
456
|
+
* and should return a formatted message to append to the error.
|
|
457
|
+
*
|
|
458
|
+
* @param suggestions Array of similar valid option/command names
|
|
459
|
+
* @returns Formatted message to append to the error (can be empty array for no suggestions)
|
|
460
|
+
* @since 0.7.0
|
|
461
|
+
*/
|
|
462
|
+
readonly suggestions?: (suggestions: readonly string[]) => Message;
|
|
430
463
|
}
|
|
431
464
|
/**
|
|
432
465
|
* Creates a parser that combines multiple parsers into a single object parser.
|
package/dist/constructs.js
CHANGED
|
@@ -44,7 +44,7 @@ function or(...args) {
|
|
|
44
44
|
const token = context.buffer[0];
|
|
45
45
|
const defaultMsg = message`Unexpected option or subcommand: ${optionName(token)}.`;
|
|
46
46
|
if (options?.errors?.unexpectedInput != null) return typeof options.errors.unexpectedInput === "function" ? options.errors.unexpectedInput(token) : options.errors.unexpectedInput;
|
|
47
|
-
return createErrorWithSuggestions(defaultMsg, token, context.usage, "both");
|
|
47
|
+
return createErrorWithSuggestions(defaultMsg, token, context.usage, "both", options?.errors?.suggestions);
|
|
48
48
|
})()
|
|
49
49
|
};
|
|
50
50
|
const orderedParsers = parsers.map((p, i) => [p, i]);
|
|
@@ -180,7 +180,7 @@ function longestMatch(...args) {
|
|
|
180
180
|
const token = context.buffer[0];
|
|
181
181
|
const defaultMsg = message`Unexpected option or subcommand: ${optionName(token)}.`;
|
|
182
182
|
if (options?.errors?.unexpectedInput != null) return typeof options.errors.unexpectedInput === "function" ? options.errors.unexpectedInput(token) : options.errors.unexpectedInput;
|
|
183
|
-
return createErrorWithSuggestions(defaultMsg, token, context.usage, "both");
|
|
183
|
+
return createErrorWithSuggestions(defaultMsg, token, context.usage, "both", options?.errors?.suggestions);
|
|
184
184
|
})()
|
|
185
185
|
};
|
|
186
186
|
for (let i = 0; i < parsers.length; i++) {
|
|
@@ -304,7 +304,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
304
304
|
const customMessage = options.errors?.unexpectedInput;
|
|
305
305
|
if (customMessage) return typeof customMessage === "function" ? customMessage(token) : customMessage;
|
|
306
306
|
const baseError = message`Unexpected option or argument: ${token}.`;
|
|
307
|
-
return createErrorWithSuggestions(baseError, token, context.usage, "both");
|
|
307
|
+
return createErrorWithSuggestions(baseError, token, context.usage, "both", options.errors?.suggestions);
|
|
308
308
|
})() : options.errors?.endOfInput ?? message`Expected an option or argument, but got end of input.`
|
|
309
309
|
};
|
|
310
310
|
let currentContext = context;
|
package/dist/primitives.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_message = require('./message.cjs');
|
|
2
|
+
const require_usage = require('./usage.cjs');
|
|
2
3
|
const require_suggestion = require('./suggestion.cjs');
|
|
3
4
|
const require_valueparser = require('./valueparser.cjs');
|
|
4
5
|
|
|
@@ -184,6 +185,17 @@ function option(...args) {
|
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
const invalidOption = context.buffer[0];
|
|
188
|
+
if (options.errors?.noMatch) {
|
|
189
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
190
|
+
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
191
|
+
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
192
|
+
const errorMessage = typeof options.errors.noMatch === "function" ? options.errors.noMatch(invalidOption, suggestions) : options.errors.noMatch;
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
consumed: 0,
|
|
196
|
+
error: errorMessage
|
|
197
|
+
};
|
|
198
|
+
}
|
|
187
199
|
const baseError = require_message.message`No matched option for ${require_message.optionName(invalidOption)}.`;
|
|
188
200
|
return {
|
|
189
201
|
success: false,
|
|
@@ -390,6 +402,17 @@ function flag(...args) {
|
|
|
390
402
|
};
|
|
391
403
|
}
|
|
392
404
|
const invalidOption = context.buffer[0];
|
|
405
|
+
if (options.errors?.noMatch) {
|
|
406
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
407
|
+
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
408
|
+
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
409
|
+
const errorMessage = typeof options.errors.noMatch === "function" ? options.errors.noMatch(invalidOption, suggestions) : options.errors.noMatch;
|
|
410
|
+
return {
|
|
411
|
+
success: false,
|
|
412
|
+
consumed: 0,
|
|
413
|
+
error: errorMessage
|
|
414
|
+
};
|
|
415
|
+
}
|
|
393
416
|
const baseError = require_message.message`No matched option for ${require_message.optionName(invalidOption)}.`;
|
|
394
417
|
return {
|
|
395
418
|
success: false,
|
|
@@ -572,10 +595,13 @@ function command(name, parser, options = {}) {
|
|
|
572
595
|
const actual = context.buffer.length > 0 ? context.buffer[0] : null;
|
|
573
596
|
if (options.errors?.notMatched) {
|
|
574
597
|
const errorMessage = options.errors.notMatched;
|
|
598
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
599
|
+
for (const cmdName of require_usage.extractCommandNames(context.usage)) candidates.add(cmdName);
|
|
600
|
+
const suggestions = actual ? require_suggestion.findSimilar(actual, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS) : [];
|
|
575
601
|
return {
|
|
576
602
|
success: false,
|
|
577
603
|
consumed: 0,
|
|
578
|
-
error: typeof errorMessage === "function" ? errorMessage(name, actual) : errorMessage
|
|
604
|
+
error: typeof errorMessage === "function" ? errorMessage(name, actual, suggestions) : errorMessage
|
|
579
605
|
};
|
|
580
606
|
}
|
|
581
607
|
if (actual == null) return {
|
package/dist/primitives.d.cts
CHANGED
|
@@ -58,6 +58,15 @@ interface OptionErrorOptions {
|
|
|
58
58
|
* Can be a static message or a function that receives the value.
|
|
59
59
|
*/
|
|
60
60
|
unexpectedValue?: Message | ((value: string) => Message);
|
|
61
|
+
/**
|
|
62
|
+
* Custom error message when no matching option is found.
|
|
63
|
+
* Can be a static message or a function that receives:
|
|
64
|
+
* - invalidOption: The invalid option name that was provided
|
|
65
|
+
* - suggestions: Array of similar valid option names (can be empty)
|
|
66
|
+
*
|
|
67
|
+
* @since 0.7.0
|
|
68
|
+
*/
|
|
69
|
+
noMatch?: Message | ((invalidOption: string, suggestions: readonly string[]) => Message);
|
|
61
70
|
}
|
|
62
71
|
/**
|
|
63
72
|
* Creates a parser for various styles of command-line options that take an
|
|
@@ -138,6 +147,15 @@ interface FlagErrorOptions {
|
|
|
138
147
|
* Can be a static message or a function that receives the token.
|
|
139
148
|
*/
|
|
140
149
|
duplicate?: Message | ((token: string) => Message);
|
|
150
|
+
/**
|
|
151
|
+
* Custom error message when no matching flag is found.
|
|
152
|
+
* Can be a static message or a function that receives:
|
|
153
|
+
* - invalidOption: The invalid option name that was provided
|
|
154
|
+
* - suggestions: Array of similar valid option names (can be empty)
|
|
155
|
+
*
|
|
156
|
+
* @since 0.7.0
|
|
157
|
+
*/
|
|
158
|
+
noMatch?: Message | ((invalidOption: string, suggestions: readonly string[]) => Message);
|
|
141
159
|
}
|
|
142
160
|
/**
|
|
143
161
|
* Creates a parser for command-line flags that must be explicitly provided.
|
|
@@ -255,8 +273,12 @@ interface CommandOptions {
|
|
|
255
273
|
interface CommandErrorOptions {
|
|
256
274
|
/**
|
|
257
275
|
* Error message when command is expected but not found.
|
|
276
|
+
* Since version 0.7.0, the function signature now includes suggestions:
|
|
277
|
+
* - expected: The expected command name
|
|
278
|
+
* - actual: The actual input (or null if no input)
|
|
279
|
+
* - suggestions: Array of similar valid command names (can be empty)
|
|
258
280
|
*/
|
|
259
|
-
readonly notMatched?: Message | ((expected: string, actual: string | null) => Message);
|
|
281
|
+
readonly notMatched?: Message | ((expected: string, actual: string | null, suggestions?: readonly string[]) => Message);
|
|
260
282
|
/**
|
|
261
283
|
* Error message when command was not matched during completion.
|
|
262
284
|
*/
|
package/dist/primitives.d.ts
CHANGED
|
@@ -58,6 +58,15 @@ interface OptionErrorOptions {
|
|
|
58
58
|
* Can be a static message or a function that receives the value.
|
|
59
59
|
*/
|
|
60
60
|
unexpectedValue?: Message | ((value: string) => Message);
|
|
61
|
+
/**
|
|
62
|
+
* Custom error message when no matching option is found.
|
|
63
|
+
* Can be a static message or a function that receives:
|
|
64
|
+
* - invalidOption: The invalid option name that was provided
|
|
65
|
+
* - suggestions: Array of similar valid option names (can be empty)
|
|
66
|
+
*
|
|
67
|
+
* @since 0.7.0
|
|
68
|
+
*/
|
|
69
|
+
noMatch?: Message | ((invalidOption: string, suggestions: readonly string[]) => Message);
|
|
61
70
|
}
|
|
62
71
|
/**
|
|
63
72
|
* Creates a parser for various styles of command-line options that take an
|
|
@@ -138,6 +147,15 @@ interface FlagErrorOptions {
|
|
|
138
147
|
* Can be a static message or a function that receives the token.
|
|
139
148
|
*/
|
|
140
149
|
duplicate?: Message | ((token: string) => Message);
|
|
150
|
+
/**
|
|
151
|
+
* Custom error message when no matching flag is found.
|
|
152
|
+
* Can be a static message or a function that receives:
|
|
153
|
+
* - invalidOption: The invalid option name that was provided
|
|
154
|
+
* - suggestions: Array of similar valid option names (can be empty)
|
|
155
|
+
*
|
|
156
|
+
* @since 0.7.0
|
|
157
|
+
*/
|
|
158
|
+
noMatch?: Message | ((invalidOption: string, suggestions: readonly string[]) => Message);
|
|
141
159
|
}
|
|
142
160
|
/**
|
|
143
161
|
* Creates a parser for command-line flags that must be explicitly provided.
|
|
@@ -255,8 +273,12 @@ interface CommandOptions {
|
|
|
255
273
|
interface CommandErrorOptions {
|
|
256
274
|
/**
|
|
257
275
|
* Error message when command is expected but not found.
|
|
276
|
+
* Since version 0.7.0, the function signature now includes suggestions:
|
|
277
|
+
* - expected: The expected command name
|
|
278
|
+
* - actual: The actual input (or null if no input)
|
|
279
|
+
* - suggestions: Array of similar valid command names (can be empty)
|
|
258
280
|
*/
|
|
259
|
-
readonly notMatched?: Message | ((expected: string, actual: string | null) => Message);
|
|
281
|
+
readonly notMatched?: Message | ((expected: string, actual: string | null, suggestions?: readonly string[]) => Message);
|
|
260
282
|
/**
|
|
261
283
|
* Error message when command was not matched during completion.
|
|
262
284
|
*/
|
package/dist/primitives.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { message, metavar, optionName, optionNames } from "./message.js";
|
|
2
|
-
import {
|
|
2
|
+
import { extractCommandNames, extractOptionNames } from "./usage.js";
|
|
3
|
+
import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, findSimilar } from "./suggestion.js";
|
|
3
4
|
import { isValueParser } from "./valueparser.js";
|
|
4
5
|
|
|
5
6
|
//#region src/primitives.ts
|
|
@@ -184,6 +185,17 @@ function option(...args) {
|
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
const invalidOption = context.buffer[0];
|
|
188
|
+
if (options.errors?.noMatch) {
|
|
189
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
190
|
+
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
191
|
+
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
192
|
+
const errorMessage = typeof options.errors.noMatch === "function" ? options.errors.noMatch(invalidOption, suggestions) : options.errors.noMatch;
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
consumed: 0,
|
|
196
|
+
error: errorMessage
|
|
197
|
+
};
|
|
198
|
+
}
|
|
187
199
|
const baseError = message`No matched option for ${optionName(invalidOption)}.`;
|
|
188
200
|
return {
|
|
189
201
|
success: false,
|
|
@@ -390,6 +402,17 @@ function flag(...args) {
|
|
|
390
402
|
};
|
|
391
403
|
}
|
|
392
404
|
const invalidOption = context.buffer[0];
|
|
405
|
+
if (options.errors?.noMatch) {
|
|
406
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
407
|
+
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
408
|
+
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
409
|
+
const errorMessage = typeof options.errors.noMatch === "function" ? options.errors.noMatch(invalidOption, suggestions) : options.errors.noMatch;
|
|
410
|
+
return {
|
|
411
|
+
success: false,
|
|
412
|
+
consumed: 0,
|
|
413
|
+
error: errorMessage
|
|
414
|
+
};
|
|
415
|
+
}
|
|
393
416
|
const baseError = message`No matched option for ${optionName(invalidOption)}.`;
|
|
394
417
|
return {
|
|
395
418
|
success: false,
|
|
@@ -572,10 +595,13 @@ function command(name, parser, options = {}) {
|
|
|
572
595
|
const actual = context.buffer.length > 0 ? context.buffer[0] : null;
|
|
573
596
|
if (options.errors?.notMatched) {
|
|
574
597
|
const errorMessage = options.errors.notMatched;
|
|
598
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
599
|
+
for (const cmdName of extractCommandNames(context.usage)) candidates.add(cmdName);
|
|
600
|
+
const suggestions = actual ? findSimilar(actual, candidates, DEFAULT_FIND_SIMILAR_OPTIONS) : [];
|
|
575
601
|
return {
|
|
576
602
|
success: false,
|
|
577
603
|
consumed: 0,
|
|
578
|
-
error: typeof errorMessage === "function" ? errorMessage(name, actual) : errorMessage
|
|
604
|
+
error: typeof errorMessage === "function" ? errorMessage(name, actual, suggestions) : errorMessage
|
|
579
605
|
};
|
|
580
606
|
}
|
|
581
607
|
if (actual == null) return {
|
package/dist/suggestion.cjs
CHANGED
|
@@ -38,6 +38,18 @@ function levenshteinDistance(source, target) {
|
|
|
38
38
|
return previousRow[source.length];
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
|
+
* Default options for finding similar strings.
|
|
42
|
+
* These values are optimized for command-line option/command name suggestions.
|
|
43
|
+
*
|
|
44
|
+
* @since 0.7.0
|
|
45
|
+
*/
|
|
46
|
+
const DEFAULT_FIND_SIMILAR_OPTIONS = {
|
|
47
|
+
maxDistance: 3,
|
|
48
|
+
maxDistanceRatio: .5,
|
|
49
|
+
maxSuggestions: 3,
|
|
50
|
+
caseSensitive: false
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
41
53
|
* Finds similar strings from a list of candidates.
|
|
42
54
|
*
|
|
43
55
|
* This function uses Levenshtein distance to find strings that are similar
|
|
@@ -62,10 +74,10 @@ function levenshteinDistance(source, target) {
|
|
|
62
74
|
* ```
|
|
63
75
|
*/
|
|
64
76
|
function findSimilar(input, candidates, options = {}) {
|
|
65
|
-
const maxDistance = options.maxDistance ??
|
|
66
|
-
const maxDistanceRatio = options.maxDistanceRatio ?? .
|
|
67
|
-
const maxSuggestions = options.maxSuggestions ??
|
|
68
|
-
const caseSensitive = options.caseSensitive ??
|
|
77
|
+
const maxDistance = options.maxDistance ?? DEFAULT_FIND_SIMILAR_OPTIONS.maxDistance;
|
|
78
|
+
const maxDistanceRatio = options.maxDistanceRatio ?? DEFAULT_FIND_SIMILAR_OPTIONS.maxDistanceRatio;
|
|
79
|
+
const maxSuggestions = options.maxSuggestions ?? DEFAULT_FIND_SIMILAR_OPTIONS.maxSuggestions;
|
|
80
|
+
const caseSensitive = options.caseSensitive ?? DEFAULT_FIND_SIMILAR_OPTIONS.caseSensitive;
|
|
69
81
|
if (input.length === 0) return [];
|
|
70
82
|
const normalizedInput = caseSensitive ? input : input.toLowerCase();
|
|
71
83
|
const matches = [];
|
|
@@ -136,6 +148,8 @@ function createSuggestionMessage(suggestions) {
|
|
|
136
148
|
* @param invalidInput The invalid option or command name that the user typed
|
|
137
149
|
* @param usage The usage information to extract available options/commands from
|
|
138
150
|
* @param type What type of names to suggest ("option", "command", or "both")
|
|
151
|
+
* @param customFormatter Optional custom function to format suggestions instead
|
|
152
|
+
* of using the default "Did you mean?" formatting
|
|
139
153
|
* @returns A message combining the base error with suggestions, or just the
|
|
140
154
|
* base error if no similar names are found
|
|
141
155
|
*
|
|
@@ -153,17 +167,12 @@ function createSuggestionMessage(suggestions) {
|
|
|
153
167
|
*
|
|
154
168
|
* @since 0.7.0
|
|
155
169
|
*/
|
|
156
|
-
function createErrorWithSuggestions(baseError, invalidInput, usage, type = "both") {
|
|
170
|
+
function createErrorWithSuggestions(baseError, invalidInput, usage, type = "both", customFormatter) {
|
|
157
171
|
const candidates = /* @__PURE__ */ new Set();
|
|
158
172
|
if (type === "option" || type === "both") for (const name of require_usage.extractOptionNames(usage)) candidates.add(name);
|
|
159
173
|
if (type === "command" || type === "both") for (const name of require_usage.extractCommandNames(usage)) candidates.add(name);
|
|
160
|
-
const suggestions = findSimilar(invalidInput, candidates,
|
|
161
|
-
|
|
162
|
-
maxDistanceRatio: .5,
|
|
163
|
-
maxSuggestions: 3,
|
|
164
|
-
caseSensitive: false
|
|
165
|
-
});
|
|
166
|
-
const suggestionMsg = createSuggestionMessage(suggestions);
|
|
174
|
+
const suggestions = findSimilar(invalidInput, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
175
|
+
const suggestionMsg = customFormatter ? customFormatter(suggestions) : createSuggestionMessage(suggestions);
|
|
167
176
|
return suggestionMsg.length > 0 ? [
|
|
168
177
|
...baseError,
|
|
169
178
|
require_message.text("\n\n"),
|
|
@@ -172,4 +181,6 @@ function createErrorWithSuggestions(baseError, invalidInput, usage, type = "both
|
|
|
172
181
|
}
|
|
173
182
|
|
|
174
183
|
//#endregion
|
|
175
|
-
exports.
|
|
184
|
+
exports.DEFAULT_FIND_SIMILAR_OPTIONS = DEFAULT_FIND_SIMILAR_OPTIONS;
|
|
185
|
+
exports.createErrorWithSuggestions = createErrorWithSuggestions;
|
|
186
|
+
exports.findSimilar = findSimilar;
|
package/dist/suggestion.js
CHANGED
|
@@ -38,6 +38,18 @@ function levenshteinDistance(source, target) {
|
|
|
38
38
|
return previousRow[source.length];
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
|
+
* Default options for finding similar strings.
|
|
42
|
+
* These values are optimized for command-line option/command name suggestions.
|
|
43
|
+
*
|
|
44
|
+
* @since 0.7.0
|
|
45
|
+
*/
|
|
46
|
+
const DEFAULT_FIND_SIMILAR_OPTIONS = {
|
|
47
|
+
maxDistance: 3,
|
|
48
|
+
maxDistanceRatio: .5,
|
|
49
|
+
maxSuggestions: 3,
|
|
50
|
+
caseSensitive: false
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
41
53
|
* Finds similar strings from a list of candidates.
|
|
42
54
|
*
|
|
43
55
|
* This function uses Levenshtein distance to find strings that are similar
|
|
@@ -62,10 +74,10 @@ function levenshteinDistance(source, target) {
|
|
|
62
74
|
* ```
|
|
63
75
|
*/
|
|
64
76
|
function findSimilar(input, candidates, options = {}) {
|
|
65
|
-
const maxDistance = options.maxDistance ??
|
|
66
|
-
const maxDistanceRatio = options.maxDistanceRatio ?? .
|
|
67
|
-
const maxSuggestions = options.maxSuggestions ??
|
|
68
|
-
const caseSensitive = options.caseSensitive ??
|
|
77
|
+
const maxDistance = options.maxDistance ?? DEFAULT_FIND_SIMILAR_OPTIONS.maxDistance;
|
|
78
|
+
const maxDistanceRatio = options.maxDistanceRatio ?? DEFAULT_FIND_SIMILAR_OPTIONS.maxDistanceRatio;
|
|
79
|
+
const maxSuggestions = options.maxSuggestions ?? DEFAULT_FIND_SIMILAR_OPTIONS.maxSuggestions;
|
|
80
|
+
const caseSensitive = options.caseSensitive ?? DEFAULT_FIND_SIMILAR_OPTIONS.caseSensitive;
|
|
69
81
|
if (input.length === 0) return [];
|
|
70
82
|
const normalizedInput = caseSensitive ? input : input.toLowerCase();
|
|
71
83
|
const matches = [];
|
|
@@ -136,6 +148,8 @@ function createSuggestionMessage(suggestions) {
|
|
|
136
148
|
* @param invalidInput The invalid option or command name that the user typed
|
|
137
149
|
* @param usage The usage information to extract available options/commands from
|
|
138
150
|
* @param type What type of names to suggest ("option", "command", or "both")
|
|
151
|
+
* @param customFormatter Optional custom function to format suggestions instead
|
|
152
|
+
* of using the default "Did you mean?" formatting
|
|
139
153
|
* @returns A message combining the base error with suggestions, or just the
|
|
140
154
|
* base error if no similar names are found
|
|
141
155
|
*
|
|
@@ -153,17 +167,12 @@ function createSuggestionMessage(suggestions) {
|
|
|
153
167
|
*
|
|
154
168
|
* @since 0.7.0
|
|
155
169
|
*/
|
|
156
|
-
function createErrorWithSuggestions(baseError, invalidInput, usage, type = "both") {
|
|
170
|
+
function createErrorWithSuggestions(baseError, invalidInput, usage, type = "both", customFormatter) {
|
|
157
171
|
const candidates = /* @__PURE__ */ new Set();
|
|
158
172
|
if (type === "option" || type === "both") for (const name of extractOptionNames(usage)) candidates.add(name);
|
|
159
173
|
if (type === "command" || type === "both") for (const name of extractCommandNames(usage)) candidates.add(name);
|
|
160
|
-
const suggestions = findSimilar(invalidInput, candidates,
|
|
161
|
-
|
|
162
|
-
maxDistanceRatio: .5,
|
|
163
|
-
maxSuggestions: 3,
|
|
164
|
-
caseSensitive: false
|
|
165
|
-
});
|
|
166
|
-
const suggestionMsg = createSuggestionMessage(suggestions);
|
|
174
|
+
const suggestions = findSimilar(invalidInput, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
175
|
+
const suggestionMsg = customFormatter ? customFormatter(suggestions) : createSuggestionMessage(suggestions);
|
|
167
176
|
return suggestionMsg.length > 0 ? [
|
|
168
177
|
...baseError,
|
|
169
178
|
text("\n\n"),
|
|
@@ -172,4 +181,4 @@ function createErrorWithSuggestions(baseError, invalidInput, usage, type = "both
|
|
|
172
181
|
}
|
|
173
182
|
|
|
174
183
|
//#endregion
|
|
175
|
-
export { createErrorWithSuggestions };
|
|
184
|
+
export { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, findSimilar };
|