polish: throw human-friendly error when item-option pair is in… (#10969)

* polish: throw human-friendly error when item-option pair is incorrectly unwrapped

* add testcase for plugin

* fix: exclude false positive

* fix: validate should support plugin optionsSourceKind

* Revert "fix: validate should support plugin optionsSourceKind"

* fix: validate plugin object in assertNoUnwrappedItemOptionPairs

* fix flow error

* update test fixtures

* refactor: move to loadDescriptor catch clause

* chore: throw Error instead of builtin ReferenceError

* fix flow errors

* chore: add more test cases
This commit is contained in:
Huáng Jùnliàng
2020-01-20 15:05:07 -05:00
committed by Nicolò Ribaudo
parent 43b23e0869
commit fa975bf7cd
7 changed files with 164 additions and 14 deletions

View File

@@ -27,6 +27,7 @@ import {
type Validator,
type OptionPath,
} from "./option-assertions";
import type { UnloadedDescriptor } from "../config-descriptors";
const ROOT_VALIDATORS: ValidatorSet = {
cwd: (assertString: Validator<$PropertyType<ValidatedOptions, "cwd">>),
@@ -365,16 +366,20 @@ function throwUnknownError(loc: OptionPath) {
if (removed[key]) {
const { message, version = 5 } = removed[key];
throw new ReferenceError(
throw new Error(
`Using removed Babel ${version} option: ${msg(loc)} - ${message}`,
);
} else {
// eslint-disable-next-line max-len
const unknownOptErr = `Unknown option: ${msg(
loc,
)}. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.`;
const unknownOptErr = new Error(
`Unknown option: ${msg(
loc,
)}. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.`,
);
// $FlowIgnore
unknownOptErr.code = "BABEL_UNKNOWN_OPTION";
throw new ReferenceError(unknownOptErr);
throw unknownOptErr;
}
}
@@ -439,3 +444,26 @@ function assertOverridesList(loc: OptionPath, value: mixed): OverridesList {
}
return (arr: any);
}
export function checkNoUnwrappedItemOptionPairs(
lastItem: UnloadedDescriptor,
thisItem: UnloadedDescriptor,
type: "plugin" | "preset",
index: number,
e: Error,
): void {
if (
lastItem.file &&
lastItem.options === undefined &&
typeof thisItem.value === "object"
) {
e.message +=
`\n- Maybe you meant to use\n` +
`"${type}": [\n ["${lastItem.file.request}", ${JSON.stringify(
thisItem.value,
undefined,
2,
)}]\n]\n` +
`To be a valid ${type}, its name and options should be wrapped in a pair of brackets`;
}
}

View File

@@ -97,7 +97,14 @@ export function validatePluginObject(obj: {}): PluginObject {
};
if (validator) validator(optLoc, obj[key]);
else throw new Error(`.${key} is not a valid Plugin property`);
else {
const invalidPluginPropertyError = new Error(
`.${key} is not a valid Plugin property`,
);
// $FlowIgnore
invalidPluginPropertyError.code = "BABEL_UNKNOWN_PLUGIN_PROPERTY";
throw invalidPluginPropertyError;
}
});
return (obj: any);