diff --git a/lib/third-party-libs.js.flow b/lib/third-party-libs.js.flow index 9d0e0e76dd..74913a5df1 100644 --- a/lib/third-party-libs.js.flow +++ b/lib/third-party-libs.js.flow @@ -32,6 +32,20 @@ declare module "lodash/merge" { declare export default (T, Object) => T; } +declare module "semver" { + declare module.exports: { + valid(v: string): boolean; + gt(v1: string, v2: string): boolean; + lt(v1: string, v2: string): boolean; + major(v: string): number; + minor(v: string): number; + patch(v: string): number; + satisfies(v1: string, r1: string): boolean; + + intersects(r1: string, r2: string): boolean; + } +} + declare module "source-map" { declare export type SourceMap = { version: 3, diff --git a/packages/babel-core/src/transformation/file/file.js b/packages/babel-core/src/transformation/file/file.js index 47900a0374..d0da2fc6ce 100644 --- a/packages/babel-core/src/transformation/file/file.js +++ b/packages/babel-core/src/transformation/file/file.js @@ -5,6 +5,7 @@ import { NodePath, Hub, Scope } from "@babel/traverse"; import { codeFrameColumns } from "@babel/code-frame"; import traverse from "@babel/traverse"; import * as t from "@babel/types"; +import semver from "semver"; import type { NormalizedFile } from "../normalize-file"; @@ -136,6 +137,30 @@ export default class File { ); } + /** + * Check if a given helper is available in @babel/core's helper list. + * + * This _also_ allows you to pass a Babel version specifically. If the + * helper exists, but was not available for the full given range, it will be + * considered unavailable. + */ + availableHelper(name: string, versionRange: ?string) { + let minVersion; + try { + minVersion = helpers.minVersion(name); + } catch (err) { + if (err.code !== "BABEL_HELPER_UNKNOWN") throw err; + + return false; + } + + return ( + typeof versionRange !== "string" || + (!semver.intersects(`<${minVersion}`, versionRange) && + !semver.intersects(`>=8.0.0`, versionRange)) + ); + } + addHelper(name: string): Object { const declar = this.declarations[name]; if (declar) return t.cloneNode(declar); diff --git a/packages/babel-core/src/transformation/plugin-pass.js b/packages/babel-core/src/transformation/plugin-pass.js index 291fbfd1ae..6e62c42bc7 100644 --- a/packages/babel-core/src/transformation/plugin-pass.js +++ b/packages/babel-core/src/transformation/plugin-pass.js @@ -31,6 +31,10 @@ export default class PluginPass { return this._map.get(key); } + availableHelper(name: string, versionRange: ?string) { + return this.file.availableHelper(name, versionRange); + } + addHelper(name: string) { return this.file.addHelper(name); }