Huáng Jùnliàng f2da186714
refactor: add @babel/helper-validator-option (#12006)
* refactor: add @babel/helper-validator-option

* refactor: simplify validateTopLevelOptions

* perf: the recursive version is not practically fast

* Update packages/babel-helper-validator-option/README.md

Co-authored-by: Brian Ng <bng412@gmail.com>

* Update packages/babel-helper-validator-option/src/validator.js

* fix: incorrect type annotation

* refactor: use babel/helper-option-validator in babel/compat-data

* chore: fix flow types error

* Address review comments

* address review comments

Co-authored-by: Brian Ng <bng412@gmail.com>
2020-09-24 16:23:35 -04:00

82 lines
2.2 KiB
JavaScript

// @flow
import { findSuggestion } from "./find-suggestion.js";
export class OptionValidator {
declare descriptor: string;
constructor(descriptor: string) {
this.descriptor = descriptor;
}
/**
* Validate if the given `options` follow the name of keys defined in the `TopLevelOptionShape`
*
* @param {Object} options
* @param {Object} TopLevelOptionShape
* An object with all the valid key names that `options` should be allowed to have
* The property values of `TopLevelOptionShape` can be arbitrary
* @memberof OptionValidator
*/
validateTopLevelOptions(options: Object, TopLevelOptionShape: Object): void {
const validOptionNames = Object.keys(TopLevelOptionShape);
for (const option of Object.keys(options)) {
if (!validOptionNames.includes(option)) {
throw new Error(
this.formatMessage(`'${option}' is not a valid top-level option.
- Did you mean '${findSuggestion(option, validOptionNames)}'?`),
);
}
}
}
// note: we do not consider rewrite them to high order functions
// until we have to support `validateNumberOption`.
validateBooleanOption(
name: string,
value?: boolean,
defaultValue?: boolean,
): boolean | void {
if (value === undefined) {
value = defaultValue;
} else {
this.invariant(
typeof value === "boolean",
`'${name}' option must be a boolean.`,
);
}
return value;
}
validateStringOption(
name: string,
value?: string,
defaultValue?: string,
): string | void {
if (value === undefined) {
value = defaultValue;
} else {
this.invariant(
typeof value === "string",
`'${name}' option must be a string.`,
);
}
return value;
}
/**
* A helper interface copied from the `invariant` npm package.
* It throws given `message` when `condition` is not met
*
* @param {boolean} condition
* @param {string} message
* @memberof OptionValidator
*/
invariant(condition: boolean, message: string): void {
if (!condition) {
throw new Error(this.formatMessage(message));
}
}
formatMessage(message: string): string {
return `${this.descriptor}: ${message}`;
}
}