diff options
author | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 |
---|---|---|
committer | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 |
commit | 5d309ff52cd399a6b71968a6b9a70c8ac0b98981 (patch) | |
tree | 360f7eb50f956e2367ef38fa1fc6ac7ac5258042 /node_modules/browserslist | |
parent | b500a50f1b97d93c98b36ed9a980f8188d648147 (diff) | |
download | LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.tar.gz LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.zip |
Added node_modules for the updating to work properly.
Diffstat (limited to 'node_modules/browserslist')
-rw-r--r-- | node_modules/browserslist/LICENSE | 20 | ||||
-rw-r--r-- | node_modules/browserslist/README.md | 66 | ||||
-rw-r--r-- | node_modules/browserslist/browser.js | 50 | ||||
-rwxr-xr-x | node_modules/browserslist/cli.js | 152 | ||||
-rw-r--r-- | node_modules/browserslist/error.d.ts | 7 | ||||
-rw-r--r-- | node_modules/browserslist/error.js | 12 | ||||
-rw-r--r-- | node_modules/browserslist/index.d.ts | 176 | ||||
-rw-r--r-- | node_modules/browserslist/index.js | 1230 | ||||
-rw-r--r-- | node_modules/browserslist/node.js | 393 | ||||
-rw-r--r-- | node_modules/browserslist/package.json | 35 | ||||
-rw-r--r-- | node_modules/browserslist/update-db.js | 317 |
11 files changed, 2458 insertions, 0 deletions
diff --git a/node_modules/browserslist/LICENSE b/node_modules/browserslist/LICENSE new file mode 100644 index 0000000..90b6b91 --- /dev/null +++ b/node_modules/browserslist/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2014 Andrey Sitnik <andrey@sitnik.ru> and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/browserslist/README.md b/node_modules/browserslist/README.md new file mode 100644 index 0000000..b1cde15 --- /dev/null +++ b/node_modules/browserslist/README.md @@ -0,0 +1,66 @@ +# Browserslist [![Cult Of Martians][cult-img]][cult] + +<img width="120" height="120" alt="Browserslist logo by Anton Lovchikov" + src="https://browserslist.github.io/browserslist/logo.svg" align="right"> + +The config to share target browsers and Node.js versions between different +front-end tools. It is used in: + +* [Autoprefixer] +* [Babel] +* [postcss-preset-env] +* [eslint-plugin-compat] +* [stylelint-no-unsupported-browser-features] +* [postcss-normalize] +* [obsolete-webpack-plugin] + +All tools will find target browsers automatically, +when you add the following to `package.json`: + +```json + "browserslist": [ + "defaults", + "not IE 11", + "maintained node versions" + ] +``` + +Or in `.browserslistrc` config: + +```yaml +# Browsers that we support + +defaults +not IE 11 +maintained node versions +``` + +Developers set their version lists using queries like `last 2 versions` +to be free from updating versions manually. +Browserslist will use [`caniuse-lite`] with [Can I Use] data for this queries. + +Browserslist will take queries from tool option, +`browserslist` config, `.browserslistrc` config, +`browserslist` section in `package.json` or environment variables. + +[cult-img]: https://cultofmartians.com/assets/badges/badge.svg +[cult]: https://cultofmartians.com/done.html + +<a href="https://evilmartians.com/?utm_source=browserslist"> + <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" + alt="Sponsored by Evil Martians" width="236" height="54"> +</a> + +[stylelint-no-unsupported-browser-features]: https://github.com/ismay/stylelint-no-unsupported-browser-features +[eslint-plugin-compat]: https://github.com/amilajack/eslint-plugin-compat +[Browserslist Example]: https://github.com/browserslist/browserslist-example +[postcss-preset-env]: https://github.com/jonathantneal/postcss-preset-env +[postcss-normalize]: https://github.com/jonathantneal/postcss-normalize +[`caniuse-lite`]: https://github.com/ben-eb/caniuse-lite +[Autoprefixer]: https://github.com/postcss/autoprefixer +[Can I Use]: https://caniuse.com/ +[Babel]: https://github.com/babel/babel/tree/master/packages/babel-preset-env +[obsolete-webpack-plugin]: https://github.com/ElemeFE/obsolete-webpack-plugin + +## Docs +Read **[full docs](https://github.com/browserslist/browserslist#readme)** on GitHub. diff --git a/node_modules/browserslist/browser.js b/node_modules/browserslist/browser.js new file mode 100644 index 0000000..4e9d8de --- /dev/null +++ b/node_modules/browserslist/browser.js @@ -0,0 +1,50 @@ +var BrowserslistError = require('./error') + +function noop() {} + +module.exports = { + loadQueries: function loadQueries() { + throw new BrowserslistError( + 'Sharable configs are not supported in client-side build of Browserslist' + ) + }, + + getStat: function getStat(opts) { + return opts.stats + }, + + loadConfig: function loadConfig(opts) { + if (opts.config) { + throw new BrowserslistError( + 'Browserslist config are not supported in client-side build' + ) + } + }, + + loadCountry: function loadCountry() { + throw new BrowserslistError( + 'Country statistics are not supported ' + + 'in client-side build of Browserslist' + ) + }, + + loadFeature: function loadFeature() { + throw new BrowserslistError( + 'Supports queries are not available in client-side build of Browserslist' + ) + }, + + currentNode: function currentNode(resolve, context) { + return resolve(['maintained node versions'], context)[0] + }, + + parseConfig: noop, + + readConfig: noop, + + findConfig: noop, + + clearCaches: noop, + + oldDataWarning: noop +} diff --git a/node_modules/browserslist/cli.js b/node_modules/browserslist/cli.js new file mode 100755 index 0000000..e4a7076 --- /dev/null +++ b/node_modules/browserslist/cli.js @@ -0,0 +1,152 @@ +#!/usr/bin/env node + +var fs = require('fs') + +var browserslist = require('./') +var updateDb = require('./update-db') +var pkg = require('./package.json') + +var args = process.argv.slice(2) + +var USAGE = + 'Usage:\n' + + ' npx browserslist\n' + + ' npx browserslist "QUERIES"\n' + + ' npx browserslist --json "QUERIES"\n' + + ' npx browserslist --config="path/to/browserlist/file"\n' + + ' npx browserslist --coverage "QUERIES"\n' + + ' npx browserslist --coverage=US "QUERIES"\n' + + ' npx browserslist --coverage=US,RU,global "QUERIES"\n' + + ' npx browserslist --env="environment name defined in config"\n' + + ' npx browserslist --stats="path/to/browserlist/stats/file"\n' + + ' npx browserslist --mobile-to-desktop\n' + + ' npx browserslist --ignore-unknown-versions\n' + + ' npx browserslist --update-db' + +function isArg(arg) { + return args.some(function (str) { + return str === arg || str.indexOf(arg + '=') === 0 + }) +} + +function error(msg) { + process.stderr.write('browserslist: ' + msg + '\n') + process.exit(1) +} + +if (isArg('--help') || isArg('-h')) { + process.stdout.write(pkg.description + '.\n\n' + USAGE + '\n') +} else if (isArg('--version') || isArg('-v')) { + process.stdout.write('browserslist ' + pkg.version + '\n') +} else if (isArg('--update-db')) { + /* c8 ignore next 3 */ + updateDb(function (str) { + process.stdout.write(str) + }) +} else { + var mode = 'browsers' + var opts = {} + var queries + var areas + + for (var i = 0; i < args.length; i++) { + if (args[i][0] !== '-') { + queries = args[i].replace(/^["']|["']$/g, '') + continue + } + + var arg = args[i].split('=') + var name = arg[0] + var value = arg[1] + + if (value) value = value.replace(/^["']|["']$/g, '') + + if (name === '--config' || name === '-b') { + opts.config = value + } else if (name === '--env' || name === '-e') { + opts.env = value + } else if (name === '--stats' || name === '-s') { + opts.stats = value + } else if (name === '--coverage' || name === '-c') { + if (mode !== 'json') mode = 'coverage' + if (value) { + areas = value.split(',') + } else { + areas = ['global'] + } + } else if (name === '--json') { + mode = 'json' + } else if (name === '--mobile-to-desktop') { + /* c8 ignore next */ + opts.mobileToDesktop = true + } else if (name === '--ignore-unknown-versions') { + /* c8 ignore next */ + opts.ignoreUnknownVersions = true + } else { + error('Unknown arguments ' + args[i] + '.\n\n' + USAGE) + } + } + + var browsers + try { + browsers = browserslist(queries, opts) + } catch (e) { + if (e.name === 'BrowserslistError') { + error(e.message) + } else /* c8 ignore start */ { + throw e + } /* c8 ignore end */ + } + + var coverage + if (mode === 'browsers') { + browsers.forEach(function (browser) { + process.stdout.write(browser + '\n') + }) + } else if (areas) { + coverage = areas.map(function (area) { + var stats + if (area !== 'global') { + stats = area + } else if (opts.stats) { + stats = JSON.parse(fs.readFileSync(opts.stats)) + } + var result = browserslist.coverage(browsers, stats) + var round = Math.round(result * 100) / 100.0 + + return [area, round] + }) + + if (mode === 'coverage') { + var prefix = 'These browsers account for ' + process.stdout.write(prefix) + coverage.forEach(function (data, index) { + var area = data[0] + var round = data[1] + var end = 'globally' + if (area && area !== 'global') { + end = 'in the ' + area.toUpperCase() + } else if (opts.stats) { + end = 'in custom statistics' + } + + if (index !== 0) { + process.stdout.write(prefix.replace(/./g, ' ')) + } + + process.stdout.write(round + '% of all users ' + end + '\n') + }) + } + } + + if (mode === 'json') { + var data = { browsers: browsers } + if (coverage) { + data.coverage = coverage.reduce(function (object, j) { + object[j[0]] = j[1] + return object + }, {}) + } + process.stdout.write(JSON.stringify(data, null, ' ') + '\n') + } +} diff --git a/node_modules/browserslist/error.d.ts b/node_modules/browserslist/error.d.ts new file mode 100644 index 0000000..12ff921 --- /dev/null +++ b/node_modules/browserslist/error.d.ts @@ -0,0 +1,7 @@ +declare class BrowserslistError extends Error { + constructor(message: any) + name: 'BrowserslistError' + browserslist: true +} + +export = BrowserslistError diff --git a/node_modules/browserslist/error.js b/node_modules/browserslist/error.js new file mode 100644 index 0000000..6e5da7a --- /dev/null +++ b/node_modules/browserslist/error.js @@ -0,0 +1,12 @@ +function BrowserslistError(message) { + this.name = 'BrowserslistError' + this.message = message + this.browserslist = true + if (Error.captureStackTrace) { + Error.captureStackTrace(this, BrowserslistError) + } +} + +BrowserslistError.prototype = Error.prototype + +module.exports = BrowserslistError diff --git a/node_modules/browserslist/index.d.ts b/node_modules/browserslist/index.d.ts new file mode 100644 index 0000000..4ca9cd9 --- /dev/null +++ b/node_modules/browserslist/index.d.ts @@ -0,0 +1,176 @@ +/** + * Return array of browsers by selection queries. + * + * ```js + * browserslist('IE >= 10, IE 8') //=> ['ie 11', 'ie 10', 'ie 8'] + * ``` + * + * @param queries Browser queries. + * @returns Array with browser names in Can I Use. + */ +declare function browserslist( + queries?: string | readonly string[] | null, + opts?: browserslist.Options +): string[] + +declare namespace browserslist { + interface Options { + /** + * Path to processed file. It will be used to find config files. + */ + path?: string | false + /** + * Processing environment. It will be used to take right queries + * from config file. + */ + env?: string + /** + * Custom browser usage statistics for "> 1% in my stats" query. + */ + stats?: Stats | string + /** + * Path to config file with queries. + */ + config?: string + /** + * Do not throw on unknown version in direct query. + */ + ignoreUnknownVersions?: boolean + /** + * Throw a error if env is not found. + */ + throwOnMissing?: boolean + /** + * Disable security checks for extend query. + */ + dangerousExtend?: boolean + /** + * Alias mobile browsers to the desktop version when Can I Use + * doesn’t have data about the specified version. + */ + mobileToDesktop?: boolean + } + + type Config = { + defaults: string[] + [section: string]: string[] | undefined + } + + interface Stats { + [browser: string]: { + [version: string]: number + } + } + + /** + * Browser names aliases. + */ + let aliases: { + [alias: string]: string | undefined + } + + /** + * Aliases to work with joined versions like `ios_saf 7.0-7.1`. + */ + let versionAliases: { + [browser: string]: + | { + [version: string]: string | undefined + } + | undefined + } + + /** + * Can I Use only provides a few versions for some browsers (e.g. `and_chr`). + * + * Fallback to a similar browser for unknown versions. + */ + let desktopNames: { + [browser: string]: string | undefined + } + + let data: { + [browser: string]: + | { + name: string + versions: string[] + released: string[] + releaseDate: { + [version: string]: number | undefined | null + } + } + | undefined + } + + interface Usage { + [version: string]: number + } + + let usage: { + global?: Usage + custom?: Usage | null + [country: string]: Usage | undefined | null + } + + let cache: { + [feature: string]: { + [name: string]: 'y' | 'n' + } + } + + /** + * Default browsers query + */ + let defaults: readonly string[] + + /** + * Which statistics should be used. Country code or custom statistics. + * Pass `"my stats"` to load statistics from `Browserslist` files. + */ + type StatsOptions = string | 'my stats' | Stats | { dataByBrowser: Stats } + + /** + * Return browsers market coverage. + * + * ```js + * browserslist.coverage(browserslist('> 1% in US'), 'US') //=> 83.1 + * ``` + * + * @param browsers Browsers names in Can I Use. + * @param stats Which statistics should be used. + * @returns Total market coverage for all selected browsers. + */ + function coverage(browsers: readonly string[], stats?: StatsOptions): number + + function clearCaches(): void + + function parseConfig(string: string): Config + + function readConfig(file: string): Config + + function findConfig(...pathSegments: string[]): Config | undefined + + interface LoadConfigOptions { + config?: string + path?: string + env?: string + } + + function loadConfig(options: LoadConfigOptions): string[] | undefined +} + +declare global { + namespace NodeJS { + interface ProcessEnv { + BROWSERSLIST?: string + BROWSERSLIST_CONFIG?: string + BROWSERSLIST_DANGEROUS_EXTEND?: string + BROWSERSLIST_DISABLE_CACHE?: string + BROWSERSLIST_ENV?: string + BROWSERSLIST_IGNORE_OLD_DATA?: string + BROWSERSLIST_STATS?: string + } + } +} + +export = browserslist diff --git a/node_modules/browserslist/index.js b/node_modules/browserslist/index.js new file mode 100644 index 0000000..baefcb4 --- /dev/null +++ b/node_modules/browserslist/index.js @@ -0,0 +1,1230 @@ +var jsReleases = require('node-releases/data/processed/envs.json') +var agents = require('caniuse-lite/dist/unpacker/agents').agents +var jsEOL = require('node-releases/data/release-schedule/release-schedule.json') +var path = require('path') +var e2c = require('electron-to-chromium/versions') + +var BrowserslistError = require('./error') +var env = require('./node') // Will load browser.js in webpack + +var YEAR = 365.259641 * 24 * 60 * 60 * 1000 +var ANDROID_EVERGREEN_FIRST = 37 + +var QUERY_OR = 1 +var QUERY_AND = 2 + +function isVersionsMatch(versionA, versionB) { + return (versionA + '.').indexOf(versionB + '.') === 0 +} + +function isEolReleased(name) { + var version = name.slice(1) + return jsReleases.some(function (i) { + return isVersionsMatch(i.version, version) + }) +} + +function normalize(versions) { + return versions.filter(function (version) { + return typeof version === 'string' + }) +} + +function normalizeElectron(version) { + var versionToUse = version + if (version.split('.').length === 3) { + versionToUse = version.split('.').slice(0, -1).join('.') + } + return versionToUse +} + +function nameMapper(name) { + return function mapName(version) { + return name + ' ' + version + } +} + +function getMajor(version) { + return parseInt(version.split('.')[0]) +} + +function getMajorVersions(released, number) { + if (released.length === 0) return [] + var majorVersions = uniq(released.map(getMajor)) + var minimum = majorVersions[majorVersions.length - number] + if (!minimum) { + return released + } + var selected = [] + for (var i = released.length - 1; i >= 0; i--) { + if (minimum > getMajor(released[i])) break + selected.unshift(released[i]) + } + return selected +} + +function uniq(array) { + var filtered = [] + for (var i = 0; i < array.length; i++) { + if (filtered.indexOf(array[i]) === -1) filtered.push(array[i]) + } + return filtered +} + +// Helpers + +function fillUsage(result, name, data) { + for (var i in data) { + result[name + ' ' + i] = data[i] + } +} + +function generateFilter(sign, version) { + version = parseFloat(version) + if (sign === '>') { + return function (v) { + return parseFloat(v) > version + } + } else if (sign === '>=') { + return function (v) { + return parseFloat(v) >= version + } + } else if (sign === '<') { + return function (v) { + return parseFloat(v) < version + } + } else { + return function (v) { + return parseFloat(v) <= version + } + } +} + +function generateSemverFilter(sign, version) { + version = version.split('.').map(parseSimpleInt) + version[1] = version[1] || 0 + version[2] = version[2] || 0 + if (sign === '>') { + return function (v) { + v = v.split('.').map(parseSimpleInt) + return compareSemver(v, version) > 0 + } + } else if (sign === '>=') { + return function (v) { + v = v.split('.').map(parseSimpleInt) + return compareSemver(v, version) >= 0 + } + } else if (sign === '<') { + return function (v) { + v = v.split('.').map(parseSimpleInt) + return compareSemver(version, v) > 0 + } + } else { + return function (v) { + v = v.split('.').map(parseSimpleInt) + return compareSemver(version, v) >= 0 + } + } +} + +function parseSimpleInt(x) { + return parseInt(x) +} + +function compare(a, b) { + if (a < b) return -1 + if (a > b) return +1 + return 0 +} + +function compareSemver(a, b) { + return ( + compare(parseInt(a[0]), parseInt(b[0])) || + compare(parseInt(a[1] || '0'), parseInt(b[1] || '0')) || + compare(parseInt(a[2] || '0'), parseInt(b[2] || '0')) + ) +} + +// this follows the npm-like semver behavior +function semverFilterLoose(operator, range) { + range = range.split('.').map(parseSimpleInt) + if (typeof range[1] === 'undefined') { + range[1] = 'x' + } + // ignore any patch version because we only return minor versions + // range[2] = 'x' + switch (operator) { + case '<=': + return function (version) { + version = version.split('.').map(parseSimpleInt) + return compareSemverLoose(version, range) <= 0 + } + case '>=': + default: + return function (version) { + version = version.split('.').map(parseSimpleInt) + return compareSemverLoose(version, range) >= 0 + } + } +} + +// this follows the npm-like semver behavior +function compareSemverLoose(version, range) { + if (version[0] !== range[0]) { + return version[0] < range[0] ? -1 : +1 + } + if (range[1] === 'x') { + return 0 + } + if (version[1] !== range[1]) { + return version[1] < range[1] ? -1 : +1 + } + return 0 +} + +function resolveVersion(data, version) { + if (data.versions.indexOf(version) !== -1) { + return version + } else if (browserslist.versionAliases[data.name][version]) { + return browserslist.versionAliases[data.name][version] + } else { + return false + } +} + +function normalizeVersion(data, version) { + var resolved = resolveVersion(data, version) + if (resolved) { + return resolved + } else if (data.versions.length === 1) { + return data.versions[0] + } else { + return false + } +} + +function filterByYear(since, context) { + since = since / 1000 + return Object.keys(agents).reduce(function (selected, name) { + var data = byName(name, context) + if (!data) return selected + var versions = Object.keys(data.releaseDate).filter(function (v) { + var date = data.releaseDate[v] + return date !== null && date >= since + }) + return selected.concat(versions.map(nameMapper(data.name))) + }, []) +} + +function cloneData(data) { + return { + name: data.name, + versions: data.versions, + released: data.released, + releaseDate: data.releaseDate + } +} + +function mapVersions(data, map) { + data.versions = data.versions.map(function (i) { + return map[i] || i + }) + data.released = data.versions.map(function (i) { + return map[i] || i + }) + var fixedDate = {} + for (var i in data.releaseDate) { + fixedDate[map[i] || i] = data.releaseDate[i] + } + data.releaseDate = fixedDate + return data +} + +function byName(name, context) { + name = name.toLowerCase() + name = browserslist.aliases[name] || name + if (context.mobileToDesktop && browserslist.desktopNames[name]) { + var desktop = browserslist.data[browserslist.desktopNames[name]] + if (name === 'android') { + return normalizeAndroidData(cloneData(browserslist.data[name]), desktop) + } else { + var cloned = cloneData(desktop) + cloned.name = name + if (name === 'op_mob') { + cloned = mapVersions(cloned, { '10.0-10.1': '10' }) + } + return cloned + } + } + return browserslist.data[name] +} + +function normalizeAndroidVersions(androidVersions, chromeVersions) { + var firstEvergreen = ANDROID_EVERGREEN_FIRST + var last = chromeVersions[chromeVersions.length - 1] + return androidVersions + .filter(function (version) { + return /^(?:[2-4]\.|[34]$)/.test(version) + }) + .concat(chromeVersions.slice(firstEvergreen - last - 1)) +} + +function normalizeAndroidData(android, chrome) { + android.released = normalizeAndroidVersions(android.released, chrome.released) + android.versions = normalizeAndroidVersions(android.versions, chrome.versions) + return android +} + +function checkName(name, context) { + var data = byName(name, context) + if (!data) throw new BrowserslistError('Unknown browser ' + name) + return data +} + +function unknownQuery(query) { + return new BrowserslistError( + 'Unknown browser query `' + + query + + '`. ' + + 'Maybe you are using old Browserslist or made typo in query.' + ) +} + +function filterAndroid(list, versions, context) { + if (context.mobileToDesktop) return list + var released = browserslist.data.android.released + var last = released[released.length - 1] + var diff = last - ANDROID_EVERGREEN_FIRST - versions + if (diff > 0) { + return list.slice(-1) + } else { + return list.slice(diff - 1) + } +} + +/** + * Resolves queries into a browser list. + * @param {string|string[]} queries Queries to combine. + * Either an array of queries or a long string of queries. + * @param {object} [context] Optional arguments to + * the select function in `queries`. + * @returns {string[]} A list of browsers + */ +function resolve(queries, context) { + if (Array.isArray(queries)) { + queries = flatten(queries.map(parse)) + } else { + queries = parse(queries) + } + + return queries.reduce(function (result, query, index) { + var selection = query.queryString + + var isExclude = selection.indexOf('not ') === 0 + if (isExclude) { + if (index === 0) { + throw new BrowserslistError( + 'Write any browsers query (for instance, `defaults`) ' + + 'before `' + + selection + + '`' + ) + } + selection = selection.slice(4) + } + + for (var i = 0; i < QUERIES.length; i++) { + var type = QUERIES[i] + var match = selection.match(type.regexp) + if (match) { + var args = [context].concat(match.slice(1)) + var array = type.select.apply(browserslist, args).map(function (j) { + var parts = j.split(' ') + if (parts[1] === '0') { + return parts[0] + ' ' + byName(parts[0], context).versions[0] + } else { + return j + } + }) + + switch (query.type) { + case QUERY_AND: + if (isExclude) { + return result.filter(function (j) { + return array.indexOf(j) === -1 + }) + } else { + return result.filter(function (j) { + return array.indexOf(j) !== -1 + }) + } + case QUERY_OR: + default: + if (isExclude) { + var filter = {} + array.forEach(function (j) { + filter[j] = true + }) + return result.filter(function (j) { + return !filter[j] + }) + } + return result.concat(array) + } + } + } + + throw unknownQuery(selection) + }, []) +} + +var cache = {} + +/** + * Return array of browsers by selection queries. + * + * @param {(string|string[])} [queries=browserslist.defaults] Browser queries. + * @param {object} [opts] Options. + * @param {string} [opts.path="."] Path to processed file. + * It will be used to find config files. + * @param {string} [opts.env="production"] Processing environment. + * It will be used to take right + * queries from config file. + * @param {string} [opts.config] Path to config file with queries. + * @param {object} [opts.stats] Custom browser usage statistics + * for "> 1% in my stats" query. + * @param {boolean} [opts.ignoreUnknownVersions=false] Do not throw on unknown + * version in direct query. + * @param {boolean} [opts.dangerousExtend] Disable security checks + * for extend query. + * @param {boolean} [opts.throwOnMissing] Throw error on missing env. + * @param {boolean} [opts.mobileToDesktop] Alias mobile browsers to the desktop + * version when Can I Use doesn't have + * data about the specified version. + * @returns {string[]} Array with browser names in Can I Use. + * + * @example + * browserslist('IE >= 10, IE 8') //=> ['ie 11', 'ie 10', 'ie 8'] + */ +function browserslist(queries, opts) { + if (typeof opts === 'undefined') opts = {} + + if (typeof opts.path === 'undefined') { + opts.path = path.resolve ? path.resolve('.') : '.' + } + + if (typeof queries === 'undefined' || queries === null) { + var config = browserslist.loadConfig(opts) + if (config) { + queries = config + } else { + queries = browserslist.defaults + } + } + + if (!(typeof queries === 'string' || Array.isArray(queries))) { + throw new BrowserslistError( + 'Browser queries must be an array or string. Got ' + typeof queries + '.' + ) + } + + var context = { + ignoreUnknownVersions: opts.ignoreUnknownVersions, + dangerousExtend: opts.dangerousExtend, + mobileToDesktop: opts.mobileToDesktop, + path: opts.path, + env: opts.env + } + + env.oldDataWarning(browserslist.data) + var stats = env.getStat(opts, browserslist.data) + if (stats) { + context.customUsage = {} + for (var browser in stats) { + fillUsage(context.customUsage, browser, stats[browser]) + } + } + + var cacheKey = JSON.stringify([queries, context]) + if (cache[cacheKey]) return cache[cacheKey] + + var result = uniq(resolve(queries, context)).sort(function (name1, name2) { + name1 = name1.split(' ') + name2 = name2.split(' ') + if (name1[0] === name2[0]) { + // assumptions on caniuse data + // 1) version ranges never overlaps + // 2) if version is not a range, it never contains `-` + var version1 = name1[1].split('-')[0] + var version2 = name2[1].split('-')[0] + return compareSemver(version2.split('.'), version1.split('.')) + } else { + return compare(name1[0], name2[0]) + } + }) + if (!process.env.BROWSERSLIST_DISABLE_CACHE) { + cache[cacheKey] = result + } + return result +} + +function parse(queries) { + var qs = [] + do { + queries = doMatch(queries, qs) + } while (queries) + return qs +} + +function doMatch(string, qs) { + var or = /^(?:,\s*|\s+or\s+)(.*)/i + var and = /^\s+and\s+(.*)/i + + return find(string, function (parsed, n, max) { + if (and.test(parsed)) { + qs.unshift({ type: QUERY_AND, queryString: parsed.match(and)[1] }) + return true + } else if (or.test(parsed)) { + qs.unshift({ type: QUERY_OR, queryString: parsed.match(or)[1] }) + return true + } else if (n === max) { + qs.unshift({ type: QUERY_OR, queryString: parsed.trim() }) + return true + } + return false + }) +} + +function find(string, predicate) { + for (var n = 1, max = string.length; n <= max; n++) { + var parsed = string.substr(-n, n) + if (predicate(parsed, n, max)) { + return string.slice(0, -n) + } + } + return '' +} + +function flatten(array) { + if (!Array.isArray(array)) return [array] + return array.reduce(function (a, b) { + return a.concat(flatten(b)) + }, []) +} + +// Will be filled by Can I Use data below +browserslist.cache = {} +browserslist.data = {} +browserslist.usage = { + global: {}, + custom: null +} + +// Default browsers query +browserslist.defaults = ['> 0.5%', 'last 2 versions', 'Firefox ESR', 'not dead'] + +// Browser names aliases +browserslist.aliases = { + fx: 'firefox', + ff: 'firefox', + ios: 'ios_saf', + explorer: 'ie', + blackberry: 'bb', + explorermobile: 'ie_mob', + operamini: 'op_mini', + operamobile: 'op_mob', + chromeandroid: 'and_chr', + firefoxandroid: 'and_ff', + ucandroid: 'and_uc', + qqandroid: 'and_qq' +} + +// Can I Use only provides a few versions for some browsers (e.g. and_chr). +// Fallback to a similar browser for unknown versions +browserslist.desktopNames = { + and_chr: 'chrome', + and_ff: 'firefox', + ie_mob: 'ie', + op_mob: 'opera', + android: 'chrome' // has extra processing logic +} + +// Aliases to work with joined versions like `ios_saf 7.0-7.1` +browserslist.versionAliases = {} + +browserslist.clearCaches = env.clearCaches +browserslist.parseConfig = env.parseConfig +browserslist.readConfig = env.readConfig +browserslist.findConfig = env.findConfig +browserslist.loadConfig = env.loadConfig + +/** + * Return browsers market coverage. + * + * @param {string[]} browsers Browsers names in Can I Use. + * @param {string|object} [stats="global"] Which statistics should be used. + * Country code or custom statistics. + * Pass `"my stats"` to load statistics + * from Browserslist files. + * + * @return {number} Total market coverage for all selected browsers. + * + * @example + * browserslist.coverage(browserslist('> 1% in US'), 'US') //=> 83.1 + */ +browserslist.coverage = function (browsers, stats) { + var data + if (typeof stats === 'undefined') { + data = browserslist.usage.global + } else if (stats === 'my stats') { + var opts = {} + opts.path = path.resolve ? path.resolve('.') : '.' + var customStats = env.getStat(opts) + if (!customStats) { + throw new BrowserslistError('Custom usage statistics was not provided') + } + data = {} + for (var browser in customStats) { + fillUsage(data, browser, customStats[browser]) + } + } else if (typeof stats === 'string') { + if (stats.length > 2) { + stats = stats.toLowerCase() + } else { + stats = stats.toUpperCase() + } + env.loadCountry(browserslist.usage, stats, browserslist.data) + data = browserslist.usage[stats] + } else { + if ('dataByBrowser' in stats) { + stats = stats.dataByBrowser + } + data = {} + for (var name in stats) { + for (var version in stats[name]) { + data[name + ' ' + version] = stats[name][version] + } + } + } + + return browsers.reduce(function (all, i) { + var usage = data[i] + if (usage === undefined) { + usage = data[i.replace(/ \S+$/, ' 0')] + } + return all + (usage || 0) + }, 0) +} + +function nodeQuery(context, version) { + var nodeReleases = jsReleases.filter(function (i) { + return i.name === 'nodejs' + }) + var matched = nodeReleases.filter(function (i) { + return isVersionsMatch(i.version, version) + }) + if (matched.length === 0) { + if (context.ignoreUnknownVersions) { + return [] + } else { + throw new BrowserslistError('Unknown version ' + version + ' of Node.js') + } + } + return ['node ' + matched[matched.length - 1].version] +} + +function sinceQuery(context, year, month, date) { + year = parseInt(year) + month = parseInt(month || '01') - 1 + date = parseInt(date || '01') + return filterByYear(Date.UTC(year, month, date, 0, 0, 0), context) +} + +function coverQuery(context, coverage, statMode) { + coverage = parseFloat(coverage) + var usage = browserslist.usage.global + if (statMode) { + if (statMode.match(/^my\s+stats$/i)) { + if (!context.customUsage) { + throw new BrowserslistError('Custom usage statistics was not provided') + } + usage = context.customUsage + } else { + var place + if (statMode.length === 2) { + place = statMode.toUpperCase() + } else { + place = statMode.toLowerCase() + } + env.loadCountry(browserslist.usage, place, browserslist.data) + usage = browserslist.usage[place] + } + } + var versions = Object.keys(usage).sort(function (a, b) { + return usage[b] - usage[a] + }) + var coveraged = 0 + var result = [] + var version + for (var i = 0; i < versions.length; i++) { + version = versions[i] + if (usage[version] === 0) break + coveraged += usage[version] + result.push(version) + if (coveraged >= coverage) break + } + return result +} + +var QUERIES = [ + { + regexp: /^last\s+(\d+)\s+major\s+versions?$/i, + select: function (context, versions) { + return Object.keys(agents).reduce(function (selected, name) { + var data = byName(name, context) + if (!data) return selected + var list = getMajorVersions(data.released, versions) + list = list.map(nameMapper(data.name)) + if (data.name === 'android') { + list = filterAndroid(list, versions, context) + } + return selected.concat(list) + }, []) + } + }, + { + regexp: /^last\s+(\d+)\s+versions?$/i, + select: function (context, versions) { + return Object.keys(agents).reduce(function (selected, name) { + var data = byName(name, context) + if (!data) return selected + var list = data.released.slice(-versions) + list = list.map(nameMapper(data.name)) + if (data.name === 'android') { + list = filterAndroid(list, versions, context) + } + return selected.concat(list) + }, []) + } + }, + { + regexp: /^last\s+(\d+)\s+electron\s+major\s+versions?$/i, + select: function (context, versions) { + var validVersions = getMajorVersions(Object.keys(e2c), versions) + return validVersions.map(function (i) { + return 'chrome ' + e2c[i] + }) + } + }, + { + regexp: /^last\s+(\d+)\s+(\w+)\s+major\s+versions?$/i, + select: function (context, versions, name) { + var data = checkName(name, context) + var validVersions = getMajorVersions(data.released, versions) + var list = validVersions.map(nameMapper(data.name)) + if (data.name === 'android') { + list = filterAndroid(list, versions, context) + } + return list + } + }, + { + regexp: /^last\s+(\d+)\s+electron\s+versions?$/i, + select: function (context, versions) { + return Object.keys(e2c) + .slice(-versions) + .map(function (i) { + return 'chrome ' + e2c[i] + }) + } + }, + { + regexp: /^last\s+(\d+)\s+(\w+)\s+versions?$/i, + select: function (context, versions, name) { + var data = checkName(name, context) + var list = data.released.slice(-versions).map(nameMapper(data.name)) + if (data.name === 'android') { + list = filterAndroid(list, versions, context) + } + return list + } + }, + { + regexp: /^unreleased\s+versions$/i, + select: function (context) { + return Object.keys(agents).reduce(function (selected, name) { + var data = byName(name, context) + if (!data) return selected + var list = data.versions.filter(function (v) { + return data.released.indexOf(v) === -1 + }) + list = list.map(nameMapper(data.name)) + return selected.concat(list) + }, []) + } + }, + { + regexp: /^unreleased\s+electron\s+versions?$/i, + select: function () { + return [] + } + }, + { + regexp: /^unreleased\s+(\w+)\s+versions?$/i, + select: function (context, name) { + var data = checkName(name, context) + return data.versions + .filter(function (v) { + return data.released.indexOf(v) === -1 + }) + .map(nameMapper(data.name)) + } + }, + { + regexp: /^last\s+(\d*.?\d+)\s+years?$/i, + select: function (context, years) { + return filterByYear(Date.now() - YEAR * years, context) + } + }, + { + regexp: /^since (\d+)$/i, + select: sinceQuery + }, + { + regexp: /^since (\d+)-(\d+)$/i, + select: sinceQuery + }, + { + regexp: /^since (\d+)-(\d+)-(\d+)$/i, + select: sinceQuery + }, + { + regexp: /^(>=?|<=?)\s*(\d+|\d+\.\d+|\.\d+)%$/, + select: function (context, sign, popularity) { + popularity = parseFloat(popularity) + var usage = browserslist.usage.global + return Object.keys(usage).reduce(function (result, version) { + if (sign === '>') { + if (usage[version] > popularity) { + result.push(version) + } + } else if (sign === '<') { + if (usage[version] < popularity) { + result.push(version) + } + } else if (sign === '<=') { + if (usage[version] <= popularity) { + result.push(version) + } + } else if (usage[version] >= popularity) { + result.push(version) + } + return result + }, []) + } + }, + { + regexp: /^(>=?|<=?)\s*(\d+|\d+\.\d+|\.\d+)%\s+in\s+my\s+stats$/, + select: function (context, sign, popularity) { + popularity = parseFloat(popularity) + if (!context.customUsage) { + throw new BrowserslistError('Custom usage statistics was not provided') + } + var usage = context.customUsage + return Object.keys(usage).reduce(function (result, version) { + var percentage = usage[version] + if (percentage == null) { + return result + } + + if (sign === '>') { + if (percentage > popularity) { + result.push(version) + } + } else if (sign === '<') { + if (percentage < popularity) { + result.push(version) + } + } else if (sign === '<=') { + if (percentage <= popularity) { + result.push(version) + } + } else if (percentage >= popularity) { + result.push(version) + } + return result + }, []) + } + }, + { + regexp: /^(>=?|<=?)\s*(\d+|\d+\.\d+|\.\d+)%\s+in\s+(\S+)\s+stats$/, + select: function (context, sign, popularity, name) { + popularity = parseFloat(popularity) + var stats = env.loadStat(context, name, browserslist.data) + if (stats) { + context.customUsage = {} + for (var browser in stats) { + fillUsage(context.customUsage, browser, stats[browser]) + } + } + if (!context.customUsage) { + throw new BrowserslistError('Custom usage statistics was not provided') + } + var usage = context.customUsage + return Object.keys(usage).reduce(function (result, version) { + var percentage = usage[version] + if (percentage == null) { + return result + } + + if (sign === '>') { + if (percentage > popularity) { + result.push(version) + } + } else if (sign === '<') { + if (percentage < popularity) { + result.push(version) + } + } else if (sign === '<=') { + if (percentage <= popularity) { + result.push(version) + } + } else if (percentage >= popularity) { + result.push(version) + } + return result + }, []) + } + }, + { + regexp: /^(>=?|<=?)\s*(\d+|\d+\.\d+|\.\d+)%\s+in\s+((alt-)?\w\w)$/, + select: function (context, sign, popularity, place) { + popularity = parseFloat(popularity) + if (place.length === 2) { + place = place.toUpperCase() + } else { + place = place.toLowerCase() + } + env.loadCountry(browserslist.usage, place, browserslist.data) + var usage = browserslist.usage[place] + return Object.keys(usage).reduce(function (result, version) { + var percentage = usage[version] + if (percentage == null) { + return result + } + + if (sign === '>') { + if (percentage > popularity) { + result.push(version) + } + } else if (sign === '<') { + if (percentage < popularity) { + result.push(version) + } + } else if (sign === '<=') { + if (percentage <= popularity) { + result.push(version) + } + } else if (percentage >= popularity) { + result.push(version) + } + return result + }, []) + } + }, + { + regexp: /^cover\s+(\d+|\d+\.\d+|\.\d+)%$/i, + select: coverQuery + }, + { + regexp: /^cover\s+(\d+|\d+\.\d+|\.\d+)%\s+in\s+(my\s+stats|(alt-)?\w\w)$/i, + select: coverQuery + }, + { + regexp: /^supports\s+([\w-]+)$/, + select: function (context, feature) { + env.loadFeature(browserslist.cache, feature) + var features = browserslist.cache[feature] + return Object.keys(features).reduce(function (result, version) { + var flags = features[version] + if (flags.indexOf('y') >= 0 || flags.indexOf('a') >= 0) { + result.push(version) + } + return result + }, []) + } + }, + { + regexp: /^electron\s+([\d.]+)\s*-\s*([\d.]+)$/i, + select: function (context, from, to) { + var fromToUse = normalizeElectron(from) + var toToUse = normalizeElectron(to) + if (!e2c[fromToUse]) { + throw new BrowserslistError('Unknown version ' + from + ' of electron') + } + if (!e2c[toToUse]) { + throw new BrowserslistError('Unknown version ' + to + ' of electron') + } + from = parseFloat(from) + to = parseFloat(to) + return Object.keys(e2c) + .filter(function (i) { + var parsed = parseFloat(i) + return parsed >= from && parsed <= to + }) + .map(function (i) { + return 'chrome ' + e2c[i] + }) + } + }, + { + regexp: /^node\s+([\d.]+)\s*-\s*([\d.]+)$/i, + select: function (context, from, to) { + var nodeVersions = jsReleases + .filter(function (i) { + return i.name === 'nodejs' + }) + .map(function (i) { + return i.version + }) + return nodeVersions + .filter(semverFilterLoose('>=', from)) + .filter(semverFilterLoose('<=', to)) + .map(function (v) { + return 'node ' + v + }) + } + }, + { + regexp: /^(\w+)\s+([\d.]+)\s*-\s*([\d.]+)$/i, + select: function (context, name, from, to) { + var data = checkName(name, context) + from = parseFloat(normalizeVersion(data, from) || from) + to = parseFloat(normalizeVersion(data, to) || to) + function filter(v) { + var parsed = parseFloat(v) + return parsed >= from && parsed <= to + } + return data.released.filter(filter).map(nameMapper(data.name)) + } + }, + { + regexp: /^electron\s*(>=?|<=?)\s*([\d.]+)$/i, + select: function (context, sign, version) { + var versionToUse = normalizeElectron(version) + return Object.keys(e2c) + .filter(generateFilter(sign, versionToUse)) + .map(function (i) { + return 'chrome ' + e2c[i] + }) + } + }, + { + regexp: /^node\s*(>=?|<=?)\s*([\d.]+)$/i, + select: function (context, sign, version) { + var nodeVersions = jsReleases + .filter(function (i) { + return i.name === 'nodejs' + }) + .map(function (i) { + return i.version + }) + return nodeVersions + .filter(generateSemverFilter(sign, version)) + .map(function (v) { + return 'node ' + v + }) + } + }, + { + regexp: /^(\w+)\s*(>=?|<=?)\s*([\d.]+)$/, + select: function (context, name, sign, version) { + var data = checkName(name, context) + var alias = browserslist.versionAliases[data.name][version] + if (alias) { + version = alias + } + return data.released + .filter(generateFilter(sign, version)) + .map(function (v) { + return data.name + ' ' + v + }) + } + }, + { + regexp: /^(firefox|ff|fx)\s+esr$/i, + select: function () { + return ['firefox 91'] + } + }, + { + regexp: /(operamini|op_mini)\s+all/i, + select: function () { + return ['op_mini all'] + } + }, + { + regexp: /^electron\s+([\d.]+)$/i, + select: function (context, version) { + var versionToUse = normalizeElectron(version) + var chrome = e2c[versionToUse] + if (!chrome) { + throw new BrowserslistError( + 'Unknown version ' + version + ' of electron' + ) + } + return ['chrome ' + chrome] + } + }, + { + regexp: /^node\s+(\d+)$/i, + select: nodeQuery + }, + { + regexp: /^node\s+(\d+\.\d+)$/i, + select: nodeQuery + }, + { + regexp: /^node\s+(\d+\.\d+\.\d+)$/i, + select: nodeQuery + }, + { + regexp: /^current\s+node$/i, + select: function (context) { + return [env.currentNode(resolve, context)] + } + }, + { + regexp: /^maintained\s+node\s+versions$/i, + select: function (context) { + var now = Date.now() + var queries = Object.keys(jsEOL) + .filter(function (key) { + return ( + now < Date.parse(jsEOL[key].end) && + now > Date.parse(jsEOL[key].start) && + isEolReleased(key) + ) + }) + .map(function (key) { + return 'node ' + key.slice(1) + }) + return resolve(queries, context) + } + }, + { + regexp: /^phantomjs\s+1.9$/i, + select: function () { + return ['safari 5'] + } + }, + { + regexp: /^phantomjs\s+2.1$/i, + select: function () { + return ['safari 6'] + } + }, + { + regexp: /^(\w+)\s+(tp|[\d.]+)$/i, + select: function (context, name, version) { + if (/^tp$/i.test(version)) version = 'TP' + var data = checkName(name, context) + var alias = normalizeVersion(data, version) + if (alias) { + version = alias + } else { + if (version.indexOf('.') === -1) { + alias = version + '.0' + } else { + alias = version.replace(/\.0$/, '') + } + alias = normalizeVersion(data, alias) + if (alias) { + version = alias + } else if (context.ignoreUnknownVersions) { + return [] + } else { + throw new BrowserslistError( + 'Unknown version ' + version + ' of ' + name + ) + } + } + return [data.name + ' ' + version] + } + }, + { + regexp: /^browserslist config$/i, + select: function (context) { + return browserslist(undefined, context) + } + }, + { + regexp: /^extends (.+)$/i, + select: function (context, name) { + return resolve(env.loadQueries(context, name), context) + } + }, + { + regexp: /^defaults$/i, + select: function (context) { + return resolve(browserslist.defaults, context) + } + }, + { + regexp: /^dead$/i, + select: function (context) { + var dead = [ + 'ie <= 10', + 'ie_mob <= 11', + 'bb <= 10', + 'op_mob <= 12.1', + 'samsung 4' + ] + return resolve(dead, context) + } + }, + { + regexp: /^(\w+)$/i, + select: function (context, name) { + if (byName(name, context)) { + throw new BrowserslistError( + 'Specify versions in Browserslist query for browser ' + name + ) + } else { + throw unknownQuery(name) + } + } + } +] + +// Get and convert Can I Use data + +;(function () { + for (var name in agents) { + var browser = agents[name] + browserslist.data[name] = { + name: name, + versions: normalize(agents[name].versions), + released: normalize(agents[name].versions.slice(0, -3)), + releaseDate: agents[name].release_date + } + fillUsage(browserslist.usage.global, name, browser.usage_global) + + browserslist.versionAliases[name] = {} + for (var i = 0; i < browser.versions.length; i++) { + var full = browser.versions[i] + if (!full) continue + + if (full.indexOf('-') !== -1) { + var interval = full.split('-') + for (var j = 0; j < interval.length; j++) { + browserslist.versionAliases[name][interval[j]] = full + } + } + } + } + + browserslist.versionAliases.op_mob['59'] = '58' +})() + +module.exports = browserslist diff --git a/node_modules/browserslist/node.js b/node_modules/browserslist/node.js new file mode 100644 index 0000000..8eb6b65 --- /dev/null +++ b/node_modules/browserslist/node.js @@ -0,0 +1,393 @@ +var feature = require('caniuse-lite/dist/unpacker/feature').default +var region = require('caniuse-lite/dist/unpacker/region').default +var path = require('path') +var fs = require('fs') + +var BrowserslistError = require('./error') + +var IS_SECTION = /^\s*\[(.+)]\s*$/ +var CONFIG_PATTERN = /^browserslist-config-/ +var SCOPED_CONFIG__PATTERN = /@[^/]+\/browserslist-config(-|$|\/)/ +var TIME_TO_UPDATE_CANIUSE = 6 * 30 * 24 * 60 * 60 * 1000 +var FORMAT = + 'Browserslist config should be a string or an array ' + + 'of strings with browser queries' + +var dataTimeChecked = false +var filenessCache = {} +var configCache = {} +function checkExtend(name) { + var use = ' Use `dangerousExtend` option to disable.' + if (!CONFIG_PATTERN.test(name) && !SCOPED_CONFIG__PATTERN.test(name)) { + throw new BrowserslistError( + 'Browserslist config needs `browserslist-config-` prefix. ' + use + ) + } + if (name.replace(/^@[^/]+\//, '').indexOf('.') !== -1) { + throw new BrowserslistError( + '`.` not allowed in Browserslist config name. ' + use + ) + } + if (name.indexOf('node_modules') !== -1) { + throw new BrowserslistError( + '`node_modules` not allowed in Browserslist config.' + use + ) + } +} + +function isFile(file) { + if (file in filenessCache) { + return filenessCache[file] + } + var result = fs.existsSync(file) && fs.statSync(file).isFile() + if (!process.env.BROWSERSLIST_DISABLE_CACHE) { + filenessCache[file] = result + } + return result +} + +function eachParent(file, callback) { + var dir = isFile(file) ? path.dirname(file) : file + var loc = path.resolve(dir) + do { + var result = callback(loc) + if (typeof result !== 'undefined') return result + } while (loc !== (loc = path.dirname(loc))) + return undefined +} + +function check(section) { + if (Array.isArray(section)) { + for (var i = 0; i < section.length; i++) { + if (typeof section[i] !== 'string') { + throw new BrowserslistError(FORMAT) + } + } + } else if (typeof section !== 'string') { + throw new BrowserslistError(FORMAT) + } +} + +function pickEnv(config, opts) { + if (typeof config !== 'object') return config + + var name + if (typeof opts.env === 'string') { + name = opts.env + } else if (process.env.BROWSERSLIST_ENV) { + name = process.env.BROWSERSLIST_ENV + } else if (process.env.NODE_ENV) { + name = process.env.NODE_ENV + } else { + name = 'production' + } + + if (opts.throwOnMissing) { + if (name && name !== 'defaults' && !config[name]) { + throw new BrowserslistError( + 'Missing config for Browserslist environment `' + name + '`' + ) + } + } + + return config[name] || config.defaults +} + +function parsePackage(file) { + var config = JSON.parse(fs.readFileSync(file)) + if (config.browserlist && !config.browserslist) { + throw new BrowserslistError( + '`browserlist` key instead of `browserslist` in ' + file + ) + } + var list = config.browserslist + if (Array.isArray(list) || typeof list === 'string') { + list = { defaults: list } + } + for (var i in list) { + check(list[i]) + } + + return list +} + +function latestReleaseTime(agents) { + var latest = 0 + for (var name in agents) { + var dates = agents[name].releaseDate || {} + for (var key in dates) { + if (latest < dates[key]) { + latest = dates[key] + } + } + } + return latest * 1000 +} + +function normalizeStats(data, stats) { + if (!data) { + data = {} + } + if (stats && 'dataByBrowser' in stats) { + stats = stats.dataByBrowser + } + + if (typeof stats !== 'object') return undefined + + var normalized = {} + for (var i in stats) { + var versions = Object.keys(stats[i]) + if (versions.length === 1 && data[i] && data[i].versions.length === 1) { + var normal = data[i].versions[0] + normalized[i] = {} + normalized[i][normal] = stats[i][versions[0]] + } else { + normalized[i] = stats[i] + } + } + + return normalized +} + +function normalizeUsageData(usageData, data) { + for (var browser in usageData) { + var browserUsage = usageData[browser] + // eslint-disable-next-line max-len + // https://github.com/browserslist/browserslist/issues/431#issuecomment-565230615 + // caniuse-db returns { 0: "percentage" } for `and_*` regional stats + if ('0' in browserUsage) { + var versions = data[browser].versions + browserUsage[versions[versions.length - 1]] = browserUsage[0] + delete browserUsage[0] + } + } +} + +module.exports = { + loadQueries: function loadQueries(ctx, name) { + if (!ctx.dangerousExtend && !process.env.BROWSERSLIST_DANGEROUS_EXTEND) { + checkExtend(name) + } + var queries = require(require.resolve(name, { paths: ['.', ctx.path] })) + if (queries) { + if (Array.isArray(queries)) { + return queries + } else if (typeof queries === 'object') { + if (!queries.defaults) queries.defaults = [] + return pickEnv(queries, ctx, name) + } + } + throw new BrowserslistError( + '`' + + name + + '` config exports not an array of queries' + + ' or an object of envs' + ) + }, + + loadStat: function loadStat(ctx, name, data) { + if (!ctx.dangerousExtend && !process.env.BROWSERSLIST_DANGEROUS_EXTEND) { + checkExtend(name) + } + var stats = require(require.resolve( + path.join(name, 'browserslist-stats.json'), + { paths: ['.'] } + )) + return normalizeStats(data, stats) + }, + + getStat: function getStat(opts, data) { + var stats + if (opts.stats) { + stats = opts.stats + } else if (process.env.BROWSERSLIST_STATS) { + stats = process.env.BROWSERSLIST_STATS + } else if (opts.path && path.resolve && fs.existsSync) { + stats = eachParent(opts.path, function (dir) { + var file = path.join(dir, 'browserslist-stats.json') + return isFile(file) ? file : undefined + }) + } + if (typeof stats === 'string') { + try { + stats = JSON.parse(fs.readFileSync(stats)) + } catch (e) { + throw new BrowserslistError("Can't read " + stats) + } + } + return normalizeStats(data, stats) + }, + + loadConfig: function loadConfig(opts) { + if (process.env.BROWSERSLIST) { + return process.env.BROWSERSLIST + } else if (opts.config || process.env.BROWSERSLIST_CONFIG) { + var file = opts.config || process.env.BROWSERSLIST_CONFIG + if (path.basename(file) === 'package.json') { + return pickEnv(parsePackage(file), opts) + } else { + return pickEnv(module.exports.readConfig(file), opts) + } + } else if (opts.path) { + return pickEnv(module.exports.findConfig(opts.path), opts) + } else { + return undefined + } + }, + + loadCountry: function loadCountry(usage, country, data) { + var code = country.replace(/[^\w-]/g, '') + if (!usage[code]) { + var compressed = require('caniuse-lite/data/regions/' + code + '.js') + var usageData = region(compressed) + normalizeUsageData(usageData, data) + usage[country] = {} + for (var i in usageData) { + for (var j in usageData[i]) { + usage[country][i + ' ' + j] = usageData[i][j] + } + } + } + }, + + loadFeature: function loadFeature(features, name) { + name = name.replace(/[^\w-]/g, '') + if (features[name]) return + + var compressed = require('caniuse-lite/data/features/' + name + '.js') + var stats = feature(compressed).stats + features[name] = {} + for (var i in stats) { + for (var j in stats[i]) { + features[name][i + ' ' + j] = stats[i][j] + } + } + }, + + parseConfig: function parseConfig(string) { + var result = { defaults: [] } + var sections = ['defaults'] + + string + .toString() + .replace(/#[^\n]*/g, '') + .split(/\n|,/) + .map(function (line) { + return line.trim() + }) + .filter(function (line) { + return line !== '' + }) + .forEach(function (line) { + if (IS_SECTION.test(line)) { + sections = line.match(IS_SECTION)[1].trim().split(' ') + sections.forEach(function (section) { + if (result[section]) { + throw new BrowserslistError( + 'Duplicate section ' + section + ' in Browserslist config' + ) + } + result[section] = [] + }) + } else { + sections.forEach(function (section) { + result[section].push(line) + }) + } + }) + + return result + }, + + readConfig: function readConfig(file) { + if (!isFile(file)) { + throw new BrowserslistError("Can't read " + file + ' config') + } + return module.exports.parseConfig(fs.readFileSync(file)) + }, + + findConfig: function findConfig(from) { + from = path.resolve(from) + + var passed = [] + var resolved = eachParent(from, function (dir) { + if (dir in configCache) { + return configCache[dir] + } + + passed.push(dir) + + var config = path.join(dir, 'browserslist') + var pkg = path.join(dir, 'package.json') + var rc = path.join(dir, '.browserslistrc') + + var pkgBrowserslist + if (isFile(pkg)) { + try { + pkgBrowserslist = parsePackage(pkg) + } catch (e) { + if (e.name === 'BrowserslistError') throw e + console.warn( + '[Browserslist] Could not parse ' + pkg + '. Ignoring it.' + ) + } + } + + if (isFile(config) && pkgBrowserslist) { + throw new BrowserslistError( + dir + ' contains both browserslist and package.json with browsers' + ) + } else if (isFile(rc) && pkgBrowserslist) { + throw new BrowserslistError( + dir + ' contains both .browserslistrc and package.json with browsers' + ) + } else if (isFile(config) && isFile(rc)) { + throw new BrowserslistError( + dir + ' contains both .browserslistrc and browserslist' + ) + } else if (isFile(config)) { + return module.exports.readConfig(config) + } else if (isFile(rc)) { + return module.exports.readConfig(rc) + } else { + return pkgBrowserslist + } + }) + if (!process.env.BROWSERSLIST_DISABLE_CACHE) { + passed.forEach(function (dir) { + configCache[dir] = resolved + }) + } + return resolved + }, + + clearCaches: function clearCaches() { + dataTimeChecked = false + filenessCache = {} + configCache = {} + + this.cache = {} + }, + + oldDataWarning: function oldDataWarning(agentsObj) { + if (dataTimeChecked) return + dataTimeChecked = true + if (process.env.BROWSERSLIST_IGNORE_OLD_DATA) return + + var latest = latestReleaseTime(agentsObj) + var halfYearAgo = Date.now() - TIME_TO_UPDATE_CANIUSE + + if (latest !== 0 && latest < halfYearAgo) { + console.warn( + 'Browserslist: caniuse-lite is outdated. Please run:\n' + + ' npx browserslist@latest --update-db\n' + + ' Why you should do it regularly: ' + + 'https://github.com/browserslist/browserslist#browsers-data-updating' + ) + } + }, + + currentNode: function currentNode() { + return 'node ' + process.versions.node + } +} diff --git a/node_modules/browserslist/package.json b/node_modules/browserslist/package.json new file mode 100644 index 0000000..7cf870d --- /dev/null +++ b/node_modules/browserslist/package.json @@ -0,0 +1,35 @@ +{ + "name": "browserslist", + "version": "4.19.3", + "description": "Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-env-preset", + "keywords": [ + "caniuse", + "browsers", + "target" + ], + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + "author": "Andrey Sitnik <andrey@sitnik.ru>", + "license": "MIT", + "repository": "browserslist/browserslist", + "dependencies": { + "caniuse-lite": "^1.0.30001312", + "electron-to-chromium": "^1.4.71", + "escalade": "^3.1.1", + "node-releases": "^2.0.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "bin": { + "browserslist": "cli.js" + }, + "types": "./index.d.ts", + "browser": { + "./node.js": "./browser.js", + "path": false + } +} diff --git a/node_modules/browserslist/update-db.js b/node_modules/browserslist/update-db.js new file mode 100644 index 0000000..3e69e64 --- /dev/null +++ b/node_modules/browserslist/update-db.js @@ -0,0 +1,317 @@ +var childProcess = require('child_process') +var escalade = require('escalade/sync') +var pico = require('picocolors') +var path = require('path') +var fs = require('fs') + +var BrowserslistError = require('./error') + +function detectLockfile() { + var packageDir = escalade('.', function (dir, names) { + return names.indexOf('package.json') !== -1 ? dir : '' + }) + + if (!packageDir) { + throw new BrowserslistError( + 'Cannot find package.json. ' + + 'Is this the right directory to run `npx browserslist --update-db` in?' + ) + } + + var lockfileNpm = path.join(packageDir, 'package-lock.json') + var lockfileShrinkwrap = path.join(packageDir, 'npm-shrinkwrap.json') + var lockfileYarn = path.join(packageDir, 'yarn.lock') + var lockfilePnpm = path.join(packageDir, 'pnpm-lock.yaml') + + if (fs.existsSync(lockfilePnpm)) { + return { mode: 'pnpm', file: lockfilePnpm } + } else if (fs.existsSync(lockfileNpm)) { + return { mode: 'npm', file: lockfileNpm } + } else if (fs.existsSync(lockfileYarn)) { + var lock = { mode: 'yarn', file: lockfileYarn } + lock.content = fs.readFileSync(lock.file).toString() + lock.version = /# yarn lockfile v1/.test(lock.content) ? 1 : 2 + return lock + } else if (fs.existsSync(lockfileShrinkwrap)) { + return { mode: 'npm', file: lockfileShrinkwrap } + } + throw new BrowserslistError( + 'No lockfile found. Run "npm install", "yarn install" or "pnpm install"' + ) +} + +function getLatestInfo(lock) { + if (lock.mode === 'yarn') { + if (lock.version === 1) { + return JSON.parse( + childProcess.execSync('yarn info caniuse-lite --json').toString() + ).data + } else { + return JSON.parse( + childProcess.execSync('yarn npm info caniuse-lite --json').toString() + ) + } + } + return JSON.parse( + childProcess.execSync('npm show caniuse-lite --json').toString() + ) +} + +function getBrowsersList() { + return childProcess + .execSync('npx browserslist') + .toString() + .trim() + .split('\n') + .map(function (line) { + return line.trim().split(' ') + }) + .reduce(function (result, entry) { + if (!result[entry[0]]) { + result[entry[0]] = [] + } + result[entry[0]].push(entry[1]) + return result + }, {}) +} + +function diffBrowsersLists(old, current) { + var browsers = Object.keys(old).concat( + Object.keys(current).filter(function (browser) { + return old[browser] === undefined + }) + ) + return browsers + .map(function (browser) { + var oldVersions = old[browser] || [] + var currentVersions = current[browser] || [] + var intersection = oldVersions.filter(function (version) { + return currentVersions.indexOf(version) !== -1 + }) + var addedVersions = currentVersions.filter(function (version) { + return intersection.indexOf(version) === -1 + }) + var removedVersions = oldVersions.filter(function (version) { + return intersection.indexOf(version) === -1 + }) + return removedVersions + .map(function (version) { + return pico.red('- ' + browser + ' ' + version) + }) + .concat( + addedVersions.map(function (version) { + return pico.green('+ ' + browser + ' ' + version) + }) + ) + }) + .reduce(function (result, array) { + return result.concat(array) + }, []) + .join('\n') +} + +function updateNpmLockfile(lock, latest) { + var metadata = { latest: latest, versions: [] } + var content = deletePackage(JSON.parse(lock.content), metadata) + metadata.content = JSON.stringify(content, null, ' ') + return metadata +} + +function deletePackage(node, metadata) { + if (node.dependencies) { + if (node.dependencies['caniuse-lite']) { + var version = node.dependencies['caniuse-lite'].version + metadata.versions[version] = true + delete node.dependencies['caniuse-lite'] + } + for (var i in node.dependencies) { + node.dependencies[i] = deletePackage(node.dependencies[i], metadata) + } + } + return node +} + +var yarnVersionRe = /version "(.*?)"/ + +function updateYarnLockfile(lock, latest) { + var blocks = lock.content.split(/(\n{2,})/).map(function (block) { + return block.split('\n') + }) + var versions = {} + blocks.forEach(function (lines) { + if (lines[0].indexOf('caniuse-lite@') !== -1) { + var match = yarnVersionRe.exec(lines[1]) + versions[match[1]] = true + if (match[1] !== latest.version) { + lines[1] = lines[1].replace( + /version "[^"]+"/, + 'version "' + latest.version + '"' + ) + lines[2] = lines[2].replace( + /resolved "[^"]+"/, + 'resolved "' + latest.dist.tarball + '"' + ) + if (lines.length === 4) { + lines[3] = latest.dist.integrity + ? lines[3].replace( + /integrity .+/, + 'integrity ' + latest.dist.integrity + ) + : '' + } + } + } + }) + var content = blocks + .map(function (lines) { + return lines.join('\n') + }) + .join('') + return { content: content, versions: versions } +} + +function updateLockfile(lock, latest) { + if (!lock.content) lock.content = fs.readFileSync(lock.file).toString() + + if (lock.mode === 'yarn') { + return updateYarnLockfile(lock, latest) + } else { + return updateNpmLockfile(lock, latest) + } +} + +function updatePackageManually(print, lock, latest) { + var lockfileData = updateLockfile(lock, latest) + var caniuseVersions = Object.keys(lockfileData.versions).sort() + if (caniuseVersions.length === 1 && caniuseVersions[0] === latest.version) { + print( + 'Installed version: ' + + pico.bold(pico.green(latest.version)) + + '\n' + + pico.bold(pico.green('caniuse-lite is up to date')) + + '\n' + ) + return + } + + if (caniuseVersions.length === 0) { + caniuseVersions[0] = 'none' + } + print( + 'Installed version' + + (caniuseVersions.length === 1 ? ': ' : 's: ') + + pico.bold(pico.red(caniuseVersions.join(', '))) + + '\n' + + 'Removing old caniuse-lite from lock file\n' + ) + fs.writeFileSync(lock.file, lockfileData.content) + + var install = lock.mode === 'yarn' ? 'yarn add -W' : lock.mode + ' install' + print( + 'Installing new caniuse-lite version\n' + + pico.yellow('$ ' + install + ' caniuse-lite') + + '\n' + ) + try { + childProcess.execSync(install + ' caniuse-lite') + } catch (e) /* c8 ignore start */ { + print( + pico.red( + '\n' + + e.stack + + '\n\n' + + 'Problem with `' + + install + + ' caniuse-lite` call. ' + + 'Run it manually.\n' + ) + ) + process.exit(1) + } /* c8 ignore end */ + + var del = lock.mode === 'yarn' ? 'yarn remove -W' : lock.mode + ' uninstall' + print( + 'Cleaning package.json dependencies from caniuse-lite\n' + + pico.yellow('$ ' + del + ' caniuse-lite') + + '\n' + ) + childProcess.execSync(del + ' caniuse-lite') +} + +function updateWith(print, cmd) { + print('Updating caniuse-lite version\n' + pico.yellow('$ ' + cmd) + '\n') + try { + childProcess.execSync(cmd) + } catch (e) /* c8 ignore start */ { + print(pico.red(e.stdout.toString())) + print( + pico.red( + '\n' + + e.stack + + '\n\n' + + 'Problem with `' + + cmd + + '` call. ' + + 'Run it manually.\n' + ) + ) + process.exit(1) + } /* c8 ignore end */ +} + +module.exports = function updateDB(print) { + var lock = detectLockfile() + var latest = getLatestInfo(lock) + + var browsersListRetrievalError + var oldBrowsersList + try { + oldBrowsersList = getBrowsersList() + } catch (e) { + browsersListRetrievalError = e + } + + print('Latest version: ' + pico.bold(pico.green(latest.version)) + '\n') + + if (lock.mode === 'yarn' && lock.version !== 1) { + updateWith(print, 'yarn up -R caniuse-lite') + } else if (lock.mode === 'pnpm') { + updateWith(print, 'pnpm up caniuse-lite') + } else { + updatePackageManually(print, lock, latest) + } + + print('caniuse-lite has been successfully updated\n') + + var currentBrowsersList + if (!browsersListRetrievalError) { + try { + currentBrowsersList = getBrowsersList() + } catch (e) /* c8 ignore start */ { + browsersListRetrievalError = e + } /* c8 ignore end */ + } + + if (browsersListRetrievalError) { + print( + pico.red( + '\n' + + browsersListRetrievalError.stack + + '\n\n' + + 'Problem with browser list retrieval.\n' + + 'Target browser changes won’t be shown.\n' + ) + ) + } else { + var targetBrowserChanges = diffBrowsersLists( + oldBrowsersList, + currentBrowsersList + ) + if (targetBrowserChanges) { + print('\nTarget browser changes:\n') + print(targetBrowserChanges + '\n') + } else { + print('\n' + pico.green('No target browser changes') + '\n') + } + } +} |