From 57641e122d69b5140ac23320f9aa5e25649b68d2 Mon Sep 17 00:00:00 2001 From: "E. Cooper" Date: Mon, 6 Jan 2025 15:06:57 -0800 Subject: [PATCH] Remove function indirection for common options (#552) --- src/commands/database/create.mjs | 2 +- src/commands/database/database.mjs | 11 +- src/commands/database/delete.mjs | 2 +- src/commands/login.mjs | 43 ++++-- src/commands/query.mjs | 24 ++- src/commands/schema/abandon.mjs | 3 +- src/commands/schema/commit.mjs | 3 +- src/commands/schema/diff.mjs | 7 +- src/commands/schema/pull.mjs | 7 +- src/commands/schema/push.mjs | 7 +- src/commands/schema/schema.mjs | 12 +- src/commands/schema/status.mjs | 25 ++-- src/commands/shell.mjs | 21 ++- src/lib/formatting/codeToAnsi.mjs | 2 +- src/lib/middleware.mjs | 55 ++++++- src/lib/misc.mjs | 3 - src/lib/{command-helpers.mjs => options.mjs} | 148 +++++-------------- src/lib/utils.mjs | 20 +++ test/query.mjs | 2 +- 19 files changed, 219 insertions(+), 178 deletions(-) delete mode 100644 src/lib/misc.mjs rename src/lib/{command-helpers.mjs => options.mjs} (51%) create mode 100644 src/lib/utils.mjs diff --git a/src/commands/database/create.mjs b/src/commands/database/create.mjs index 49905f78..5bf5ed05 100644 --- a/src/commands/database/create.mjs +++ b/src/commands/database/create.mjs @@ -2,11 +2,11 @@ import { ServiceError } from "fauna"; import { container } from "../../cli.mjs"; -import { validateDatabaseOrSecret } from "../../lib/command-helpers.mjs"; import { CommandError } from "../../lib/errors.mjs"; import { faunaToCommandError } from "../../lib/fauna.mjs"; import { getSecret, retryInvalidCredsOnce } from "../../lib/fauna-client.mjs"; import { colorize, Format } from "../../lib/formatting/colorize.mjs"; +import { validateDatabaseOrSecret } from "../../lib/middleware.mjs"; async function runCreateQuery(secret, argv) { const { fql } = container.resolve("fauna"); diff --git a/src/commands/database/database.mjs b/src/commands/database/database.mjs index 21bb1cbc..6425c48a 100644 --- a/src/commands/database/database.mjs +++ b/src/commands/database/database.mjs @@ -1,12 +1,19 @@ //@ts-check -import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs"; +import { + ACCOUNT_OPTIONS, + CORE_OPTIONS, + DATABASE_PATH_OPTIONS, +} from "../../lib/options.mjs"; import createCommand from "./create.mjs"; import deleteCommand from "./delete.mjs"; import listCommand from "./list.mjs"; function buildDatabase(yargs) { - return yargsWithCommonQueryOptions(yargs) + return yargs + .options(ACCOUNT_OPTIONS) + .options(CORE_OPTIONS) + .options(DATABASE_PATH_OPTIONS) .command(listCommand) .command(createCommand) .command(deleteCommand) diff --git a/src/commands/database/delete.mjs b/src/commands/database/delete.mjs index ce255770..4b491bef 100644 --- a/src/commands/database/delete.mjs +++ b/src/commands/database/delete.mjs @@ -3,10 +3,10 @@ import { ServiceError } from "fauna"; import { container } from "../../cli.mjs"; -import { validateDatabaseOrSecret } from "../../lib/command-helpers.mjs"; import { CommandError } from "../../lib/errors.mjs"; import { faunaToCommandError } from "../../lib/fauna.mjs"; import { getSecret, retryInvalidCredsOnce } from "../../lib/fauna-client.mjs"; +import { validateDatabaseOrSecret } from "../../lib/middleware.mjs"; async function runDeleteQuery(secret, argv) { const { fql } = container.resolve("fauna"); diff --git a/src/commands/login.mjs b/src/commands/login.mjs index df416022..0d89b60c 100644 --- a/src/commands/login.mjs +++ b/src/commands/login.mjs @@ -1,7 +1,6 @@ //@ts-check import { container } from "../cli.mjs"; -import { yargsWithCommonOptions } from "../lib/command-helpers.mjs"; import { FaunaAccountClient } from "../lib/fauna-account-client.mjs"; async function doLogin(argv) { @@ -38,17 +37,37 @@ async function doLogin(argv) { * @returns */ function buildLoginCommand(yargs) { - return yargsWithCommonOptions(yargs, { - user: { - alias: "u", - type: "string", - description: "User to log in as.", - default: "default", - }, - }).example([ - ["$0 login", "Log in as the 'default' user."], - ["$0 login --user john_doe", "Log in as the 'john_doe' user."], - ]); + return yargs + .options({ + "account-url": { + type: "string", + description: "The Fauna account URL to query", + default: "https://account.fauna.com", + hidden: true, + }, + "client-id": { + type: "string", + description: "the client id to use when calling Fauna", + required: false, + hidden: true, + }, + "client-secret": { + type: "string", + description: "the client secret to use when calling Fauna", + required: false, + hidden: true, + }, + user: { + alias: "u", + type: "string", + description: "User to log in as.", + default: "default", + }, + }) + .example([ + ["$0 login", "Log in as the 'default' user."], + ["$0 login --user john_doe", "Log in as the 'john_doe' user."], + ]); } export default { diff --git a/src/commands/query.mjs b/src/commands/query.mjs index 520b4166..cde0fd56 100644 --- a/src/commands/query.mjs +++ b/src/commands/query.mjs @@ -1,11 +1,6 @@ //@ts-check import { container } from "../cli.mjs"; -import { - resolveFormat, - validateDatabaseOrSecret, - yargsWithCommonConfigurableQueryOptions, -} from "../lib/command-helpers.mjs"; import { CommandError, isUnknownError, @@ -16,7 +11,17 @@ import { formatQueryResponse, getSecret, } from "../lib/fauna-client.mjs"; -import { isTTY } from "../lib/misc.mjs"; +import { + resolveIncludeOptions, + validateDatabaseOrSecret, +} from "../lib/middleware.mjs"; +import { + ACCOUNT_OPTIONS, + CORE_OPTIONS, + DATABASE_PATH_OPTIONS, + QUERY_OPTIONS, +} from "../lib/options.mjs"; +import { isTTY, resolveFormat } from "../lib/utils.mjs"; function validate(argv) { const { existsSync, accessSync, constants } = container.resolve("fs"); @@ -149,7 +154,12 @@ async function queryCommand(argv) { } function buildQueryCommand(yargs) { - return yargsWithCommonConfigurableQueryOptions(yargs) + return yargs + .options(ACCOUNT_OPTIONS) + .options(DATABASE_PATH_OPTIONS) + .options(CORE_OPTIONS) + .options(QUERY_OPTIONS) + .middleware(resolveIncludeOptions) .positional("fql", { type: "string", description: "FQL query to run. Use - to read from stdin.", diff --git a/src/commands/schema/abandon.mjs b/src/commands/schema/abandon.mjs index 8cb1a30b..5ded505c 100644 --- a/src/commands/schema/abandon.mjs +++ b/src/commands/schema/abandon.mjs @@ -1,7 +1,6 @@ //@ts-check import { container } from "../../cli.mjs"; -import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs"; import { CommandError } from "../../lib/errors.mjs"; import { getSecret } from "../../lib/fauna-client.mjs"; @@ -65,7 +64,7 @@ async function doAbandon(argv) { } function buildAbandonCommand(yargs) { - return yargsWithCommonQueryOptions(yargs) + return yargs .options({ input: { description: "Prompt for input. Use --no-input to disable.", diff --git a/src/commands/schema/commit.mjs b/src/commands/schema/commit.mjs index d9820087..7d26bb41 100644 --- a/src/commands/schema/commit.mjs +++ b/src/commands/schema/commit.mjs @@ -1,7 +1,6 @@ //@ts-check import { container } from "../../cli.mjs"; -import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs"; import { CommandError } from "../../lib/errors.mjs"; import { getSecret } from "../../lib/fauna-client.mjs"; @@ -69,7 +68,7 @@ async function doCommit(argv) { } function buildCommitCommand(yargs) { - return yargsWithCommonQueryOptions(yargs) + return yargs .options({ input: { description: "Prompt for input. Use --no-input to disable.", diff --git a/src/commands/schema/diff.mjs b/src/commands/schema/diff.mjs index b55d60ea..2177ea31 100644 --- a/src/commands/schema/diff.mjs +++ b/src/commands/schema/diff.mjs @@ -3,11 +3,10 @@ import chalk from "chalk"; import { container } from "../../cli.mjs"; -import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs"; import { ValidationError } from "../../lib/errors.mjs"; import { getSecret } from "../../lib/fauna-client.mjs"; import { reformatFSL } from "../../lib/schema.mjs"; -import { localSchemaOptions } from "./schema.mjs"; +import { LOCAL_SCHEMA_OPTIONS } from "./schema.mjs"; /** * @returns {[string, string]} An tuple containing the source and target schema @@ -110,7 +109,8 @@ async function doDiff(argv) { } function buildDiffCommand(yargs) { - return yargsWithCommonQueryOptions(yargs) + return yargs + .options(LOCAL_SCHEMA_OPTIONS) .options({ staged: { description: "Show the diff between the active and staged schema.", @@ -128,7 +128,6 @@ function buildDiffCommand(yargs) { default: false, type: "boolean", }, - ...localSchemaOptions, }) .example([ [ diff --git a/src/commands/schema/pull.mjs b/src/commands/schema/pull.mjs index 65804375..649df955 100644 --- a/src/commands/schema/pull.mjs +++ b/src/commands/schema/pull.mjs @@ -1,9 +1,8 @@ //@ts-check import { container } from "../../cli.mjs"; -import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs"; import { getSecret } from "../../lib/fauna-client.mjs"; -import { localSchemaOptions } from "./schema.mjs"; +import { LOCAL_SCHEMA_OPTIONS } from "./schema.mjs"; async function determineFileState(argv, filenames) { const gatherFSL = container.resolve("gatherFSL"); @@ -135,7 +134,8 @@ async function doPull(argv) { } function buildPullCommand(yargs) { - return yargsWithCommonQueryOptions(yargs) + return yargs + .options(LOCAL_SCHEMA_OPTIONS) .options({ delete: { description: @@ -148,7 +148,6 @@ function buildPullCommand(yargs) { type: "boolean", default: false, }, - ...localSchemaOptions, }) .example([ [ diff --git a/src/commands/schema/push.mjs b/src/commands/schema/push.mjs index 68938033..a43f9609 100644 --- a/src/commands/schema/push.mjs +++ b/src/commands/schema/push.mjs @@ -3,11 +3,10 @@ import path from "path"; import { container } from "../../cli.mjs"; -import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs"; import { ValidationError } from "../../lib/errors.mjs"; import { getSecret } from "../../lib/fauna-client.mjs"; import { reformatFSL } from "../../lib/schema.mjs"; -import { localSchemaOptions } from "./schema.mjs"; +import { LOCAL_SCHEMA_OPTIONS } from "./schema.mjs"; /** * Pushes a schema (FSL) based on argv. @@ -98,7 +97,8 @@ export async function pushSchema(argv) { } function buildPushCommand(yargs) { - return yargsWithCommonQueryOptions(yargs) + return yargs + .options(LOCAL_SCHEMA_OPTIONS) .options({ input: { description: "Prompt for input. Use --no-input to disable.", @@ -111,7 +111,6 @@ function buildPushCommand(yargs) { type: "boolean", default: false, }, - ...localSchemaOptions, }) .example([ [ diff --git a/src/commands/schema/schema.mjs b/src/commands/schema/schema.mjs index f6b54351..55c3cfc3 100644 --- a/src/commands/schema/schema.mjs +++ b/src/commands/schema/schema.mjs @@ -1,6 +1,11 @@ //@ts-check -import { validateDatabaseOrSecret } from "../../lib/command-helpers.mjs"; +import { validateDatabaseOrSecret } from "../../lib/middleware.mjs"; +import { + ACCOUNT_OPTIONS, + CORE_OPTIONS, + DATABASE_PATH_OPTIONS, +} from "../../lib/options.mjs"; import abandonCommand from "./abandon.mjs"; import commitCommand from "./commit.mjs"; import diffCommand from "./diff.mjs"; @@ -8,7 +13,7 @@ import pullCommand from "./pull.mjs"; import pushCommand from "./push.mjs"; import statusCommand from "./status.mjs"; -export const localSchemaOptions = { +export const LOCAL_SCHEMA_OPTIONS = { "fsl-directory": { alias: ["directory", "dir"], type: "string", @@ -20,6 +25,9 @@ export const localSchemaOptions = { function buildSchema(yargs) { return yargs + .options(ACCOUNT_OPTIONS) + .options(DATABASE_PATH_OPTIONS) + .options(CORE_OPTIONS) .command(abandonCommand) .command(commitCommand) .command(diffCommand) diff --git a/src/commands/schema/status.mjs b/src/commands/schema/status.mjs index 06173651..5a2aa6ed 100644 --- a/src/commands/schema/status.mjs +++ b/src/commands/schema/status.mjs @@ -4,11 +4,10 @@ import chalk from "chalk"; import path from "path"; import { container } from "../../cli.mjs"; -import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs"; import { CommandError } from "../../lib/errors.mjs"; import { getSecret } from "../../lib/fauna-client.mjs"; import { reformatFSL } from "../../lib/schema.mjs"; -import { localSchemaOptions } from "./schema.mjs"; +import { LOCAL_SCHEMA_OPTIONS } from "./schema.mjs"; async function doStatus(argv) { const logger = container.resolve("logger"); @@ -81,18 +80,16 @@ async function doStatus(argv) { } function buildStatusCommand(yargs) { - return yargsWithCommonQueryOptions(yargs) - .options(localSchemaOptions) - .example([ - [ - "$0 schema status --database us/my_db", - "Get the staged schema status for the 'us/my_db' database.", - ], - [ - "$0 schema status --secret my-secret", - "Get the staged schema status for the database scoped to a secret.", - ], - ]); + return yargs.options(LOCAL_SCHEMA_OPTIONS).example([ + [ + "$0 schema status --database us/my_db", + "Get the staged schema status for the 'us/my_db' database.", + ], + [ + "$0 schema status --secret my-secret", + "Get the staged schema status for the database scoped to a secret.", + ], + ]); } export default { diff --git a/src/commands/shell.mjs b/src/commands/shell.mjs index ce25dd4b..3e765b00 100644 --- a/src/commands/shell.mjs +++ b/src/commands/shell.mjs @@ -6,14 +6,17 @@ import repl from "node:repl"; import * as esprima from "esprima"; import { container } from "../cli.mjs"; -import { - QUERY_INFO_CHOICES, - resolveFormat, - validateDatabaseOrSecret, - yargsWithCommonConfigurableQueryOptions, -} from "../lib/command-helpers.mjs"; import { formatQueryResponse, getSecret } from "../lib/fauna-client.mjs"; import { clearHistoryStorage, initHistoryStorage } from "../lib/file-util.mjs"; +import { validateDatabaseOrSecret } from "../lib/middleware.mjs"; +import { + ACCOUNT_OPTIONS, + CORE_OPTIONS, + DATABASE_PATH_OPTIONS, + QUERY_INFO_CHOICES, + QUERY_OPTIONS, +} from "../lib/options.mjs"; +import { resolveFormat } from "../lib/utils.mjs"; async function shellCommand(argv) { const { query: v4Query } = container.resolve("faunadb"); @@ -219,7 +222,11 @@ async function buildCustomEval(argv) { } function buildShellCommand(yargs) { - return yargsWithCommonConfigurableQueryOptions(yargs) + return yargs + .options(ACCOUNT_OPTIONS) + .options(DATABASE_PATH_OPTIONS) + .options(CORE_OPTIONS) + .options(QUERY_OPTIONS) .example([ [ "$0 shell --database us/my_db", diff --git a/src/lib/formatting/codeToAnsi.mjs b/src/lib/formatting/codeToAnsi.mjs index 675745b2..78848300 100644 --- a/src/lib/formatting/codeToAnsi.mjs +++ b/src/lib/formatting/codeToAnsi.mjs @@ -6,7 +6,7 @@ import log from "shiki/langs/log.mjs"; import yaml from "shiki/langs/yaml.mjs"; import githubDarkHighContrast from "shiki/themes/github-dark-high-contrast.mjs"; -import { isTTY } from "../misc.mjs"; +import { isTTY } from "../utils.mjs"; import { fql } from "./fql.mjs"; const THEME = "github-dark-high-contrast"; diff --git a/src/lib/middleware.mjs b/src/lib/middleware.mjs index 11402e68..a0f69fa3 100644 --- a/src/lib/middleware.mjs +++ b/src/lib/middleware.mjs @@ -7,7 +7,9 @@ import { fileURLToPath } from "node:url"; import { container } from "../cli.mjs"; import { fixPath } from "../lib/file-util.mjs"; +import { ValidationError } from "./errors.mjs"; import { redactedStringify } from "./formatting/redact.mjs"; +import { QUERY_OPTIONS } from "./options.mjs"; const LOCAL_URL = "http://0.0.0.0:8443"; const LOCAL_SECRET = "secret"; @@ -84,7 +86,7 @@ export function applyLocalArg(argv) { * container, false otherwise. */ export function isLocal(argv) { - return argv.local || argv._[0] === "local"; + return Boolean(argv.local) || argv._[0] === "local"; } /** @@ -149,3 +151,54 @@ was ${argv.role ? `'${argv.role}'` : "not"}}`, } return argv; } + +/** + * Mutates argv.include appropriately for query options + * @param {Object} argv + * @param {Array} argv.include + * @param {boolean} argv.performanceHints + * @returns {Object} + */ +export function resolveIncludeOptions(argv) { + if (argv.include.includes("none")) { + if (argv.include.length !== 1) { + throw new ValidationError( + `'--include none' cannot be used with other include options. Provided options: '${argv.include.join(", ")}'`, + ); + } + argv.include = []; + } + + if (argv.include.includes("all")) { + argv.include = [...QUERY_OPTIONS.include.choices]; + } + + if (argv.performanceHints && !argv.include.includes("summary")) { + argv.include.push("summary"); + } + + return argv; +} + +/** + * Validate that the user has specified either a database or a secret. + * This check is not required for commands that can operate at a + * "root" level. + * + * @param {object} argv + * @param {string} argv.database - The database to use + * @param {string} argv.secret - The secret to use + * @param {boolean} argv.local - Whether to use a local Fauna container + * @param {boolean|undefined} argv.getYargsCompletions - Whether this CLI run is to generate completions + */ +export const validateDatabaseOrSecret = (argv) => { + // don't validate completion invocations + if (argv.getYargsCompletions) return true; + + if (!argv.database && !argv.secret && !argv.local) { + throw new ValidationError( + "No database or secret specified. Please use either --database, --secret, or --local to connect to your desired Fauna database.", + ); + } + return true; +}; diff --git a/src/lib/misc.mjs b/src/lib/misc.mjs deleted file mode 100644 index 73fd4f1c..00000000 --- a/src/lib/misc.mjs +++ /dev/null @@ -1,3 +0,0 @@ -export function isTTY() { - return process.stdout.isTTY; -} diff --git a/src/lib/command-helpers.mjs b/src/lib/options.mjs similarity index 51% rename from src/lib/command-helpers.mjs rename to src/lib/options.mjs index bd997740..41cd089f 100644 --- a/src/lib/command-helpers.mjs +++ b/src/lib/options.mjs @@ -1,33 +1,24 @@ //@ts-check -import { container } from "../cli.mjs"; -import { ValidationError } from "./errors.mjs"; import { Format } from "./formatting/colorize.mjs"; -const COMMON_OPTIONS = { - // hidden +/** + * Options required for any command making API requests to the Account API + */ +export const ACCOUNT_OPTIONS = { "account-url": { type: "string", - description: "the Fauna account URL to query", + description: "The Fauna account URL to query", default: "https://account.fauna.com", hidden: true, }, - "client-id": { - type: "string", - description: "the client id to use when calling Fauna", - required: false, - hidden: true, - }, - "client-secret": { + "account-key": { type: "string", - description: "the client secret to use when calling Fauna", + description: + "Fauna account key used for authentication. Can't be used with --user or --secret.", required: false, - hidden: true, + group: "API:", }, -}; - -// used for queries customers can't configure that are made on their behalf -const COMMON_QUERY_OPTIONS = { user: { alias: "u", type: "string", @@ -36,6 +27,31 @@ const COMMON_QUERY_OPTIONS = { default: "default", group: "API:", }, + role: { + alias: "r", + type: "string", + description: "Role used to run the command. Can't be used with --secret.", + group: "API:", + }, +}; + +/** + * Options required for commands relying on a database path + */ +export const DATABASE_PATH_OPTIONS = { + database: { + alias: "d", + type: "string", + description: + "Database, including Region Group and hierarchy, to run the command in. Ex: 'us/my_db', 'eu/parent_db/child_db', 'global/db'.", + group: "API:", + }, +}; + +/** + * Options required for commands making API requests to the Core API + */ +export const CORE_OPTIONS = { local: { type: "boolean", describe: @@ -56,26 +72,6 @@ const COMMON_QUERY_OPTIONS = { required: false, group: "API:", }, - "account-key": { - type: "string", - description: - "Fauna account key used for authentication. Can't be used with --user or --secret.", - required: false, - group: "API:", - }, - database: { - alias: "d", - type: "string", - description: - "Database, including Region Group and hierarchy, to run the command in. Ex: 'us/my_db', 'eu/parent_db/child_db', 'global/db'. Can't be used with --secret.", - group: "API:", - }, - role: { - alias: "r", - type: "string", - description: "Role used to run the command. Can't be used with --secret.", - group: "API:", - }, }; export const QUERY_INFO_CHOICES = [ @@ -86,9 +82,10 @@ export const QUERY_INFO_CHOICES = [ "stats", ]; -// used for queries customers can configure -const COMMON_CONFIGURABLE_QUERY_OPTIONS = { - ...COMMON_QUERY_OPTIONS, +/** + * Options required for commands making FQL queries to the Core API + */ +export const QUERY_OPTIONS = { "api-version": { description: "FQL version to use.", type: "string", @@ -136,72 +133,3 @@ const COMMON_CONFIGURABLE_QUERY_OPTIONS = { "Query response info to output. Pass values as a space-separated list. Ex: --include summary queryTags.", }, }; - -export function yargsWithCommonQueryOptions(yargs) { - return yargsWithCommonOptions(yargs, COMMON_QUERY_OPTIONS); -} - -export function yargsWithCommonConfigurableQueryOptions(yargs) { - return yargsWithCommonOptions( - yargs, - COMMON_CONFIGURABLE_QUERY_OPTIONS, - ).middleware((argv) => { - if (argv.include.includes("none")) { - if (argv.include.length !== 1) { - throw new ValidationError( - `'--include none' cannot be used with other include options. Provided options: '${argv.include.join(", ")}'`, - ); - } - argv.include = []; - } - - if (argv.include.includes("all")) { - argv.include = [...QUERY_INFO_CHOICES]; - } - - if (argv.performanceHints && !argv.include.includes("summary")) { - argv.include.push("summary"); - } - }); -} - -export function yargsWithCommonOptions(yargs, options) { - return yargs.options({ ...options, ...COMMON_OPTIONS }); -} - -export const resolveFormat = (argv) => { - const logger = container.resolve("logger"); - - if (argv.json) { - logger.debug( - "--json has taken precedence over other formatting options, using JSON output", - "argv", - ); - return Format.JSON; - } - - return argv.format; -}; - -/** - * Validate that the user has specified either a database or a secret. - * This check is not required for commands that can operate at a - * "root" level. - * - * @param {object} argv - * @param {string} argv.database - The database to use - * @param {string} argv.secret - The secret to use - * @param {boolean} argv.local - Whether to use a local Fauna container - * @param {boolean|undefined} argv.getYargsCompletions - Whether this CLI run is to generate completions - */ -export const validateDatabaseOrSecret = (argv) => { - // don't validate completion invocations - if (argv.getYargsCompletions) return true; - - if (!argv.database && !argv.secret && !argv.local) { - throw new ValidationError( - "No database or secret specified. Please use either --database, --secret, or --local to connect to your desired Fauna database.", - ); - } - return true; -}; diff --git a/src/lib/utils.mjs b/src/lib/utils.mjs new file mode 100644 index 00000000..7462f5ab --- /dev/null +++ b/src/lib/utils.mjs @@ -0,0 +1,20 @@ +import { container } from "../cli.mjs"; +import { Format } from "./formatting/colorize.mjs"; + +export function isTTY() { + return process.stdout.isTTY; +} + +export const resolveFormat = (argv) => { + const logger = container.resolve("logger"); + + if (argv.json) { + logger.debug( + "--json has taken precedence over other formatting options, using JSON output", + "argv", + ); + return Format.JSON; + } + + return argv.format; +}; diff --git a/test/query.mjs b/test/query.mjs index 40a54ce2..56af5a71 100644 --- a/test/query.mjs +++ b/test/query.mjs @@ -6,9 +6,9 @@ import sinon from "sinon"; import { run } from "../src/cli.mjs"; import { setupTestContainer as setupContainer } from "../src/config/setup-test-container.mjs"; -import { QUERY_INFO_CHOICES } from "../src/lib/command-helpers.mjs"; import { NETWORK_ERROR_MESSAGE } from "../src/lib/errors.mjs"; import { colorize } from "../src/lib/formatting/colorize.mjs"; +import { QUERY_INFO_CHOICES } from "../src/lib/options.mjs"; import { createV4QueryFailure, createV4QuerySuccess,