|
|
- 'use strict';
- const { coerce, lt, lte } = require('semver');
- const browserslist = require('browserslist');
- const data = require('./data');
- const getModulesListForTargetVersion = require('./get-modules-list-for-target-version');
- const has = Function.call.bind({}.hasOwnProperty);
-
- const mapping = new Map([
- ['ios_saf', 'ios'],
- ['and_chr', 'chrome'],
- ['and_ff', 'firefox'],
- ]);
-
- const validTargets = new Set([
- 'android',
- 'chrome',
- 'edge',
- 'electron',
- 'firefox',
- 'ie',
- 'ios',
- 'node',
- 'opera',
- 'phantom',
- 'safari',
- 'samsung',
- ]);
-
- function coercedLte(a, b) {
- return lte(coerce(a), coerce(b));
- }
-
- function coercedLt(a, b) {
- return lt(coerce(a), coerce(b));
- }
-
- function normalizeBrowsersList(list) {
- return list.map(it => {
- let [engine, version] = it.split(' ');
- if (mapping.has(engine)) engine = mapping.get(engine);
- else if (engine === 'android' && !coercedLte(version, '4.4.4')) engine = 'chrome';
- return [engine, version];
- }).filter(([engine]) => validTargets.has(engine));
- }
-
- function reduceByMinVersion(list) {
- const targets = new Map();
- for (const [engine, version] of list) {
- if (!targets.has(engine) || coercedLte(version, targets.get(engine))) {
- targets.set(engine, version);
- }
- }
- return targets;
- }
-
- function checkModule(name, targets) {
- if (!has(data, name)) throw new TypeError(`Incorrect module: ${ name }`);
- const requirements = data[name];
- const result = {
- required: false,
- targets: {},
- };
- for (const [engine, version] of targets) {
- if (!has(requirements, engine) || coercedLt(version, requirements[engine])) {
- result.required = true;
- result.targets[engine] = version;
- }
- }
- return result;
- }
-
- function compat({ targets, filter, version }) {
- const list = browserslist(targets);
- const engines = normalizeBrowsersList(list);
- const reducedTargets = reduceByMinVersion(engines);
-
- const result = {
- list: [],
- targets: {},
- };
-
- let modules = Array.isArray(filter) ? filter : Object.keys(data);
-
- if (filter instanceof RegExp) modules = modules.filter(it => filter.test(it));
- else if (typeof filter == 'string') modules = modules.filter(it => it.startsWith(filter));
-
- if (version) {
- const availableModules = new Set(getModulesListForTargetVersion(version));
- modules = modules.filter(name => availableModules.has(name));
- }
-
- modules.forEach(key => {
- const check = checkModule(key, reducedTargets);
- if (check.required) {
- result.list.push(key);
- result.targets[key] = check.targets;
- }
- });
-
- return result;
- }
-
- module.exports = compat;
- module.exports.compat = compat;
- module.exports.getModulesListForTargetVersion = getModulesListForTargetVersion;
|