aboutsummaryrefslogtreecommitdiff
path: root/node_modules/browserslist/update-db.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/browserslist/update-db.js')
-rw-r--r--node_modules/browserslist/update-db.js317
1 files changed, 317 insertions, 0 deletions
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')
+ }
+ }
+}