mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-01 09:47:56 +08:00
Some packages have vulnerabilities, which can be fixed with "npm audit fix". Unfortunately not all packages can be fixed, as they are transitive dependencies that require major breaking change updates from other packages. Luckily we are not affected by these vulnerabilities in our frontend code. R=aerotwist@chromium.org Bug: none Change-Id: I728411390ebbcb5240045aae5b67b4d8cfc540fb Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2949048 Auto-Submit: Tim van der Lippe <tvanderlippe@chromium.org> Reviewed-by: Paul Lewis <aerotwist@chromium.org> Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
297 lines
8.4 KiB
JavaScript
297 lines
8.4 KiB
JavaScript
var childProcess = require('child_process')
|
||
var colorette = require('colorette')
|
||
var escalade = require('escalade/sync')
|
||
var path = require('path')
|
||
var fs = require('fs')
|
||
|
||
var BrowserslistError = require('./error')
|
||
|
||
var red = colorette.red
|
||
var bold = colorette.bold
|
||
var green = colorette.green
|
||
var yellow = colorette.yellow
|
||
|
||
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)) {
|
||
return { mode: 'yarn', file: lockfileYarn }
|
||
} 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') {
|
||
return JSON.parse(
|
||
childProcess.execSync('yarn info caniuse-lite --json').toString()
|
||
).data
|
||
}
|
||
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 red('- ' + browser + ' ' + version)
|
||
}).concat(addedVersions.map(function (version) {
|
||
return 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 = new RegExp('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 + '"'
|
||
)
|
||
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 updatePnpmLockfile (lock, latest) {
|
||
var versions = {}
|
||
var lines = lock.content.split('\n')
|
||
var i
|
||
var j
|
||
var lineParts
|
||
|
||
for (i = 0; i < lines.length; i++) {
|
||
if (lines[i].indexOf('caniuse-lite:') >= 0) {
|
||
lineParts = lines[i].split(/:\s?/, 2)
|
||
versions[lineParts[1]] = true
|
||
lines[i] = lineParts[0] + ': ' + latest.version
|
||
} else if (lines[i].indexOf('/caniuse-lite') >= 0) {
|
||
lineParts = lines[i].split(/([/:])/)
|
||
for (j = 0; j < lineParts.length; j++) {
|
||
if (lineParts[j].indexOf('caniuse-lite') >= 0) {
|
||
versions[lineParts[j + 2]] = true
|
||
lineParts[j + 2] = latest.version
|
||
break
|
||
}
|
||
}
|
||
lines[i] = lineParts.join('')
|
||
for (i = i + 1; i < lines.length; i++) {
|
||
if (lines[i].indexOf('integrity: ') !== -1) {
|
||
lines[i] = lines[i].replace(
|
||
/integrity: .+/, 'integrity: ' + latest.dist.integrity
|
||
)
|
||
} else if (lines[i].indexOf(' /') !== -1) {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return { content: lines.join('\n'), versions: versions }
|
||
}
|
||
|
||
function updateLockfile (lock, latest) {
|
||
lock.content = fs.readFileSync(lock.file).toString()
|
||
|
||
if (lock.mode === 'npm') {
|
||
return updateNpmLockfile(lock, latest)
|
||
} else if (lock.mode === 'yarn') {
|
||
return updateYarnLockfile(lock, latest)
|
||
}
|
||
return updatePnpmLockfile(lock, latest)
|
||
}
|
||
|
||
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: ' + bold(green(latest.version)) + '\n'
|
||
)
|
||
|
||
var lockfileData = updateLockfile(lock, latest)
|
||
var caniuseVersions = Object.keys(lockfileData.versions).sort()
|
||
if (caniuseVersions.length === 1 &&
|
||
caniuseVersions[0] === latest.version) {
|
||
print(
|
||
'Installed version: ' + bold(green(latest.version)) + '\n' +
|
||
bold(green('caniuse-lite is up to date')) + '\n'
|
||
)
|
||
return
|
||
}
|
||
|
||
if (caniuseVersions.length === 0) {
|
||
caniuseVersions[0] = 'none'
|
||
}
|
||
print(
|
||
'Installed version' +
|
||
(caniuseVersions.length === 1 ? ': ' : 's: ') +
|
||
bold(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' +
|
||
yellow('$ ' + install + ' caniuse-lite') + '\n'
|
||
)
|
||
try {
|
||
childProcess.execSync(install + ' caniuse-lite')
|
||
} catch (e) /* istanbul ignore next */ {
|
||
print(
|
||
red(
|
||
'\n' +
|
||
e.stack + '\n\n' +
|
||
'Problem with `' + install + ' caniuse-lite` call. ' +
|
||
'Run it manually.\n'
|
||
)
|
||
)
|
||
process.exit(1)
|
||
}
|
||
|
||
var del = lock.mode === 'yarn' ? 'yarn remove -W' : lock.mode + ' uninstall'
|
||
print(
|
||
'Cleaning package.json dependencies from caniuse-lite\n' +
|
||
yellow('$ ' + del + ' caniuse-lite') + '\n'
|
||
)
|
||
childProcess.execSync(del + ' caniuse-lite')
|
||
|
||
print('caniuse-lite has been successfully updated\n')
|
||
|
||
var currentBrowsersList
|
||
if (!browsersListRetrievalError) {
|
||
try {
|
||
currentBrowsersList = getBrowsersList()
|
||
} catch (e) /* istanbul ignore next */ {
|
||
browsersListRetrievalError = e
|
||
}
|
||
}
|
||
|
||
if (browsersListRetrievalError) {
|
||
print(
|
||
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' + green('No target browser changes') + '\n')
|
||
}
|
||
}
|
||
}
|