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 pkg.bin = { [pkg.name]: pkg.bin } 16 return normalizeObject(pkg) 17} 18 19const normalizeArray = pkg => { 20 pkg.bin = pkg.bin.reduce((acc, k) => { 21 acc[basename(k)] = k 22 return acc 23 }, {}) 24 return normalizeObject(pkg) 25} 26 27const removeBin = pkg => { 28 delete pkg.bin 29 return pkg 30} 31 32const normalizeObject = pkg => { 33 const orig = pkg.bin 34 const clean = {} 35 let hasBins = false 36 Object.keys(orig).forEach(binKey => { 37 const base = join('/', basename(binKey.replace(/\\|:/g, '/'))).substr(1) 38 39 if (typeof orig[binKey] !== 'string' || !base) 40 return 41 42 const binTarget = join('/', orig[binKey]) 43 .replace(/\\/g, '/').substr(1) 44 45 if (!binTarget) 46 return 47 48 clean[base] = binTarget 49 hasBins = true 50 }) 51 52 if (hasBins) 53 pkg.bin = clean 54 else 55 delete pkg.bin 56 57 return pkg 58} 59 60module.exports = normalize 61