[babel 8] Type checking preset-typescript options (#12460)
* refactor: extract option normalization in preset-typescript * breaking: type checking preset-typescript options * chore: bundle preset-typescript into a single lib * test: disable Babel 7 test on Babel 8 breaking change test * workaround Jest 24 error snapshot dedent issue * skip Babel 8 test when the Breaking ENV is not available * chore: update test snapshot * Update packages/babel-preset-typescript/test/normalize-options.spec.js Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com> * update test fixtures Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
parent
866a742bf7
commit
ff52acee79
@ -361,6 +361,7 @@ function copyDts(packages) {
|
|||||||
const libBundles = [
|
const libBundles = [
|
||||||
"packages/babel-parser",
|
"packages/babel-parser",
|
||||||
"packages/babel-plugin-proposal-optional-chaining",
|
"packages/babel-plugin-proposal-optional-chaining",
|
||||||
|
"packages/babel-preset-typescript",
|
||||||
"packages/babel-helper-member-expression-to-functions",
|
"packages/babel-helper-member-expression-to-functions",
|
||||||
].map(src => ({
|
].map(src => ({
|
||||||
src,
|
src,
|
||||||
|
|||||||
@ -1,35 +1,19 @@
|
|||||||
import { declare } from "@babel/helper-plugin-utils";
|
import { declare } from "@babel/helper-plugin-utils";
|
||||||
import transformTypeScript from "@babel/plugin-transform-typescript";
|
import transformTypeScript from "@babel/plugin-transform-typescript";
|
||||||
import { OptionValidator } from "@babel/helper-validator-option";
|
import normalizeOptions from "./normalize-options.js";
|
||||||
const v = new OptionValidator("@babel/preset-typescript");
|
|
||||||
|
|
||||||
export default declare((api, opts) => {
|
export default declare((api, opts) => {
|
||||||
api.assertVersion(7);
|
api.assertVersion(7);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
allExtensions,
|
||||||
allowDeclareFields,
|
allowDeclareFields,
|
||||||
allowNamespaces,
|
allowNamespaces,
|
||||||
|
isTSX,
|
||||||
jsxPragma,
|
jsxPragma,
|
||||||
|
jsxPragmaFrag,
|
||||||
onlyRemoveTypeImports,
|
onlyRemoveTypeImports,
|
||||||
} = opts;
|
} = normalizeOptions(opts);
|
||||||
|
|
||||||
const jsxPragmaFrag = v.validateStringOption(
|
|
||||||
"jsxPragmaFrag",
|
|
||||||
opts.jsxPragmaFrag,
|
|
||||||
"React.Fragment",
|
|
||||||
);
|
|
||||||
|
|
||||||
const allExtensions = v.validateBooleanOption(
|
|
||||||
"allExtensions",
|
|
||||||
opts.allExtensions,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
const isTSX = v.validateBooleanOption("isTSX", opts.isTSX, false);
|
|
||||||
|
|
||||||
if (isTSX) {
|
|
||||||
v.invariant(allExtensions, "isTSX:true requires allExtensions:true");
|
|
||||||
}
|
|
||||||
|
|
||||||
const pluginOptions = isTSX => ({
|
const pluginOptions = isTSX => ({
|
||||||
allowDeclareFields,
|
allowDeclareFields,
|
||||||
|
|||||||
72
packages/babel-preset-typescript/src/normalize-options.js
Normal file
72
packages/babel-preset-typescript/src/normalize-options.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { OptionValidator } from "@babel/helper-validator-option";
|
||||||
|
const v = new OptionValidator("@babel/preset-typescript");
|
||||||
|
|
||||||
|
export default function normalizeOptions(options = {}) {
|
||||||
|
let {
|
||||||
|
allowDeclareFields,
|
||||||
|
allowNamespaces,
|
||||||
|
jsxPragma,
|
||||||
|
onlyRemoveTypeImports,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
if (process.env.BABEL_8_BREAKING) {
|
||||||
|
const TopLevelOptions = {
|
||||||
|
allowDeclareFields: "allowDeclareFields",
|
||||||
|
allExtensions: "allExtensions",
|
||||||
|
allowNamespaces: "allowNamespaces",
|
||||||
|
isTSX: "isTSX",
|
||||||
|
jsxPragma: "jsxPragma",
|
||||||
|
jsxPragmaFrag: "jsxPragmaFrag",
|
||||||
|
onlyRemoveTypeImports: "onlyRemoveTypeImports",
|
||||||
|
};
|
||||||
|
v.validateTopLevelOptions(options, TopLevelOptions);
|
||||||
|
allowDeclareFields = v.validateBooleanOption(
|
||||||
|
TopLevelOptions.allowDeclareFields,
|
||||||
|
options.allowDeclareFields,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
allowNamespaces = v.validateBooleanOption(
|
||||||
|
TopLevelOptions.allowNamespaces,
|
||||||
|
options.allowNamespaces,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
jsxPragma = v.validateStringOption(
|
||||||
|
TopLevelOptions.jsxPragma,
|
||||||
|
options.jsxPragma,
|
||||||
|
"React",
|
||||||
|
);
|
||||||
|
onlyRemoveTypeImports = v.validateBooleanOption(
|
||||||
|
TopLevelOptions.onlyRemoveTypeImports,
|
||||||
|
options.onlyRemoveTypeImports,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsxPragmaFrag = v.validateStringOption(
|
||||||
|
"jsxPragmaFrag",
|
||||||
|
options.jsxPragmaFrag,
|
||||||
|
"React.Fragment",
|
||||||
|
);
|
||||||
|
|
||||||
|
const allExtensions = v.validateBooleanOption(
|
||||||
|
"allExtensions",
|
||||||
|
options.allExtensions,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const isTSX = v.validateBooleanOption("isTSX", options.isTSX, false);
|
||||||
|
|
||||||
|
if (isTSX) {
|
||||||
|
v.invariant(allExtensions, "isTSX:true requires allExtensions:true");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
allExtensions,
|
||||||
|
allowDeclareFields,
|
||||||
|
allowNamespaces,
|
||||||
|
isTSX,
|
||||||
|
jsxPragma,
|
||||||
|
jsxPragmaFrag,
|
||||||
|
onlyRemoveTypeImports,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
import normalizeOptions from "../src/normalize-options";
|
||||||
|
describe("normalize options", () => {
|
||||||
|
(process.env.BABEL_8_BREAKING ? describe : describe.skip)("Babel 8", () => {
|
||||||
|
it("should throw on unknown options", () => {
|
||||||
|
expect(() => normalizeOptions({ allowNamespace: true })).toThrowError(
|
||||||
|
"@babel/preset-typescript: 'allowNamespace' is not a valid top-level option.\n- Did you mean 'allowNamespaces'?",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it.each([
|
||||||
|
"allowDeclareFields",
|
||||||
|
"allExtensions",
|
||||||
|
"allowNamespaces",
|
||||||
|
"isTSX",
|
||||||
|
"onlyRemoveTypeImports",
|
||||||
|
])("should throw when `%p` is not a boolean", optionName => {
|
||||||
|
expect(() => normalizeOptions({ [optionName]: 0 })).toThrow(
|
||||||
|
`@babel/preset-typescript: '${optionName}' option must be a boolean.`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it.each(["jsxPragma", "jsxPragmaFrag"])(
|
||||||
|
"should throw when `%p` is not a string",
|
||||||
|
optionName => {
|
||||||
|
expect(() => normalizeOptions({ [optionName]: 0 })).toThrow(
|
||||||
|
`@babel/preset-typescript: '${optionName}' option must be a string.`,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
it("should not throw when options is not defined", () => {
|
||||||
|
expect(() => normalizeOptions()).not.toThrowError();
|
||||||
|
});
|
||||||
|
it("default values", () => {
|
||||||
|
expect(normalizeOptions({})).toMatchInlineSnapshot(`
|
||||||
|
Object {
|
||||||
|
"allExtensions": false,
|
||||||
|
"allowDeclareFields": true,
|
||||||
|
"allowNamespaces": true,
|
||||||
|
"isTSX": false,
|
||||||
|
"jsxPragma": "React",
|
||||||
|
"jsxPragmaFrag": "React.Fragment",
|
||||||
|
"onlyRemoveTypeImports": true,
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
(process.env.BABEL_8_BREAKING ? describe.skip : describe)("Babel 7", () => {
|
||||||
|
it("should not throw on unknown options", () => {
|
||||||
|
expect(() =>
|
||||||
|
normalizeOptions({ allowNamespace: true }),
|
||||||
|
).not.toThrowError();
|
||||||
|
});
|
||||||
|
it.each(["allowDeclareFields", "allowNamespaces", "onlyRemoveTypeImports"])(
|
||||||
|
"should not throw when `%p` is not a boolean",
|
||||||
|
optionName => {
|
||||||
|
expect(() => normalizeOptions({ [optionName]: 0 })).not.toThrowError();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
it.each(["jsxPragma"])(
|
||||||
|
"should throw when `%p` is not a string",
|
||||||
|
optionName => {
|
||||||
|
expect(() => normalizeOptions({ [optionName]: 0 })).not.toThrowError();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
it.each(["allExtensions", "isTSX"])(
|
||||||
|
"should throw when `%p` is not a boolean",
|
||||||
|
optionName => {
|
||||||
|
expect(() => normalizeOptions({ [optionName]: 0 })).toThrow(
|
||||||
|
`@babel/preset-typescript: '${optionName}' option must be a boolean.`,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
it.each(["jsxPragmaFrag"])(
|
||||||
|
"should throw when `%p` is not a string",
|
||||||
|
optionName => {
|
||||||
|
expect(() => normalizeOptions({ [optionName]: 0 })).toThrow(
|
||||||
|
`@babel/preset-typescript: '${optionName}' option must be a string.`,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
it("default values", () => {
|
||||||
|
expect(normalizeOptions({})).toMatchInlineSnapshot(`
|
||||||
|
Object {
|
||||||
|
"allExtensions": false,
|
||||||
|
"allowDeclareFields": undefined,
|
||||||
|
"allowNamespaces": undefined,
|
||||||
|
"isTSX": false,
|
||||||
|
"jsxPragma": undefined,
|
||||||
|
"jsxPragmaFrag": "React.Fragment",
|
||||||
|
"onlyRemoveTypeImports": undefined,
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user