1const depTypes = new Set([ 2 'dependencies', 3 'optionalDependencies', 4 'devDependencies', 5 'peerDependencies', 6]) 7 8// sort alphabetically all types of deps for a given package 9const orderDeps = (content) => { 10 for (const type of depTypes) { 11 if (content && content[type]) { 12 content[type] = Object.keys(content[type]) 13 .sort((a, b) => a.localeCompare(b, 'en')) 14 .reduce((res, key) => { 15 res[key] = content[type][key] 16 return res 17 }, {}) 18 } 19 } 20 return content 21} 22 23const updateDependencies = ({ content, originalContent }) => { 24 const pkg = orderDeps({ 25 ...content, 26 }) 27 28 // optionalDependencies don't need to be repeated in two places 29 if (pkg.dependencies) { 30 if (pkg.optionalDependencies) { 31 for (const name of Object.keys(pkg.optionalDependencies)) { 32 delete pkg.dependencies[name] 33 } 34 } 35 } 36 37 const result = { ...originalContent } 38 39 // loop through all types of dependencies and update package json pkg 40 for (const type of depTypes) { 41 if (pkg[type]) { 42 result[type] = pkg[type] 43 } 44 45 // prune empty type props from resulting object 46 const emptyDepType = 47 pkg[type] 48 && typeof pkg === 'object' 49 && Object.keys(pkg[type]).length === 0 50 if (emptyDepType) { 51 delete result[type] 52 } 53 } 54 55 // if original package.json had dep in peerDeps AND deps, preserve that. 56 const { dependencies: origProd, peerDependencies: origPeer } = 57 originalContent || {} 58 const { peerDependencies: newPeer } = result 59 if (origProd && origPeer && newPeer) { 60 // we have original prod/peer deps, and new peer deps 61 // copy over any that were in both in the original 62 for (const name of Object.keys(origPeer)) { 63 if (origProd[name] !== undefined && newPeer[name] !== undefined) { 64 result.dependencies = result.dependencies || {} 65 result.dependencies[name] = newPeer[name] 66 } 67 } 68 } 69 70 return result 71} 72 73updateDependencies.knownKeys = depTypes 74 75module.exports = updateDependencies 76