"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validate = validate; exports.checkNoUnwrappedItemOptionPairs = checkNoUnwrappedItemOptionPairs; var _plugin = _interopRequireDefault(require("../plugin")); var _removed = _interopRequireDefault(require("./removed")); var _optionAssertions = require("./option-assertions"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const ROOT_VALIDATORS = { cwd: _optionAssertions.assertString, root: _optionAssertions.assertString, rootMode: _optionAssertions.assertRootMode, configFile: _optionAssertions.assertConfigFileSearch, caller: _optionAssertions.assertCallerMetadata, filename: _optionAssertions.assertString, filenameRelative: _optionAssertions.assertString, code: _optionAssertions.assertBoolean, ast: _optionAssertions.assertBoolean, cloneInputAst: _optionAssertions.assertBoolean, envName: _optionAssertions.assertString }; const BABELRC_VALIDATORS = { babelrc: _optionAssertions.assertBoolean, babelrcRoots: _optionAssertions.assertBabelrcSearch }; const NONPRESET_VALIDATORS = { extends: _optionAssertions.assertString, ignore: _optionAssertions.assertIgnoreList, only: _optionAssertions.assertIgnoreList }; const COMMON_VALIDATORS = { inputSourceMap: _optionAssertions.assertInputSourceMap, presets: _optionAssertions.assertPluginList, plugins: _optionAssertions.assertPluginList, passPerPreset: _optionAssertions.assertBoolean, env: assertEnvSet, overrides: assertOverridesList, test: _optionAssertions.assertConfigApplicableTest, include: _optionAssertions.assertConfigApplicableTest, exclude: _optionAssertions.assertConfigApplicableTest, retainLines: _optionAssertions.assertBoolean, comments: _optionAssertions.assertBoolean, shouldPrintComment: _optionAssertions.assertFunction, compact: _optionAssertions.assertCompact, minified: _optionAssertions.assertBoolean, auxiliaryCommentBefore: _optionAssertions.assertString, auxiliaryCommentAfter: _optionAssertions.assertString, sourceType: _optionAssertions.assertSourceType, wrapPluginVisitorMethod: _optionAssertions.assertFunction, highlightCode: _optionAssertions.assertBoolean, sourceMaps: _optionAssertions.assertSourceMaps, sourceMap: _optionAssertions.assertSourceMaps, sourceFileName: _optionAssertions.assertString, sourceRoot: _optionAssertions.assertString, getModuleId: _optionAssertions.assertFunction, moduleRoot: _optionAssertions.assertString, moduleIds: _optionAssertions.assertBoolean, moduleId: _optionAssertions.assertString, parserOpts: _optionAssertions.assertObject, generatorOpts: _optionAssertions.assertObject }; function getSource(loc) { return loc.type === "root" ? loc.source : getSource(loc.parent); } function validate(type, opts) { return validateNested({ type: "root", source: type }, opts); } function validateNested(loc, opts) { const type = getSource(loc); assertNoDuplicateSourcemap(opts); Object.keys(opts).forEach(key => { const optLoc = { type: "option", name: key, parent: loc }; if (type === "preset" && NONPRESET_VALIDATORS[key]) { throw new Error(`${(0, _optionAssertions.msg)(optLoc)} is not allowed in preset options`); } if (type !== "arguments" && ROOT_VALIDATORS[key]) { throw new Error(`${(0, _optionAssertions.msg)(optLoc)} is only allowed in root programmatic options`); } if (type !== "arguments" && type !== "configfile" && BABELRC_VALIDATORS[key]) { if (type === "babelrcfile" || type === "extendsfile") { throw new Error(`${(0, _optionAssertions.msg)(optLoc)} is not allowed in .babelrc or "extends"ed files, only in root programmatic options, ` + `or babel.config.js/config file options`); } throw new Error(`${(0, _optionAssertions.msg)(optLoc)} is only allowed in root programmatic options, or babel.config.js/config file options`); } const validator = COMMON_VALIDATORS[key] || NONPRESET_VALIDATORS[key] || BABELRC_VALIDATORS[key] || ROOT_VALIDATORS[key] || throwUnknownError; validator(optLoc, opts[key]); }); return opts; } function throwUnknownError(loc) { const key = loc.name; if (_removed.default[key]) { const { message, version = 5 } = _removed.default[key]; throw new Error(`Using removed Babel ${version} option: ${(0, _optionAssertions.msg)(loc)} - ${message}`); } else { const unknownOptErr = new Error(`Unknown option: ${(0, _optionAssertions.msg)(loc)}. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.`); unknownOptErr.code = "BABEL_UNKNOWN_OPTION"; throw unknownOptErr; } } function has(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } function assertNoDuplicateSourcemap(opts) { if (has(opts, "sourceMap") && has(opts, "sourceMaps")) { throw new Error(".sourceMap is an alias for .sourceMaps, cannot use both"); } } function assertEnvSet(loc, value) { if (loc.parent.type === "env") { throw new Error(`${(0, _optionAssertions.msg)(loc)} is not allowed inside of another .env block`); } const parent = loc.parent; const obj = (0, _optionAssertions.assertObject)(loc, value); if (obj) { for (const envName of Object.keys(obj)) { const env = (0, _optionAssertions.assertObject)((0, _optionAssertions.access)(loc, envName), obj[envName]); if (!env) continue; const envLoc = { type: "env", name: envName, parent }; validateNested(envLoc, env); } } return obj; } function assertOverridesList(loc, value) { if (loc.parent.type === "env") { throw new Error(`${(0, _optionAssertions.msg)(loc)} is not allowed inside an .env block`); } if (loc.parent.type === "overrides") { throw new Error(`${(0, _optionAssertions.msg)(loc)} is not allowed inside an .overrides block`); } const parent = loc.parent; const arr = (0, _optionAssertions.assertArray)(loc, value); if (arr) { for (const [index, item] of arr.entries()) { const objLoc = (0, _optionAssertions.access)(loc, index); const env = (0, _optionAssertions.assertObject)(objLoc, item); if (!env) throw new Error(`${(0, _optionAssertions.msg)(objLoc)} must be an object`); const overridesLoc = { type: "overrides", index, parent }; validateNested(overridesLoc, env); } } return arr; } function checkNoUnwrappedItemOptionPairs(items, index, type, e) { if (index === 0) return; const lastItem = items[index - 1]; const thisItem = items[index]; 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`; } }