diff --git a/experimental/babel-preset-env/.eslintignore b/experimental/babel-preset-env/.eslintignore index 87bef84070..8af3c04471 100644 --- a/experimental/babel-preset-env/.eslintignore +++ b/experimental/babel-preset-env/.eslintignore @@ -1,3 +1,4 @@ /lib fixtures /data +/flow-typed diff --git a/experimental/babel-preset-env/.flowconfig b/experimental/babel-preset-env/.flowconfig new file mode 100644 index 0000000000..4a62bf66c4 --- /dev/null +++ b/experimental/babel-preset-env/.flowconfig @@ -0,0 +1,10 @@ +[ignore] +.*/lib/.* +.*/test/.* +.*/build/.* +.*/node_modules/jest-validate/.* + +[options] +strip_root=true +suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe +suppress_comment= \\(.\\|\n\\)*\\$FlowIssue diff --git a/experimental/babel-preset-env/.npmignore b/experimental/babel-preset-env/.npmignore index bf67f6570e..860048ba15 100644 --- a/experimental/babel-preset-env/.npmignore +++ b/experimental/babel-preset-env/.npmignore @@ -9,3 +9,4 @@ yarn.lock .nyc_output .vscode babel-preset-env-*.tgz +flow-typed diff --git a/experimental/babel-preset-env/flow-typed/npm/semver_v5.1.x.js b/experimental/babel-preset-env/flow-typed/npm/semver_v5.1.x.js new file mode 100644 index 0000000000..6331b8488c --- /dev/null +++ b/experimental/babel-preset-env/flow-typed/npm/semver_v5.1.x.js @@ -0,0 +1,81 @@ +// flow-typed signature: c5f918cd3de18b19a20558e6f3bbcc84 +// flow-typed version: cdd17a64e0/semver_v5.1.x/flow_>=v0.27.0 + +// List of members taken from here: https://www.npmjs.com/package/semver/#functions +// TODO support the `loose` parameter +// TODO support SemVer instances as input parameters +declare module 'semver' { + declare type Release = + 'major' | + 'premajor' | + 'minor' | + 'preminor' | + 'patch' | + 'prepatch' | + 'prerelease'; + + // The supported comparators are taken from the source here: + // https://github.com/npm/node-semver/blob/8bd070b550db2646362c9883c8d008d32f66a234/semver.js#L623 + declare type Comparator = + '===' | + '!==' | + '==' | + '=' | + '' | // Not sure why you would want this, but whatever. + '!=' | + '>' | + '>=' | + '<' | + '<='; + + declare class SemVer { + loose: ?boolean, + raw: string, + major: number, + minor: number, + patch: number, + prerelease: Array, + build: Array, + version: string, + } + + // Functions + declare function valid(v: string): string | null; + declare function inc(v: string, release: Release): string | null; + declare function major(v: string): number; + declare function minor(v: string): number; + declare function patch(v: string): number; + + // Comparison + declare function gt(v1: string, v2: string): boolean; + declare function gte(v1: string, v2: string): boolean; + declare function lt(v1: string, v2: string): boolean; + declare function lte(v1: string, v2: string): boolean; + declare function eq(v1: string, v2: string): boolean; + declare function neq(v1: string, v2: string): boolean; + declare function cmp(v1: string, comparator: Comparator, v2: string): boolean; + declare function compare(v1: string, v2: string): -1 | 0 | 1; + declare function rcompare(v1: string, v2: string): -1 | 0 | 1; + declare function diff(v1: string, v2: string): ?Release; + + // Ranges + declare function validRange(r: string): string | null; + declare function satisfies(version: string, range: string): boolean; + declare function maxSatisfying(versions: Array, range: string): string | null; + declare function gtr(version: string, range: string): boolean; + declare function ltr(version: string, range: string): boolean; + declare function outside(version: string, range: string, hilo: '>' | '<'): boolean; + + // Not explicitly documented + declare function parse(version: string): ?SemVer; + + declare class Range { + set: Array>; + + constructor(range: string, loose?: boolean): Range; + + format(): string; + test(version: string): boolean; + toString(): string; + } +} diff --git a/experimental/babel-preset-env/package.json b/experimental/babel-preset-env/package.json index 4179182b8b..6e6401065f 100644 --- a/experimental/babel-preset-env/package.json +++ b/experimental/babel-preset-env/package.json @@ -15,11 +15,12 @@ "coverage-ci": "nyc report --reporter=json && codecov -f coverage/coverage-final.json", "dev": "babel -w src -d lib", "fix": "eslint . --fix", + "flow": "flow", "format": "prettier --trailing-comma all --write \"src/*.js\" \"test/*.js\" && prettier --trailing-comma es5 --write \"scripts/*.js\"", "lint": "eslint .", "precommit": "lint-staged", "prepublish": "npm run build", - "test": "npm run build && npm run test-only", + "test": "npm run build && npm run flow && npm run test-only", "test-ci": "nyc npm run test", "test-only": "mocha ./test --compilers js:babel-register -t 10000" }, @@ -71,6 +72,7 @@ "eslint": "^3.17.1", "eslint-config-babel": "^6.0.0", "eslint-plugin-flowtype": "^2.29.1", + "flow-bin": "^0.43.0", "fs-extra": "^2.0.0", "husky": "^0.13.2", "lint-staged": "^3.3.1", diff --git a/experimental/babel-preset-env/src/targets-parser.js b/experimental/babel-preset-env/src/targets-parser.js index 1a8cbf7551..b7025a3fa4 100644 --- a/experimental/babel-preset-env/src/targets-parser.js +++ b/experimental/babel-preset-env/src/targets-parser.js @@ -1,7 +1,13 @@ +// @flow + import browserslist from "browserslist"; import semver from "semver"; import { semverify } from "./utils"; +export type Targets = { + [target: string]: string, +}; + const browserNameMap = { chrome: "chrome", edge: "edge", @@ -11,10 +17,10 @@ const browserNameMap = { safari: "safari", }; -const isBrowsersQueryValid = browsers => +const isBrowsersQueryValid = (browsers: string | Array): boolean => typeof browsers === "string" || Array.isArray(browsers); -const semverMin = (first, second) => { +const semverMin = (first: ?string, second: string): string => { return first && semver.lt(first, second) ? first : second; }; @@ -45,7 +51,7 @@ const getLowestVersions = browsers => { ); }; -const outputDecimalWarning = decimalTargets => { +const outputDecimalWarning = (decimalTargets: Array): void => { if (!decimalTargets || !decimalTargets.length) { return; } @@ -78,7 +84,7 @@ const targetParserMap = { uglify: (target, value) => [target, value === true], }; -const getTargets = (targets = {}) => { +const getTargets = (targets: Object = {}): Targets => { let targetOpts = {}; // Parse browsers target via browserslist diff --git a/experimental/babel-preset-env/src/utils.js b/experimental/babel-preset-env/src/utils.js index 54d37b8287..db59f4301c 100644 --- a/experimental/babel-preset-env/src/utils.js +++ b/experimental/babel-preset-env/src/utils.js @@ -1,9 +1,11 @@ // @flow + import semver from "semver"; +import type { Targets } from "./targets-parser"; // Convert version to a semver value. // 2.5 -> 2.5.0; 1 -> 1.0.0; -export const semverify = version => { +export const semverify = (version: string | number) => { if (typeof version === "string" && semver.valid(version)) { return version; } @@ -11,13 +13,13 @@ export const semverify = version => { const split = version.toString().split("."); while (split.length < 3) { - split.push(0); + split.push("0"); } return split.join("."); }; -export const prettifyVersion = version => { +export const prettifyVersion = (version: string | number) => { if (typeof version !== "string") { return version; } @@ -37,7 +39,7 @@ export const prettifyVersion = version => { return parts.join("."); }; -export const prettifyTargets = (targets = {}) => { +export const prettifyTargets = (targets: Targets) => { return Object.keys(targets).reduce( (results, target) => { let value = targets[target]; diff --git a/experimental/babel-preset-env/yarn.lock b/experimental/babel-preset-env/yarn.lock index a178bb3434..54a5591b1d 100644 --- a/experimental/babel-preset-env/yarn.lock +++ b/experimental/babel-preset-env/yarn.lock @@ -2637,6 +2637,10 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" +flow-bin@^0.43.0: + version "0.43.1" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.43.1.tgz#0733958b448fb8ad4b1576add7e87c31794c81bc" + flow-parser@0.40.0: version "0.40.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.40.0.tgz#b3444742189093323c4319c4fe9d35391f46bcbc"