11cb0ef41Sopenharmony_civar fs = require('fs') 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_civar path = require('path') 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_civar { glob } = require('glob') 61cb0ef41Sopenharmony_civar normalizeData = require('normalize-package-data') 71cb0ef41Sopenharmony_civar safeJSON = require('json-parse-even-better-errors') 81cb0ef41Sopenharmony_civar util = require('util') 91cb0ef41Sopenharmony_civar normalizePackageBin = require('npm-normalize-package-bin') 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_cimodule.exports = readJson 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci// put more stuff on here to customize. 141cb0ef41Sopenharmony_cireadJson.extraSet = [ 151cb0ef41Sopenharmony_ci bundleDependencies, 161cb0ef41Sopenharmony_ci gypfile, 171cb0ef41Sopenharmony_ci serverjs, 181cb0ef41Sopenharmony_ci scriptpath, 191cb0ef41Sopenharmony_ci authors, 201cb0ef41Sopenharmony_ci readme, 211cb0ef41Sopenharmony_ci mans, 221cb0ef41Sopenharmony_ci bins, 231cb0ef41Sopenharmony_ci githead, 241cb0ef41Sopenharmony_ci fillTypes, 251cb0ef41Sopenharmony_ci] 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_civar typoWarned = {} 281cb0ef41Sopenharmony_civar cache = {} 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_cifunction readJson (file, log_, strict_, cb_) { 311cb0ef41Sopenharmony_ci var log, strict, cb 321cb0ef41Sopenharmony_ci for (var i = 1; i < arguments.length - 1; i++) { 331cb0ef41Sopenharmony_ci if (typeof arguments[i] === 'boolean') { 341cb0ef41Sopenharmony_ci strict = arguments[i] 351cb0ef41Sopenharmony_ci } else if (typeof arguments[i] === 'function') { 361cb0ef41Sopenharmony_ci log = arguments[i] 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci if (!log) { 411cb0ef41Sopenharmony_ci log = function () {} 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci cb = arguments[arguments.length - 1] 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci readJson_(file, log, strict, cb) 461cb0ef41Sopenharmony_ci} 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_cifunction readJson_ (file, log, strict, cb) { 491cb0ef41Sopenharmony_ci fs.readFile(file, 'utf8', function (er, d) { 501cb0ef41Sopenharmony_ci parseJson(file, er, d, log, strict, cb) 511cb0ef41Sopenharmony_ci }) 521cb0ef41Sopenharmony_ci} 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_cifunction stripBOM (content) { 551cb0ef41Sopenharmony_ci // Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) 561cb0ef41Sopenharmony_ci // because the buffer-to-string conversion in `fs.readFileSync()` 571cb0ef41Sopenharmony_ci // translates it to FEFF, the UTF-16 BOM. 581cb0ef41Sopenharmony_ci if (content.charCodeAt(0) === 0xFEFF) { 591cb0ef41Sopenharmony_ci content = content.slice(1) 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci return content 621cb0ef41Sopenharmony_ci} 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_cifunction jsonClone (obj) { 651cb0ef41Sopenharmony_ci if (obj == null) { 661cb0ef41Sopenharmony_ci return obj 671cb0ef41Sopenharmony_ci } else if (Array.isArray(obj)) { 681cb0ef41Sopenharmony_ci var newarr = new Array(obj.length) 691cb0ef41Sopenharmony_ci for (var ii in obj) { 701cb0ef41Sopenharmony_ci newarr[ii] = jsonClone(obj[ii]) 711cb0ef41Sopenharmony_ci } 721cb0ef41Sopenharmony_ci return newarr 731cb0ef41Sopenharmony_ci } else if (typeof obj === 'object') { 741cb0ef41Sopenharmony_ci var newobj = {} 751cb0ef41Sopenharmony_ci for (var kk in obj) { 761cb0ef41Sopenharmony_ci newobj[kk] = jsonClone(obj[kk]) 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci return newobj 791cb0ef41Sopenharmony_ci } else { 801cb0ef41Sopenharmony_ci return obj 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci} 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_cifunction parseJson (file, er, d, log, strict, cb) { 851cb0ef41Sopenharmony_ci if (er && er.code === 'ENOENT') { 861cb0ef41Sopenharmony_ci return fs.stat(path.dirname(file), function (err, stat) { 871cb0ef41Sopenharmony_ci if (!err && stat && !stat.isDirectory()) { 881cb0ef41Sopenharmony_ci // ENOTDIR isn't used on Windows, but npm expects it. 891cb0ef41Sopenharmony_ci er = Object.create(er) 901cb0ef41Sopenharmony_ci er.code = 'ENOTDIR' 911cb0ef41Sopenharmony_ci return cb(er) 921cb0ef41Sopenharmony_ci } else { 931cb0ef41Sopenharmony_ci return indexjs(file, er, log, strict, cb) 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci }) 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci if (er) { 981cb0ef41Sopenharmony_ci return cb(er) 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci if (cache[d]) { 1021cb0ef41Sopenharmony_ci return cb(null, jsonClone(cache[d])) 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci var data 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci try { 1081cb0ef41Sopenharmony_ci data = safeJSON(stripBOM(d)) 1091cb0ef41Sopenharmony_ci for (var key in data) { 1101cb0ef41Sopenharmony_ci if (/^_/.test(key)) { 1111cb0ef41Sopenharmony_ci delete data[key] 1121cb0ef41Sopenharmony_ci } 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci } catch (jsonErr) { 1151cb0ef41Sopenharmony_ci data = parseIndex(d) 1161cb0ef41Sopenharmony_ci if (!data) { 1171cb0ef41Sopenharmony_ci return cb(parseError(jsonErr, file)) 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci } 1201cb0ef41Sopenharmony_ci extrasCached(file, d, data, log, strict, cb) 1211cb0ef41Sopenharmony_ci} 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_cifunction extrasCached (file, d, data, log, strict, cb) { 1241cb0ef41Sopenharmony_ci extras(file, data, log, strict, function (err, extrasData) { 1251cb0ef41Sopenharmony_ci if (!err) { 1261cb0ef41Sopenharmony_ci cache[d] = jsonClone(extrasData) 1271cb0ef41Sopenharmony_ci } 1281cb0ef41Sopenharmony_ci cb(err, extrasData) 1291cb0ef41Sopenharmony_ci }) 1301cb0ef41Sopenharmony_ci} 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_cifunction indexjs (file, er, log, strict, cb) { 1331cb0ef41Sopenharmony_ci if (path.basename(file) === 'index.js') { 1341cb0ef41Sopenharmony_ci return cb(er) 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci var index = path.resolve(path.dirname(file), 'index.js') 1381cb0ef41Sopenharmony_ci fs.readFile(index, 'utf8', function (er2, d) { 1391cb0ef41Sopenharmony_ci if (er2) { 1401cb0ef41Sopenharmony_ci return cb(er) 1411cb0ef41Sopenharmony_ci } 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci if (cache[d]) { 1441cb0ef41Sopenharmony_ci return cb(null, cache[d]) 1451cb0ef41Sopenharmony_ci } 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci var data = parseIndex(d) 1481cb0ef41Sopenharmony_ci if (!data) { 1491cb0ef41Sopenharmony_ci return cb(er) 1501cb0ef41Sopenharmony_ci } 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci extrasCached(file, d, data, log, strict, cb) 1531cb0ef41Sopenharmony_ci }) 1541cb0ef41Sopenharmony_ci} 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_cireadJson.extras = extras 1571cb0ef41Sopenharmony_cifunction extras (file, data, log_, strict_, cb_) { 1581cb0ef41Sopenharmony_ci var log, strict, cb 1591cb0ef41Sopenharmony_ci for (var i = 2; i < arguments.length - 1; i++) { 1601cb0ef41Sopenharmony_ci if (typeof arguments[i] === 'boolean') { 1611cb0ef41Sopenharmony_ci strict = arguments[i] 1621cb0ef41Sopenharmony_ci } else if (typeof arguments[i] === 'function') { 1631cb0ef41Sopenharmony_ci log = arguments[i] 1641cb0ef41Sopenharmony_ci } 1651cb0ef41Sopenharmony_ci } 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci if (!log) { 1681cb0ef41Sopenharmony_ci log = function () {} 1691cb0ef41Sopenharmony_ci } 1701cb0ef41Sopenharmony_ci cb = arguments[i] 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci var set = readJson.extraSet 1731cb0ef41Sopenharmony_ci var n = set.length 1741cb0ef41Sopenharmony_ci var errState = null 1751cb0ef41Sopenharmony_ci set.forEach(function (fn) { 1761cb0ef41Sopenharmony_ci fn(file, data, then) 1771cb0ef41Sopenharmony_ci }) 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci function then (er) { 1801cb0ef41Sopenharmony_ci if (errState) { 1811cb0ef41Sopenharmony_ci return 1821cb0ef41Sopenharmony_ci } 1831cb0ef41Sopenharmony_ci if (er) { 1841cb0ef41Sopenharmony_ci return cb(errState = er) 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci if (--n > 0) { 1871cb0ef41Sopenharmony_ci return 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci final(file, data, log, strict, cb) 1901cb0ef41Sopenharmony_ci } 1911cb0ef41Sopenharmony_ci} 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_cifunction scriptpath (file, data, cb) { 1941cb0ef41Sopenharmony_ci if (!data.scripts) { 1951cb0ef41Sopenharmony_ci return cb(null, data) 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci var k = Object.keys(data.scripts) 1981cb0ef41Sopenharmony_ci k.forEach(scriptpath_, data.scripts) 1991cb0ef41Sopenharmony_ci cb(null, data) 2001cb0ef41Sopenharmony_ci} 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_cifunction scriptpath_ (key) { 2031cb0ef41Sopenharmony_ci var s = this[key] 2041cb0ef41Sopenharmony_ci // This is never allowed, and only causes problems 2051cb0ef41Sopenharmony_ci if (typeof s !== 'string') { 2061cb0ef41Sopenharmony_ci return delete this[key] 2071cb0ef41Sopenharmony_ci } 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci var spre = /^(\.[/\\])?node_modules[/\\].bin[\\/]/ 2101cb0ef41Sopenharmony_ci if (s.match(spre)) { 2111cb0ef41Sopenharmony_ci this[key] = this[key].replace(spre, '') 2121cb0ef41Sopenharmony_ci } 2131cb0ef41Sopenharmony_ci} 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_cifunction gypfile (file, data, cb) { 2161cb0ef41Sopenharmony_ci var dir = path.dirname(file) 2171cb0ef41Sopenharmony_ci var s = data.scripts || {} 2181cb0ef41Sopenharmony_ci if (s.install || s.preinstall) { 2191cb0ef41Sopenharmony_ci return cb(null, data) 2201cb0ef41Sopenharmony_ci } 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci if (data.gypfile === false) { 2231cb0ef41Sopenharmony_ci return cb(null, data) 2241cb0ef41Sopenharmony_ci } 2251cb0ef41Sopenharmony_ci glob('*.gyp', { cwd: dir }) 2261cb0ef41Sopenharmony_ci .then(files => gypfile_(file, data, files, cb)) 2271cb0ef41Sopenharmony_ci .catch(er => cb(er)) 2281cb0ef41Sopenharmony_ci} 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_cifunction gypfile_ (file, data, files, cb) { 2311cb0ef41Sopenharmony_ci if (!files.length) { 2321cb0ef41Sopenharmony_ci return cb(null, data) 2331cb0ef41Sopenharmony_ci } 2341cb0ef41Sopenharmony_ci var s = data.scripts || {} 2351cb0ef41Sopenharmony_ci s.install = 'node-gyp rebuild' 2361cb0ef41Sopenharmony_ci data.scripts = s 2371cb0ef41Sopenharmony_ci data.gypfile = true 2381cb0ef41Sopenharmony_ci return cb(null, data) 2391cb0ef41Sopenharmony_ci} 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_cifunction serverjs (file, data, cb) { 2421cb0ef41Sopenharmony_ci var dir = path.dirname(file) 2431cb0ef41Sopenharmony_ci var s = data.scripts || {} 2441cb0ef41Sopenharmony_ci if (s.start) { 2451cb0ef41Sopenharmony_ci return cb(null, data) 2461cb0ef41Sopenharmony_ci } 2471cb0ef41Sopenharmony_ci fs.access(path.join(dir, 'server.js'), (err) => { 2481cb0ef41Sopenharmony_ci if (!err) { 2491cb0ef41Sopenharmony_ci s.start = 'node server.js' 2501cb0ef41Sopenharmony_ci data.scripts = s 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci return cb(null, data) 2531cb0ef41Sopenharmony_ci }) 2541cb0ef41Sopenharmony_ci} 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_cifunction authors (file, data, cb) { 2571cb0ef41Sopenharmony_ci if (data.contributors) { 2581cb0ef41Sopenharmony_ci return cb(null, data) 2591cb0ef41Sopenharmony_ci } 2601cb0ef41Sopenharmony_ci var af = path.resolve(path.dirname(file), 'AUTHORS') 2611cb0ef41Sopenharmony_ci fs.readFile(af, 'utf8', function (er, ad) { 2621cb0ef41Sopenharmony_ci // ignore error. just checking it. 2631cb0ef41Sopenharmony_ci if (er) { 2641cb0ef41Sopenharmony_ci return cb(null, data) 2651cb0ef41Sopenharmony_ci } 2661cb0ef41Sopenharmony_ci authors_(file, data, ad, cb) 2671cb0ef41Sopenharmony_ci }) 2681cb0ef41Sopenharmony_ci} 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_cifunction authors_ (file, data, ad, cb) { 2711cb0ef41Sopenharmony_ci ad = ad.split(/\r?\n/g).map(function (line) { 2721cb0ef41Sopenharmony_ci return line.replace(/^\s*#.*$/, '').trim() 2731cb0ef41Sopenharmony_ci }).filter(function (line) { 2741cb0ef41Sopenharmony_ci return line 2751cb0ef41Sopenharmony_ci }) 2761cb0ef41Sopenharmony_ci data.contributors = ad 2771cb0ef41Sopenharmony_ci return cb(null, data) 2781cb0ef41Sopenharmony_ci} 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_cifunction readme (file, data, cb) { 2811cb0ef41Sopenharmony_ci if (data.readme) { 2821cb0ef41Sopenharmony_ci return cb(null, data) 2831cb0ef41Sopenharmony_ci } 2841cb0ef41Sopenharmony_ci var dir = path.dirname(file) 2851cb0ef41Sopenharmony_ci var globOpts = { cwd: dir, nocase: true, mark: true } 2861cb0ef41Sopenharmony_ci glob('{README,README.*}', globOpts) 2871cb0ef41Sopenharmony_ci .then(files => { 2881cb0ef41Sopenharmony_ci // don't accept directories. 2891cb0ef41Sopenharmony_ci files = files.filter(function (filtered) { 2901cb0ef41Sopenharmony_ci return !filtered.match(/\/$/) 2911cb0ef41Sopenharmony_ci }) 2921cb0ef41Sopenharmony_ci if (!files.length) { 2931cb0ef41Sopenharmony_ci return cb() 2941cb0ef41Sopenharmony_ci } 2951cb0ef41Sopenharmony_ci var fn = preferMarkdownReadme(files) 2961cb0ef41Sopenharmony_ci var rm = path.resolve(dir, fn) 2971cb0ef41Sopenharmony_ci return readme_(file, data, rm, cb) 2981cb0ef41Sopenharmony_ci }) 2991cb0ef41Sopenharmony_ci .catch(er => cb(er)) 3001cb0ef41Sopenharmony_ci} 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_cifunction preferMarkdownReadme (files) { 3031cb0ef41Sopenharmony_ci var fallback = 0 3041cb0ef41Sopenharmony_ci var re = /\.m?a?r?k?d?o?w?n?$/i 3051cb0ef41Sopenharmony_ci for (var i = 0; i < files.length; i++) { 3061cb0ef41Sopenharmony_ci if (files[i].match(re)) { 3071cb0ef41Sopenharmony_ci return files[i] 3081cb0ef41Sopenharmony_ci } else if (files[i].match(/README$/)) { 3091cb0ef41Sopenharmony_ci fallback = i 3101cb0ef41Sopenharmony_ci } 3111cb0ef41Sopenharmony_ci } 3121cb0ef41Sopenharmony_ci // prefer README.md, followed by README; otherwise, return 3131cb0ef41Sopenharmony_ci // the first filename (which could be README) 3141cb0ef41Sopenharmony_ci return files[fallback] 3151cb0ef41Sopenharmony_ci} 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_cifunction readme_ (file, data, rm, cb) { 3181cb0ef41Sopenharmony_ci var rmfn = path.basename(rm) 3191cb0ef41Sopenharmony_ci fs.readFile(rm, 'utf8', function (er, rmData) { 3201cb0ef41Sopenharmony_ci // maybe not readable, or something. 3211cb0ef41Sopenharmony_ci if (er) { 3221cb0ef41Sopenharmony_ci return cb() 3231cb0ef41Sopenharmony_ci } 3241cb0ef41Sopenharmony_ci data.readme = rmData 3251cb0ef41Sopenharmony_ci data.readmeFilename = rmfn 3261cb0ef41Sopenharmony_ci return cb(er, data) 3271cb0ef41Sopenharmony_ci }) 3281cb0ef41Sopenharmony_ci} 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_cifunction mans (file, data, cb) { 3311cb0ef41Sopenharmony_ci let cwd = data.directories && data.directories.man 3321cb0ef41Sopenharmony_ci if (data.man || !cwd) { 3331cb0ef41Sopenharmony_ci return cb(null, data) 3341cb0ef41Sopenharmony_ci } 3351cb0ef41Sopenharmony_ci const dirname = path.dirname(file) 3361cb0ef41Sopenharmony_ci cwd = path.resolve(path.dirname(file), cwd) 3371cb0ef41Sopenharmony_ci glob('**/*.[0-9]', { cwd }) 3381cb0ef41Sopenharmony_ci .then(mansGlob => { 3391cb0ef41Sopenharmony_ci data.man = mansGlob.map(man => 3401cb0ef41Sopenharmony_ci path.relative(dirname, path.join(cwd, man)).split(path.sep).join('/') 3411cb0ef41Sopenharmony_ci ) 3421cb0ef41Sopenharmony_ci return cb(null, data) 3431cb0ef41Sopenharmony_ci }) 3441cb0ef41Sopenharmony_ci .catch(er => cb(er)) 3451cb0ef41Sopenharmony_ci} 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_cifunction bins (file, data, cb) { 3481cb0ef41Sopenharmony_ci data = normalizePackageBin(data) 3491cb0ef41Sopenharmony_ci 3501cb0ef41Sopenharmony_ci var m = data.directories && data.directories.bin 3511cb0ef41Sopenharmony_ci if (data.bin || !m) { 3521cb0ef41Sopenharmony_ci return cb(null, data) 3531cb0ef41Sopenharmony_ci } 3541cb0ef41Sopenharmony_ci 3551cb0ef41Sopenharmony_ci m = path.resolve(path.dirname(file), path.join('.', path.join('/', m))) 3561cb0ef41Sopenharmony_ci glob('**', { cwd: m }) 3571cb0ef41Sopenharmony_ci .then(binsGlob => bins_(file, data, binsGlob, cb)) 3581cb0ef41Sopenharmony_ci .catch(er => cb(er)) 3591cb0ef41Sopenharmony_ci} 3601cb0ef41Sopenharmony_ci 3611cb0ef41Sopenharmony_cifunction bins_ (file, data, binsGlob, cb) { 3621cb0ef41Sopenharmony_ci var m = (data.directories && data.directories.bin) || '.' 3631cb0ef41Sopenharmony_ci data.bin = binsGlob.reduce(function (acc, mf) { 3641cb0ef41Sopenharmony_ci if (mf && mf.charAt(0) !== '.') { 3651cb0ef41Sopenharmony_ci var f = path.basename(mf) 3661cb0ef41Sopenharmony_ci acc[f] = path.join(m, mf) 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci return acc 3691cb0ef41Sopenharmony_ci }, {}) 3701cb0ef41Sopenharmony_ci return cb(null, normalizePackageBin(data)) 3711cb0ef41Sopenharmony_ci} 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_cifunction bundleDependencies (file, data, cb) { 3741cb0ef41Sopenharmony_ci var bd = 'bundleDependencies' 3751cb0ef41Sopenharmony_ci var bdd = 'bundledDependencies' 3761cb0ef41Sopenharmony_ci // normalize key name 3771cb0ef41Sopenharmony_ci if (data[bdd] !== undefined) { 3781cb0ef41Sopenharmony_ci if (data[bd] === undefined) { 3791cb0ef41Sopenharmony_ci data[bd] = data[bdd] 3801cb0ef41Sopenharmony_ci } 3811cb0ef41Sopenharmony_ci delete data[bdd] 3821cb0ef41Sopenharmony_ci } 3831cb0ef41Sopenharmony_ci if (data[bd] === false) { 3841cb0ef41Sopenharmony_ci delete data[bd] 3851cb0ef41Sopenharmony_ci } else if (data[bd] === true) { 3861cb0ef41Sopenharmony_ci data[bd] = Object.keys(data.dependencies || {}) 3871cb0ef41Sopenharmony_ci } else if (data[bd] !== undefined && !Array.isArray(data[bd])) { 3881cb0ef41Sopenharmony_ci delete data[bd] 3891cb0ef41Sopenharmony_ci } 3901cb0ef41Sopenharmony_ci return cb(null, data) 3911cb0ef41Sopenharmony_ci} 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_cifunction githead (file, data, cb) { 3941cb0ef41Sopenharmony_ci if (data.gitHead) { 3951cb0ef41Sopenharmony_ci return cb(null, data) 3961cb0ef41Sopenharmony_ci } 3971cb0ef41Sopenharmony_ci var dir = path.dirname(file) 3981cb0ef41Sopenharmony_ci var head = path.resolve(dir, '.git/HEAD') 3991cb0ef41Sopenharmony_ci fs.readFile(head, 'utf8', function (er, headData) { 4001cb0ef41Sopenharmony_ci if (er) { 4011cb0ef41Sopenharmony_ci var parent = path.dirname(dir) 4021cb0ef41Sopenharmony_ci if (parent === dir) { 4031cb0ef41Sopenharmony_ci return cb(null, data) 4041cb0ef41Sopenharmony_ci } 4051cb0ef41Sopenharmony_ci return githead(dir, data, cb) 4061cb0ef41Sopenharmony_ci } 4071cb0ef41Sopenharmony_ci githead_(data, dir, headData, cb) 4081cb0ef41Sopenharmony_ci }) 4091cb0ef41Sopenharmony_ci} 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_cifunction githead_ (data, dir, head, cb) { 4121cb0ef41Sopenharmony_ci if (!head.match(/^ref: /)) { 4131cb0ef41Sopenharmony_ci data.gitHead = head.trim() 4141cb0ef41Sopenharmony_ci return cb(null, data) 4151cb0ef41Sopenharmony_ci } 4161cb0ef41Sopenharmony_ci var headRef = head.replace(/^ref: /, '').trim() 4171cb0ef41Sopenharmony_ci var headFile = path.resolve(dir, '.git', headRef) 4181cb0ef41Sopenharmony_ci fs.readFile(headFile, 'utf8', function (er, headData) { 4191cb0ef41Sopenharmony_ci if (er || !headData) { 4201cb0ef41Sopenharmony_ci var packFile = path.resolve(dir, '.git/packed-refs') 4211cb0ef41Sopenharmony_ci return fs.readFile(packFile, 'utf8', function (readFileErr, refs) { 4221cb0ef41Sopenharmony_ci if (readFileErr || !refs) { 4231cb0ef41Sopenharmony_ci return cb(null, data) 4241cb0ef41Sopenharmony_ci } 4251cb0ef41Sopenharmony_ci refs = refs.split('\n') 4261cb0ef41Sopenharmony_ci for (var i = 0; i < refs.length; i++) { 4271cb0ef41Sopenharmony_ci var match = refs[i].match(/^([0-9a-f]{40}) (.+)$/) 4281cb0ef41Sopenharmony_ci if (match && match[2].trim() === headRef) { 4291cb0ef41Sopenharmony_ci data.gitHead = match[1] 4301cb0ef41Sopenharmony_ci break 4311cb0ef41Sopenharmony_ci } 4321cb0ef41Sopenharmony_ci } 4331cb0ef41Sopenharmony_ci return cb(null, data) 4341cb0ef41Sopenharmony_ci }) 4351cb0ef41Sopenharmony_ci } 4361cb0ef41Sopenharmony_ci headData = headData.replace(/^ref: /, '').trim() 4371cb0ef41Sopenharmony_ci data.gitHead = headData 4381cb0ef41Sopenharmony_ci return cb(null, data) 4391cb0ef41Sopenharmony_ci }) 4401cb0ef41Sopenharmony_ci} 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_ci/** 4431cb0ef41Sopenharmony_ci * Warn if the bin references don't point to anything. This might be better in 4441cb0ef41Sopenharmony_ci * normalize-package-data if it had access to the file path. 4451cb0ef41Sopenharmony_ci */ 4461cb0ef41Sopenharmony_cifunction checkBinReferences_ (file, data, warn, cb) { 4471cb0ef41Sopenharmony_ci if (!(data.bin instanceof Object)) { 4481cb0ef41Sopenharmony_ci return cb() 4491cb0ef41Sopenharmony_ci } 4501cb0ef41Sopenharmony_ci 4511cb0ef41Sopenharmony_ci var keys = Object.keys(data.bin) 4521cb0ef41Sopenharmony_ci var keysLeft = keys.length 4531cb0ef41Sopenharmony_ci if (!keysLeft) { 4541cb0ef41Sopenharmony_ci return cb() 4551cb0ef41Sopenharmony_ci } 4561cb0ef41Sopenharmony_ci 4571cb0ef41Sopenharmony_ci function handleExists (relName, result) { 4581cb0ef41Sopenharmony_ci keysLeft-- 4591cb0ef41Sopenharmony_ci if (!result) { 4601cb0ef41Sopenharmony_ci warn('No bin file found at ' + relName) 4611cb0ef41Sopenharmony_ci } 4621cb0ef41Sopenharmony_ci if (!keysLeft) { 4631cb0ef41Sopenharmony_ci cb() 4641cb0ef41Sopenharmony_ci } 4651cb0ef41Sopenharmony_ci } 4661cb0ef41Sopenharmony_ci 4671cb0ef41Sopenharmony_ci keys.forEach(function (key) { 4681cb0ef41Sopenharmony_ci var dirName = path.dirname(file) 4691cb0ef41Sopenharmony_ci var relName = data.bin[key] 4701cb0ef41Sopenharmony_ci /* istanbul ignore if - impossible, bins have been normalized */ 4711cb0ef41Sopenharmony_ci if (typeof relName !== 'string') { 4721cb0ef41Sopenharmony_ci var msg = 'Bin filename for ' + key + 4731cb0ef41Sopenharmony_ci ' is not a string: ' + util.inspect(relName) 4741cb0ef41Sopenharmony_ci warn(msg) 4751cb0ef41Sopenharmony_ci delete data.bin[key] 4761cb0ef41Sopenharmony_ci handleExists(relName, true) 4771cb0ef41Sopenharmony_ci return 4781cb0ef41Sopenharmony_ci } 4791cb0ef41Sopenharmony_ci var binPath = path.resolve(dirName, relName) 4801cb0ef41Sopenharmony_ci fs.stat(binPath, (err) => handleExists(relName, !err)) 4811cb0ef41Sopenharmony_ci }) 4821cb0ef41Sopenharmony_ci} 4831cb0ef41Sopenharmony_ci 4841cb0ef41Sopenharmony_cifunction final (file, data, log, strict, cb) { 4851cb0ef41Sopenharmony_ci var pId = makePackageId(data) 4861cb0ef41Sopenharmony_ci 4871cb0ef41Sopenharmony_ci function warn (msg) { 4881cb0ef41Sopenharmony_ci if (typoWarned[pId]) { 4891cb0ef41Sopenharmony_ci return 4901cb0ef41Sopenharmony_ci } 4911cb0ef41Sopenharmony_ci if (log) { 4921cb0ef41Sopenharmony_ci log('package.json', pId, msg) 4931cb0ef41Sopenharmony_ci } 4941cb0ef41Sopenharmony_ci } 4951cb0ef41Sopenharmony_ci 4961cb0ef41Sopenharmony_ci try { 4971cb0ef41Sopenharmony_ci normalizeData(data, warn, strict) 4981cb0ef41Sopenharmony_ci } catch (error) { 4991cb0ef41Sopenharmony_ci return cb(error) 5001cb0ef41Sopenharmony_ci } 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ci checkBinReferences_(file, data, warn, function () { 5031cb0ef41Sopenharmony_ci typoWarned[pId] = true 5041cb0ef41Sopenharmony_ci cb(null, data) 5051cb0ef41Sopenharmony_ci }) 5061cb0ef41Sopenharmony_ci} 5071cb0ef41Sopenharmony_ci 5081cb0ef41Sopenharmony_cifunction fillTypes (file, data, cb) { 5091cb0ef41Sopenharmony_ci var index = data.main || 'index.js' 5101cb0ef41Sopenharmony_ci 5111cb0ef41Sopenharmony_ci if (typeof index !== 'string') { 5121cb0ef41Sopenharmony_ci return cb(new TypeError('The "main" attribute must be of type string.')) 5131cb0ef41Sopenharmony_ci } 5141cb0ef41Sopenharmony_ci 5151cb0ef41Sopenharmony_ci // TODO exports is much more complicated than this in verbose format 5161cb0ef41Sopenharmony_ci // We need to support for instance 5171cb0ef41Sopenharmony_ci 5181cb0ef41Sopenharmony_ci // "exports": { 5191cb0ef41Sopenharmony_ci // ".": [ 5201cb0ef41Sopenharmony_ci // { 5211cb0ef41Sopenharmony_ci // "default": "./lib/npm.js" 5221cb0ef41Sopenharmony_ci // }, 5231cb0ef41Sopenharmony_ci // "./lib/npm.js" 5241cb0ef41Sopenharmony_ci // ], 5251cb0ef41Sopenharmony_ci // "./package.json": "./package.json" 5261cb0ef41Sopenharmony_ci // }, 5271cb0ef41Sopenharmony_ci // as well as conditional exports 5281cb0ef41Sopenharmony_ci 5291cb0ef41Sopenharmony_ci // if (data.exports && typeof data.exports === 'string') { 5301cb0ef41Sopenharmony_ci // index = data.exports 5311cb0ef41Sopenharmony_ci // } 5321cb0ef41Sopenharmony_ci 5331cb0ef41Sopenharmony_ci // if (data.exports && data.exports['.']) { 5341cb0ef41Sopenharmony_ci // index = data.exports['.'] 5351cb0ef41Sopenharmony_ci // if (typeof index !== 'string') { 5361cb0ef41Sopenharmony_ci // } 5371cb0ef41Sopenharmony_ci // } 5381cb0ef41Sopenharmony_ci 5391cb0ef41Sopenharmony_ci var extless = 5401cb0ef41Sopenharmony_ci path.join(path.dirname(index), path.basename(index, path.extname(index))) 5411cb0ef41Sopenharmony_ci var dts = `./${extless}.d.ts` 5421cb0ef41Sopenharmony_ci var dtsPath = path.join(path.dirname(file), dts) 5431cb0ef41Sopenharmony_ci var hasDTSFields = 'types' in data || 'typings' in data 5441cb0ef41Sopenharmony_ci if (!hasDTSFields && fs.existsSync(dtsPath)) { 5451cb0ef41Sopenharmony_ci data.types = dts.split(path.sep).join('/') 5461cb0ef41Sopenharmony_ci } 5471cb0ef41Sopenharmony_ci 5481cb0ef41Sopenharmony_ci cb(null, data) 5491cb0ef41Sopenharmony_ci} 5501cb0ef41Sopenharmony_ci 5511cb0ef41Sopenharmony_cifunction makePackageId (data) { 5521cb0ef41Sopenharmony_ci var name = cleanString(data.name) 5531cb0ef41Sopenharmony_ci var ver = cleanString(data.version) 5541cb0ef41Sopenharmony_ci return name + '@' + ver 5551cb0ef41Sopenharmony_ci} 5561cb0ef41Sopenharmony_ci 5571cb0ef41Sopenharmony_cifunction cleanString (str) { 5581cb0ef41Sopenharmony_ci return (!str || typeof (str) !== 'string') ? '' : str.trim() 5591cb0ef41Sopenharmony_ci} 5601cb0ef41Sopenharmony_ci 5611cb0ef41Sopenharmony_ci// /**package { "name": "foo", "version": "1.2.3", ... } **/ 5621cb0ef41Sopenharmony_cifunction parseIndex (data) { 5631cb0ef41Sopenharmony_ci data = data.split(/^\/\*\*package(?:\s|$)/m) 5641cb0ef41Sopenharmony_ci 5651cb0ef41Sopenharmony_ci if (data.length < 2) { 5661cb0ef41Sopenharmony_ci return null 5671cb0ef41Sopenharmony_ci } 5681cb0ef41Sopenharmony_ci data = data[1] 5691cb0ef41Sopenharmony_ci data = data.split(/\*\*\/$/m) 5701cb0ef41Sopenharmony_ci 5711cb0ef41Sopenharmony_ci if (data.length < 2) { 5721cb0ef41Sopenharmony_ci return null 5731cb0ef41Sopenharmony_ci } 5741cb0ef41Sopenharmony_ci data = data[0] 5751cb0ef41Sopenharmony_ci data = data.replace(/^\s*\*/mg, '') 5761cb0ef41Sopenharmony_ci 5771cb0ef41Sopenharmony_ci try { 5781cb0ef41Sopenharmony_ci return safeJSON(data) 5791cb0ef41Sopenharmony_ci } catch (er) { 5801cb0ef41Sopenharmony_ci return null 5811cb0ef41Sopenharmony_ci } 5821cb0ef41Sopenharmony_ci} 5831cb0ef41Sopenharmony_ci 5841cb0ef41Sopenharmony_cifunction parseError (ex, file) { 5851cb0ef41Sopenharmony_ci var e = new Error('Failed to parse json\n' + ex.message) 5861cb0ef41Sopenharmony_ci e.code = 'EJSONPARSE' 5871cb0ef41Sopenharmony_ci e.path = file 5881cb0ef41Sopenharmony_ci return e 5891cb0ef41Sopenharmony_ci} 590