From 47c8a006d46a5e327c2a03081c07c3e2ba824f8f Mon Sep 17 00:00:00 2001 From: "E. Cooper" Date: Tue, 10 Dec 2024 16:33:35 -0800 Subject: [PATCH] Handle all yargs validation errors in isYargsError --- src/lib/command-helpers.mjs | 153 ++++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 68 deletions(-) diff --git a/src/lib/command-helpers.mjs b/src/lib/command-helpers.mjs index 82797df6..66d538c4 100644 --- a/src/lib/command-helpers.mjs +++ b/src/lib/command-helpers.mjs @@ -3,6 +3,26 @@ import { container } from "../cli.mjs"; import { Format } from "./formatting/colorize.mjs"; +/* + * These are the error message prefixes that yargs throws during + * validation. To detect these errors, you can either parse the stack + * or the message. We've decided to parse the messages. + * + * Compiled from https://github.com/yargs/yargs/blob/main/lib/validation.ts + */ +const YARGS_STATIC_PREFIXES = [ + "Unknown argument:", + "Unknown arguments:", + "Missing required argument:", + "Missing required arguments:", + "Unknown command:", + "Unknown commands:", + "Invalid values:", + "Not enough non-option arguments:", + "Too many non-option arguments:", + "Implications failed:", +]; + const COMMON_OPTIONS = { // hidden accountUrl: { @@ -78,6 +98,69 @@ const COMMON_QUERY_OPTIONS = { }, }; +// used for queries customers can configure +const COMMON_CONFIGURABLE_QUERY_OPTIONS = { + ...COMMON_QUERY_OPTIONS, + apiVersion: { + description: "FQL version to use.", + type: "string", + alias: "v", + default: "10", + choices: ["4", "10"], + group: "API:", + }, + // v10 specific options + format: { + type: "string", + alias: "f", + description: + "Output format for the query. When present, --json takes precedence over --format. Only applies to v10 queries.", + choices: [Format.FQL, Format.JSON], + default: Format.FQL, + group: "API:", + }, + typecheck: { + type: "boolean", + description: + "Enable typechecking. Defaults to the typechecking setting of the database.", + default: undefined, + group: "API:", + }, + timeout: { + type: "number", + description: + "Maximum runtime, in milliseconds, for Fauna Core HTTP API requests made by the command.", + default: 5000, + group: "API:", + }, + summary: { + type: "boolean", + description: + "Output the summary field of the API response. Only applies to v10 queries.", + default: false, + group: "API:", + }, + performanceHints: { + type: "boolean", + description: + "Output the performance hints for the current query. Only applies to v10 queries.", + default: false, + group: "API:", + }, +}; + +export function yargsWithCommonQueryOptions(yargs) { + return yargsWithCommonOptions(yargs, COMMON_QUERY_OPTIONS); +} + +export function yargsWithCommonConfigurableQueryOptions(yargs) { + return yargsWithCommonOptions(yargs, COMMON_CONFIGURABLE_QUERY_OPTIONS); +} + +export function yargsWithCommonOptions(yargs, options) { + return yargs.options({ ...options, ...COMMON_OPTIONS }); +} + /** * An error that is thrown by commands that is not a validation error, but * a known error state that should be communicated to the user. @@ -126,13 +209,10 @@ function isYargsError(error) { return true; } - // Usage errors from yargs are thrown as plain old Error. The best - // you can do is check for the message. + // Does the message look if ( error.message && - (error.message.startsWith("Unknown argument") || - error.message.startsWith("Missing required argument") || - error.message.startsWith("Unknown command")) + YARGS_STATIC_PREFIXES.some((prefix) => error.message.startsWith(prefix)) ) { return true; } @@ -189,66 +269,3 @@ export const validateDatabaseOrSecret = (argv) => { } return true; }; - -// used for queries customers can configure -const COMMON_CONFIGURABLE_QUERY_OPTIONS = { - ...COMMON_QUERY_OPTIONS, - apiVersion: { - description: "FQL version to use.", - type: "string", - alias: "v", - default: "10", - choices: ["4", "10"], - group: "API:", - }, - // v10 specific options - format: { - type: "string", - alias: "f", - description: - "Output format for the query. When present, --json takes precedence over --format. Only applies to v10 queries.", - choices: [Format.FQL, Format.JSON], - default: Format.FQL, - group: "API:", - }, - typecheck: { - type: "boolean", - description: - "Enable typechecking. Defaults to the typechecking setting of the database.", - default: undefined, - group: "API:", - }, - timeout: { - type: "number", - description: - "Maximum runtime, in milliseconds, for Fauna Core HTTP API requests made by the command.", - default: 5000, - group: "API:", - }, - summary: { - type: "boolean", - description: - "Output the summary field of the API response. Only applies to v10 queries.", - default: false, - group: "API:", - }, - performanceHints: { - type: "boolean", - description: - "Output the performance hints for the current query. Only applies to v10 queries.", - default: false, - group: "API:", - }, -}; - -export function yargsWithCommonQueryOptions(yargs) { - return yargsWithCommonOptions(yargs, COMMON_QUERY_OPTIONS); -} - -export function yargsWithCommonConfigurableQueryOptions(yargs) { - return yargsWithCommonOptions(yargs, COMMON_CONFIGURABLE_QUERY_OPTIONS); -} - -export function yargsWithCommonOptions(yargs, options) { - return yargs.options({ ...options, ...COMMON_OPTIONS }); -}