UNPKG

6.83 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = exports.semverMin = exports.isBrowsersQueryValid = void 0;
7
8var _browserslist = _interopRequireDefault(require("browserslist"));
9
10var _invariant = _interopRequireDefault(require("invariant"));
11
12var _semver = _interopRequireDefault(require("semver"));
13
14var _utils = require("./utils");
15
16var _builtInModules = _interopRequireDefault(require("../data/built-in-modules.json"));
17
18var _options = require("./options");
19
20function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
22const browserslistDefaults = _browserslist.default.defaults;
23const validBrowserslistTargets = [...Object.keys(_browserslist.default.data), ...Object.keys(_browserslist.default.aliases)];
24
25const objectToBrowserslist = object => {
26 return Object.keys(object).reduce((list, targetName) => {
27 if (validBrowserslistTargets.indexOf(targetName) >= 0) {
28 const targetVersion = object[targetName];
29 return list.concat(`${targetName} ${targetVersion}`);
30 }
31
32 return list;
33 }, []);
34};
35
36const validateTargetNames = targets => {
37 const validTargets = Object.keys(_options.TargetNames);
38
39 for (const target in targets) {
40 if (!_options.TargetNames[target]) {
41 throw new Error(`Invalid Option: '${target}' is not a valid target
42 Maybe you meant to use '${(0, _utils.findSuggestion)(validTargets, target)}'?`);
43 }
44 }
45};
46
47const browserNameMap = {
48 and_chr: "chrome",
49 and_ff: "firefox",
50 android: "android",
51 chrome: "chrome",
52 edge: "edge",
53 firefox: "firefox",
54 ie: "ie",
55 ie_mob: "ie",
56 ios_saf: "ios",
57 node: "node",
58 op_mob: "opera",
59 opera: "opera",
60 safari: "safari",
61 samsung: "samsung"
62};
63
64const isBrowsersQueryValid = browsers => typeof browsers === "string" || Array.isArray(browsers);
65
66exports.isBrowsersQueryValid = isBrowsersQueryValid;
67
68const validateBrowsers = browsers => {
69 (0, _invariant.default)(typeof browsers === "undefined" || isBrowsersQueryValid(browsers), `Invalid Option: '${browsers}' is not a valid browserslist query`);
70 return browsers;
71};
72
73const semverMin = (first, second) => {
74 return first && _semver.default.lt(first, second) ? first : second;
75};
76
77exports.semverMin = semverMin;
78
79const mergeBrowsers = (fromQuery, fromTarget) => {
80 return Object.keys(fromTarget).reduce((queryObj, targKey) => {
81 if (targKey !== _options.TargetNames.browsers) {
82 queryObj[targKey] = fromTarget[targKey];
83 }
84
85 return queryObj;
86 }, fromQuery);
87};
88
89const getLowestVersions = browsers => {
90 return browsers.reduce((all, browser) => {
91 const [browserName, browserVersion] = browser.split(" ");
92 const normalizedBrowserName = browserNameMap[browserName];
93
94 if (!normalizedBrowserName) {
95 return all;
96 }
97
98 try {
99 const splitVersion = browserVersion.split("-")[0].toLowerCase();
100 const isSplitUnreleased = (0, _utils.isUnreleasedVersion)(splitVersion, browserName);
101
102 if (!all[normalizedBrowserName]) {
103 all[normalizedBrowserName] = isSplitUnreleased ? splitVersion : (0, _utils.semverify)(splitVersion);
104 return all;
105 }
106
107 const version = all[normalizedBrowserName];
108 const isUnreleased = (0, _utils.isUnreleasedVersion)(version, browserName);
109
110 if (isUnreleased && isSplitUnreleased) {
111 all[normalizedBrowserName] = (0, _utils.getLowestUnreleased)(version, splitVersion, browserName);
112 } else if (isUnreleased) {
113 all[normalizedBrowserName] = (0, _utils.semverify)(splitVersion);
114 } else if (!isUnreleased && !isSplitUnreleased) {
115 const parsedBrowserVersion = (0, _utils.semverify)(splitVersion);
116 all[normalizedBrowserName] = semverMin(version, parsedBrowserVersion);
117 }
118 } catch (e) {}
119
120 return all;
121 }, {});
122};
123
124const outputDecimalWarning = decimalTargets => {
125 if (!decimalTargets || !decimalTargets.length) {
126 return;
127 }
128
129 console.log("Warning, the following targets are using a decimal version:");
130 console.log("");
131 decimalTargets.forEach(({
132 target,
133 value
134 }) => console.log(` ${target}: ${value}`));
135 console.log("");
136 console.log("We recommend using a string for minor/patch versions to avoid numbers like 6.10");
137 console.log("getting parsed as 6.1, which can lead to unexpected behavior.");
138 console.log("");
139};
140
141const semverifyTarget = (target, value) => {
142 try {
143 return (0, _utils.semverify)(value);
144 } catch (error) {
145 throw new Error(`Invalid Option: '${value}' is not a valid value for 'targets.${target}'.`);
146 }
147};
148
149const targetParserMap = {
150 __default: (target, value) => {
151 const version = (0, _utils.isUnreleasedVersion)(value, target) ? value.toLowerCase() : semverifyTarget(target, value);
152 return [target, version];
153 },
154 node: (target, value) => {
155 const parsed = value === true || value === "current" ? process.versions.node : semverifyTarget(target, value);
156 return [target, parsed];
157 }
158};
159
160const getTargets = (targets = {}, options = {}) => {
161 const targetOpts = {};
162 validateTargetNames(targets);
163
164 if (targets.esmodules) {
165 const supportsESModules = _builtInModules.default["es6.module"];
166 targets.browsers = Object.keys(supportsESModules).map(browser => `${browser} ${supportsESModules[browser]}`).join(", ");
167 }
168
169 const browsersquery = validateBrowsers(targets.browsers);
170 const hasTargets = Object.keys(targets).length > 0;
171 const shouldParseBrowsers = !!targets.browsers;
172 const shouldSearchForConfig = !options.ignoreBrowserslistConfig && !hasTargets;
173
174 if (shouldParseBrowsers || shouldSearchForConfig) {
175 if (!hasTargets) {
176 _browserslist.default.defaults = objectToBrowserslist(targets);
177 }
178
179 const browsers = (0, _browserslist.default)(browsersquery, {
180 path: options.configPath,
181 mobileToDesktop: true
182 });
183 const queryBrowsers = getLowestVersions(browsers);
184 targets = mergeBrowsers(queryBrowsers, targets);
185 _browserslist.default.defaults = browserslistDefaults;
186 }
187
188 const parsed = Object.keys(targets).filter(value => value !== _options.TargetNames.esmodules).sort().reduce((results, target) => {
189 if (target !== _options.TargetNames.browsers) {
190 const value = targets[target];
191
192 if (typeof value === "number" && value % 1 !== 0) {
193 results.decimalWarnings.push({
194 target,
195 value
196 });
197 }
198
199 const parser = targetParserMap[target] || targetParserMap.__default;
200 const [parsedTarget, parsedValue] = parser(target, value);
201
202 if (parsedValue) {
203 results.targets[parsedTarget] = parsedValue;
204 }
205 }
206
207 return results;
208 }, {
209 targets: targetOpts,
210 decimalWarnings: []
211 });
212 outputDecimalWarning(parsed.decimalWarnings);
213 return parsed.targets;
214};
215
216var _default = getTargets;
217exports.default = _default;
\No newline at end of file