1// pass in a manifest with a 'bin' field here, and it'll turn it 2// into a properly santized bin object 3const { join, basename } = require('path') 4 5const normalize = pkg => 6 !pkg.bin ? removeBin(pkg) 7 : typeof pkg.bin === 'string' ? normalizeString(pkg) 8 : Array.isArray(pkg.bin) ? normalizeArray(pkg) 9 : typeof pkg.bin === 'object' ? normalizeObject(pkg) 10 : removeBin(pkg) 11 12const normalizeString = pkg => { 13 if (!pkg.name) { 14 return removeBin(pkg) 15 } 16 pkg.bin = { [pkg.name]: pkg.bin } 17 return normalizeObject(pkg) 18} 19 20const normalizeArray = pkg => { 21 pkg.bin = pkg.bin.reduce((acc, k) => { 22 acc[basename(k)] = k 23 return acc 24 }, {}) 25 return normalizeObject(pkg) 26} 27 28const removeBin = pkg => { 29 delete pkg.bin 30 return pkg 31} 32 33const normalizeObject = pkg => { 34 const orig = pkg.bin 35 const clean = {} 36 let hasBins = false 37 Object.keys(orig).forEach(binKey => { 38 const base = join('/', basename(binKey.replace(/\\|:/g, '/'))).slice(1) 39 40 if (typeof orig[binKey] !== 'string' || !base) { 41 return 42 } 43 44 const binTarget = join('/', orig[binKey].replace(/\\/g, '/')) 45 .replace(/\\/g, '/').slice(1) 46 47 if (!binTarget) { 48 return 49 } 50 51 clean[base] = binTarget 52 hasBins = true 53 }) 54 55 if (hasBins) { 56 pkg.bin = clean 57 } else { 58 delete pkg.bin 59 } 60 61 return pkg 62} 63 64module.exports = normalize 65