Skip to content

Commit

Permalink
move demandSingleValue and demandOneOfOptions to core
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed Oct 21, 2024
1 parent 1e3057e commit 4bf4f4b
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 53 deletions.
48 changes: 48 additions & 0 deletions packages/wrangler/src/core/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { CommandLineArgsError } from "../errors";

/**
* A helper to demand one of a set of options
* via https://github.com/yargs/yargs/issues/1093#issuecomment-491299261
*/
export function demandOneOfOption(...options: string[]) {
return function (argv: { [key: string]: unknown }) {
const count = options.filter((option) => argv[option]).length;
const lastOption = options.pop();

if (count === 0) {
throw new CommandLineArgsError(
`Exactly one of the arguments ${options.join(
", "
)} and ${lastOption} is required`
);
} else if (count > 1) {
throw new CommandLineArgsError(
`Arguments ${options.join(
", "
)} and ${lastOption} are mutually exclusive`
);
}

return true;
};
}

/**
* A helper to ensure that an argument only receives a single value.
*
* This is a workaround for a limitation in yargs where non-array arguments can still receive multiple values
* even though the inferred type is not an array.
*
* @see https://github.com/yargs/yargs/issues/1318
*/
export function demandSingleValue(key: string) {
return function (argv: { [key: string]: unknown }) {
if (Array.isArray(argv[key])) {
throw new CommandLineArgsError(
`The argument '--${key}' expects a single value, but received multiple: ${JSON.stringify(argv[key])}.`
);
}

return true;
};
}
1 change: 1 addition & 0 deletions packages/wrangler/src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { defineAlias, defineCommand, defineNamespace } from "./define-command";
export { demandOneOfOption, demandSingleValue } from "./helpers";
2 changes: 2 additions & 0 deletions packages/wrangler/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export class FatalError extends UserError {
}
}

export class CommandLineArgsError extends UserError {}

/**
* JsonFriendlyFatalError is used to output JSON when wrangler crashes, useful for --json mode.
*
Expand Down
56 changes: 6 additions & 50 deletions packages/wrangler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,17 @@ import {
import { devHandler, devOptions } from "./dev";
import { workerNamespaceCommands } from "./dispatch-namespace";
import { docsHandler, docsOptions } from "./docs";
import { JsonFriendlyFatalError, UserError } from "./errors";
import {
CommandLineArgsError,
JsonFriendlyFatalError,
UserError,
} from "./errors";
import { generateHandler, generateOptions } from "./generate";
import { hyperdrive } from "./hyperdrive/index";
import { initHandler, initOptions } from "./init";
import "./kv";
import "./workflows";
import { demandSingleValue } from "./core";
import { logBuildFailure, logger, LOGGER_LEVELS } from "./logger";
import * as metrics from "./metrics";
import { mTlsCertificateCommands } from "./mtls-certificate/cli";
Expand Down Expand Up @@ -159,55 +164,6 @@ export function getLegacyScriptName(
: args.name ?? config.name;
}

/**
* A helper to demand one of a set of options
* via https://github.com/yargs/yargs/issues/1093#issuecomment-491299261
*/
export function demandOneOfOption(...options: string[]) {
return function (argv: { [key: string]: unknown }) {
const count = options.filter((option) => argv[option]).length;
const lastOption = options.pop();

if (count === 0) {
throw new CommandLineArgsError(
`Exactly one of the arguments ${options.join(
", "
)} and ${lastOption} is required`
);
} else if (count > 1) {
throw new CommandLineArgsError(
`Arguments ${options.join(
", "
)} and ${lastOption} are mutually exclusive`
);
}

return true;
};
}

/**
* A helper to ensure that an argument only receives a single value.
*
* This is a workaround for a limitation in yargs where non-array arguments can still receive multiple values
* even though the inferred type is not an array.
*
* @see https://github.com/yargs/yargs/issues/1318
*/
export function demandSingleValue(key: string) {
return function (argv: { [key: string]: unknown }) {
if (Array.isArray(argv[key])) {
throw new CommandLineArgsError(
`The argument '--${key}' expects a single value, but received multiple: ${JSON.stringify(argv[key])}.`
);
}

return true;
};
}

export class CommandLineArgsError extends UserError {}

export function createCLIParser(argv: string[]) {
const experimentalGradualRollouts =
// original flag -- using internal product name (Gradual Rollouts) -- kept for temp back-compat
Expand Down
10 changes: 7 additions & 3 deletions packages/wrangler/src/kv/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import { Blob } from "node:buffer";
import { arrayBuffer } from "node:stream/consumers";
import { StringDecoder } from "node:string_decoder";
import { readConfig } from "../config";
import { defineAlias, defineCommand, defineNamespace } from "../core";
import {
defineAlias,
defineCommand,
defineNamespace,
demandOneOfOption,
} from "../core";
import { confirm } from "../dialogs";
import { UserError } from "../errors";
import { CommandLineArgsError, demandOneOfOption } from "../index";
import { CommandLineArgsError, UserError } from "../errors";
import { logger } from "../logger";
import * as metrics from "../metrics";
import { parseJSON, readFileSync, readFileSyncToBuffer } from "../parse";
Expand Down

0 comments on commit 4bf4f4b

Please sign in to comment.