update-db.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. var childProcess = require('child_process')
  2. var escalade = require('escalade/sync')
  3. var path = require('path')
  4. var fs = require('fs')
  5. var BrowserslistError = require('./error')
  6. function detectLockfile () {
  7. var packageDir = escalade('.', function (dir, names) {
  8. return names.indexOf('package.json') !== -1 ? dir : ''
  9. })
  10. if (!packageDir) {
  11. throw new BrowserslistError(
  12. 'Cannot find package.json. ' +
  13. 'Is it a right project to run npx browserslist --update-db?'
  14. )
  15. }
  16. var lockfileNpm = path.join(packageDir, 'package-lock.json')
  17. var lockfileYarn = path.join(packageDir, 'yarn.lock')
  18. var lockfilePnpm = path.join(packageDir, 'pnpm-lock.yaml')
  19. /* istanbul ignore next */
  20. if (fs.existsSync(lockfilePnpm)) {
  21. return { mode: 'pnpm', file: lockfilePnpm }
  22. } else if (fs.existsSync(lockfileNpm)) {
  23. return { mode: 'npm', file: lockfileNpm }
  24. } else if (fs.existsSync(lockfileYarn)) {
  25. return { mode: 'yarn', file: lockfileYarn }
  26. } else {
  27. throw new BrowserslistError(
  28. 'No lockfile found. Run "npm install", "yarn install" or "pnpm install"'
  29. )
  30. }
  31. }
  32. function getCurrentVersion (lock) {
  33. var match
  34. /* istanbul ignore if */
  35. if (lock.mode === 'pnpm') {
  36. match = /\/caniuse-lite\/([^:]+):/.exec(lock.content)
  37. if (match[1]) return match[1]
  38. } else if (lock.mode === 'npm') {
  39. var dependencies = JSON.parse(lock.content).dependencies
  40. if (dependencies && dependencies['caniuse-lite']) {
  41. return dependencies['caniuse-lite'].version
  42. }
  43. } else if (lock.mode === 'yarn') {
  44. match = /caniuse-lite@[^:]+:\r?\n\s+version\s+"([^"]+)"/.exec(lock.content)
  45. if (match[1]) return match[1]
  46. }
  47. return null
  48. }
  49. function getLatestInfo () {
  50. return JSON.parse(
  51. childProcess.execSync('npm show caniuse-lite --json').toString()
  52. )
  53. }
  54. function updateLockfile (lock, latest) {
  55. if (lock.mode === 'npm') {
  56. var fixed = deletePackage(JSON.parse(lock.content))
  57. return JSON.stringify(fixed, null, ' ')
  58. } else {
  59. var lines = lock.content.split('\n')
  60. var i
  61. /* istanbul ignore if */
  62. if (lock.mode === 'pnpm') {
  63. for (i = 0; i < lines.length; i++) {
  64. if (lines[i].indexOf('caniuse-lite:') >= 0) {
  65. lines[i] = lines[i].replace(/: .*$/, ': ' + latest.version)
  66. } else if (lines[i].indexOf('/caniuse-lite') >= 0) {
  67. lines[i] = lines[i].replace(/\/[^/:]+:/, '/' + latest.version + ':')
  68. for (i = i + 1; i < lines.length; i++) {
  69. if (lines[i].indexOf('integrity: ') !== -1) {
  70. lines[i] = lines[i].replace(
  71. /integrity: .+/, 'integrity: ' + latest.dist.integrity
  72. )
  73. } else if (lines[i].indexOf(' /') !== -1) {
  74. break
  75. }
  76. }
  77. }
  78. }
  79. } else if (lock.mode === 'yarn') {
  80. for (i = 0; i < lines.length; i++) {
  81. if (lines[i].indexOf('caniuse-lite@') !== -1) {
  82. lines[i + 1] = lines[i + 1].replace(
  83. /version "[^"]+"/, 'version "' + latest.version + '"'
  84. )
  85. lines[i + 2] = lines[i + 2].replace(
  86. /resolved "[^"]+"/, 'resolved "' + latest.dist.tarball + '"'
  87. )
  88. lines[i + 3] = lines[i + 3].replace(
  89. /integrity .+/, 'integrity ' + latest.dist.integrity
  90. )
  91. i += 4
  92. }
  93. }
  94. }
  95. return lines.join('\n')
  96. }
  97. }
  98. function deletePackage (node) {
  99. if (node.dependencies) {
  100. delete node.dependencies['caniuse-lite']
  101. for (var i in node.dependencies) {
  102. node.dependencies[i] = deletePackage(node.dependencies[i])
  103. }
  104. }
  105. return node
  106. }
  107. module.exports = function updateDB (print) {
  108. var lock = detectLockfile()
  109. lock.content = fs.readFileSync(lock.file).toString()
  110. var current = getCurrentVersion(lock)
  111. var latest = getLatestInfo()
  112. if (typeof current === 'string') {
  113. print('Current version: ' + current + '\n')
  114. }
  115. print(
  116. 'New version: ' + latest.version + '\n' +
  117. 'Removing old caniuse-lite from lock file…\n'
  118. )
  119. fs.writeFileSync(lock.file, updateLockfile(lock, latest))
  120. print(
  121. 'Installing new caniuse-lite version…\n' +
  122. '$ ' + lock.mode + ' install\n'
  123. )
  124. try {
  125. childProcess.execSync(lock.mode + ' install')
  126. } catch (e) /* istanbul ignore next */ {
  127. print(e.stack)
  128. print('\nProblem with `' + lock.mode + ' install` call. Run it manually.\n')
  129. process.exit(1)
  130. }
  131. print('caniuse-lite has been successfully updated\n')
  132. }