mergeDeps.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. const { semver, warn } = require('@vue/cli-shared-utils')
  2. const tryGetNewerRange = require('./tryGetNewerRange')
  3. const extractSemver = r => r.replace(/^.+#semver:/, '')
  4. const injectSemver = (r, v) =>
  5. semver.validRange(r) ? v : r.replace(/#semver:.+$/, `#semver:${v}`)
  6. const isValidRange = range => {
  7. if (typeof range !== 'string') {
  8. return false
  9. }
  10. const isValidSemver = !!semver.validRange(range)
  11. const isValidGitHub = range.match(/^[^/]+\/[^/]+/) != null
  12. const isValidURI =
  13. range.match(
  14. /^(?:file|git|git\+ssh|git\+http|git\+https|git\+file|https?):/
  15. ) != null
  16. return isValidSemver || isValidGitHub || isValidURI
  17. }
  18. module.exports = function mergeDeps (
  19. generatorId,
  20. sourceDeps,
  21. depsToInject,
  22. sources,
  23. {
  24. prune,
  25. warnIncompatibleVersions
  26. }
  27. ) {
  28. const result = Object.assign({}, sourceDeps)
  29. for (const depName in depsToInject) {
  30. const sourceRange = sourceDeps[depName]
  31. const injectingRange = depsToInject[depName]
  32. // if they are the same, do nothing. Helps when non semver type deps are used
  33. if (sourceRange === injectingRange) continue
  34. if (prune && injectingRange == null) {
  35. delete result[depName]
  36. }
  37. if (!isValidRange(injectingRange)) {
  38. warn(
  39. `invalid version range for dependency "${depName}":\n\n` +
  40. `- ${injectingRange} injected by generator "${generatorId}"`
  41. )
  42. continue
  43. }
  44. const sourceGeneratorId = sources[depName]
  45. if (!sourceRange) {
  46. result[depName] = injectingRange
  47. sources[depName] = generatorId
  48. } else {
  49. const sourceRangeSemver = extractSemver(sourceRange)
  50. const injectingRangeSemver = extractSemver(injectingRange)
  51. const r = tryGetNewerRange(sourceRangeSemver, injectingRangeSemver)
  52. const didGetNewer = !!r
  53. // if failed to infer newer version, use existing one because it's likely
  54. // built-in
  55. result[depName] = didGetNewer
  56. ? injectSemver(injectingRange, r)
  57. : sourceRange
  58. // if changed, update source
  59. if (result[depName] === injectingRange) {
  60. sources[depName] = generatorId
  61. }
  62. // warn incompatible version requirements
  63. if (
  64. warnIncompatibleVersions &&
  65. (!semver.validRange(sourceRangeSemver) ||
  66. !semver.validRange(injectingRangeSemver) ||
  67. !semver.intersects(sourceRangeSemver, injectingRangeSemver))
  68. ) {
  69. warn(
  70. `conflicting versions for project dependency "${depName}":\n\n` +
  71. `- ${sourceRange} injected by generator "${sourceGeneratorId}"\n` +
  72. `- ${injectingRange} injected by generator "${generatorId}"\n\n` +
  73. `Using ${didGetNewer ? `newer ` : ``}version (${
  74. result[depName]
  75. }), but this may cause build errors.`
  76. )
  77. }
  78. }
  79. }
  80. return result
  81. }