// @flow import removed from "./removed"; import { assertString, assertBoolean, assertObject, assertInputSourceMap, assertIgnoreList, assertPluginList, assertFunction, assertSourceMaps, assertCompact, assertSourceType, type ValidatorSet, type Validator, } from "./option-assertions"; const ROOT_VALIDATORS: ValidatorSet = { cwd: (assertString: Validator<$PropertyType>), filename: (assertString: Validator< $PropertyType, >), filenameRelative: (assertString: Validator< $PropertyType, >), babelrc: (assertBoolean: Validator< $PropertyType, >), code: (assertBoolean: Validator<$PropertyType>), ast: (assertBoolean: Validator<$PropertyType>), envName: (assertString: Validator< $PropertyType, >), }; const NONPRESET_VALIDATORS: ValidatorSet = { extends: (assertString: Validator< $PropertyType, >), env: (assertEnvSet: Validator<$PropertyType>), ignore: (assertIgnoreList: Validator< $PropertyType, >), only: (assertIgnoreList: Validator<$PropertyType>), }; const COMMON_VALIDATORS: ValidatorSet = { // TODO: Should 'inputSourceMap' be moved to be a root-only option? // We may want a boolean-only version to be a common option, with the // object only allowed as a root config argument. inputSourceMap: (assertInputSourceMap: Validator< $PropertyType, >), presets: (assertPluginList: Validator< $PropertyType, >), plugins: (assertPluginList: Validator< $PropertyType, >), passPerPreset: (assertBoolean: Validator< $PropertyType, >), retainLines: (assertBoolean: Validator< $PropertyType, >), comments: (assertBoolean: Validator< $PropertyType, >), shouldPrintComment: (assertFunction: Validator< $PropertyType, >), compact: (assertCompact: Validator< $PropertyType, >), minified: (assertBoolean: Validator< $PropertyType, >), auxiliaryCommentBefore: (assertString: Validator< $PropertyType, >), auxiliaryCommentAfter: (assertString: Validator< $PropertyType, >), sourceType: (assertSourceType: Validator< $PropertyType, >), wrapPluginVisitorMethod: (assertFunction: Validator< $PropertyType, >), highlightCode: (assertBoolean: Validator< $PropertyType, >), sourceMaps: (assertSourceMaps: Validator< $PropertyType, >), sourceMap: (assertSourceMaps: Validator< $PropertyType, >), sourceMapTarget: (assertString: Validator< $PropertyType, >), sourceFileName: (assertString: Validator< $PropertyType, >), sourceRoot: (assertString: Validator< $PropertyType, >), getModuleId: (assertFunction: Validator< $PropertyType, >), moduleRoot: (assertString: Validator< $PropertyType, >), moduleIds: (assertBoolean: Validator< $PropertyType, >), moduleId: (assertString: Validator< $PropertyType, >), parserOpts: (assertObject: Validator< $PropertyType, >), generatorOpts: (assertObject: Validator< $PropertyType, >), }; export type InputOptions = ValidatedOptions; export type ValidatedOptions = { cwd?: string, filename?: string, filenameRelative?: string, babelrc?: boolean, code?: boolean, ast?: boolean, inputSourceMap?: RootInputSourceMapOption, envName?: string, extends?: string, env?: EnvSet, ignore?: IgnoreList, only?: IgnoreList, presets?: PluginList, plugins?: PluginList, passPerPreset?: boolean, // Options for @babel/generator retainLines?: boolean, comments?: boolean, shouldPrintComment?: Function, compact?: CompactOption, minified?: boolean, auxiliaryCommentBefore?: string, auxiliaryCommentAfter?: string, // Parser sourceType?: SourceTypeOption, wrapPluginVisitorMethod?: Function, highlightCode?: boolean, // Sourcemap generation options. sourceMaps?: SourceMapsOption, sourceMap?: SourceMapsOption, sourceMapTarget?: string, sourceFileName?: string, sourceRoot?: string, // AMD/UMD/SystemJS module naming options. getModuleId?: Function, moduleRoot?: string, moduleIds?: boolean, moduleId?: string, // Deprecate top level parserOpts parserOpts?: {}, // Deprecate top level generatorOpts generatorOpts?: {}, }; export type EnvSet = { [string]: ?T, }; export type IgnoreItem = string | Function | RegExp; export type IgnoreList = $ReadOnlyArray; export type PluginOptions = {} | void | false; export type PluginTarget = string | {} | Function; export type PluginItem = | Plugin | PluginTarget | [PluginTarget, PluginOptions] | [PluginTarget, PluginOptions, string]; export type PluginList = $ReadOnlyArray; export type SourceMapsOption = boolean | "inline" | "both"; export type SourceTypeOption = "module" | "script" | "unambiguous"; export type CompactOption = boolean | "auto"; export type RootInputSourceMapOption = {} | boolean; export type OptionsType = "arguments" | "file" | "env" | "preset"; export function validate(type: OptionsType, opts: {}): ValidatedOptions { assertNoDuplicateSourcemap(opts); Object.keys(opts).forEach(key => { if (type === "preset" && NONPRESET_VALIDATORS[key]) { throw new Error(`.${key} is not allowed in preset options`); } if (type !== "arguments" && ROOT_VALIDATORS[key]) { throw new Error(`.${key} is only allowed in root programmatic options`); } if (type === "env" && key === "env") { throw new Error(`.${key} is not allowed inside another env block`); } const validator = COMMON_VALIDATORS[key] || NONPRESET_VALIDATORS[key] || ROOT_VALIDATORS[key]; if (validator) validator(key, opts[key]); else throw buildUnknownError(key); }); return (opts: any); } function buildUnknownError(key: string) { if (removed[key]) { const { message, version = 5 } = removed[key]; throw new ReferenceError( `Using removed Babel ${version} option: .${key} - ${message}`, ); } else { // eslint-disable-next-line max-len const unknownOptErr = `Unknown option: .${key}. Check out http://babeljs.io/docs/usage/options/ for more information about options.`; throw new ReferenceError(unknownOptErr); } } function has(obj: {}, key: string) { return Object.prototype.hasOwnProperty.call(obj, key); } function assertNoDuplicateSourcemap(opts: {}): void { if (has(opts, "sourceMap") && has(opts, "sourceMaps")) { throw new Error(".sourceMap is an alias for .sourceMaps, cannot use both"); } } function assertEnvSet(key: string, value: mixed): EnvSet { const obj = assertObject(key, value); if (obj) { // Validate but don't copy the .env object in order to preserve // object identity for use during config chain processing. for (const key of Object.keys(obj)) { const env = assertObject(key, obj[key]); if (env) validate("env", env); } } return (obj: any); }