index.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. const semver = require('semver')
  2. const checkEngine = (target, npmVer, nodeVer, force = false) => {
  3. const nodev = force ? null : nodeVer
  4. const eng = target.engines
  5. const opt = { includePrerelease: true }
  6. if (!eng) {
  7. return
  8. }
  9. const nodeFail = nodev && eng.node && !semver.satisfies(nodev, eng.node, opt)
  10. const npmFail = npmVer && eng.npm && !semver.satisfies(npmVer, eng.npm, opt)
  11. if (nodeFail || npmFail) {
  12. throw Object.assign(new Error('Unsupported engine'), {
  13. pkgid: target._id,
  14. current: { node: nodeVer, npm: npmVer },
  15. required: eng,
  16. code: 'EBADENGINE',
  17. })
  18. }
  19. }
  20. const isMusl = (file) => file.includes('libc.musl-') || file.includes('ld-musl-')
  21. const checkPlatform = (target, force = false) => {
  22. if (force) {
  23. return
  24. }
  25. const platform = process.platform
  26. const arch = process.arch
  27. const osOk = target.os ? checkList(platform, target.os) : true
  28. const cpuOk = target.cpu ? checkList(arch, target.cpu) : true
  29. let libcOk = true
  30. let libcFamily = null
  31. if (target.libc) {
  32. // libc checks only work in linux, any value is a failure if we aren't
  33. if (platform !== 'linux') {
  34. libcOk = false
  35. } else {
  36. const report = process.report.getReport()
  37. if (report.header?.glibcVersionRuntime) {
  38. libcFamily = 'glibc'
  39. } else if (Array.isArray(report.sharedObjects) && report.sharedObjects.some(isMusl)) {
  40. libcFamily = 'musl'
  41. }
  42. libcOk = libcFamily ? checkList(libcFamily, target.libc) : false
  43. }
  44. }
  45. if (!osOk || !cpuOk || !libcOk) {
  46. throw Object.assign(new Error('Unsupported platform'), {
  47. pkgid: target._id,
  48. current: {
  49. os: platform,
  50. cpu: arch,
  51. libc: libcFamily,
  52. },
  53. required: {
  54. os: target.os,
  55. cpu: target.cpu,
  56. libc: target.libc,
  57. },
  58. code: 'EBADPLATFORM',
  59. })
  60. }
  61. }
  62. const checkList = (value, list) => {
  63. if (typeof list === 'string') {
  64. list = [list]
  65. }
  66. if (list.length === 1 && list[0] === 'any') {
  67. return true
  68. }
  69. // match none of the negated values, and at least one of the
  70. // non-negated values, if any are present.
  71. let negated = 0
  72. let match = false
  73. for (const entry of list) {
  74. const negate = entry.charAt(0) === '!'
  75. const test = negate ? entry.slice(1) : entry
  76. if (negate) {
  77. negated++
  78. if (value === test) {
  79. return false
  80. }
  81. } else {
  82. match = match || value === test
  83. }
  84. }
  85. return match || negated === list.length
  86. }
  87. module.exports = {
  88. checkEngine,
  89. checkPlatform,
  90. }