11cb0ef41Sopenharmony_ci 21cb0ef41Sopenharmony_ciconst promzard = require('promzard') 31cb0ef41Sopenharmony_ciconst path = require('path') 41cb0ef41Sopenharmony_ciconst fs = require('fs/promises') 51cb0ef41Sopenharmony_ciconst semver = require('semver') 61cb0ef41Sopenharmony_ciconst read = require('read') 71cb0ef41Sopenharmony_ciconst util = require('util') 81cb0ef41Sopenharmony_ciconst rpj = require('read-package-json') 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst def = require.resolve('./default-input.js') 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci// to validate the data object at the end as a worthwhile package 131cb0ef41Sopenharmony_ci// and assign default values for things. 141cb0ef41Sopenharmony_ciconst _extraSet = rpj.extraSet 151cb0ef41Sopenharmony_ciconst _rpj = util.promisify(rpj) 161cb0ef41Sopenharmony_ciconst _rpjExtras = util.promisify(rpj.extras) 171cb0ef41Sopenharmony_ciconst readPkgJson = async (file, pkg) => { 181cb0ef41Sopenharmony_ci // only do a few of these. no need for mans or contributors if they're in the files 191cb0ef41Sopenharmony_ci rpj.extraSet = _extraSet.filter(f => f.name !== 'authors' && f.name !== 'mans') 201cb0ef41Sopenharmony_ci const p = pkg ? _rpjExtras(file, pkg) : _rpj(file) 211cb0ef41Sopenharmony_ci return p.catch(() => ({})).finally(() => rpj.extraSet = _extraSet) 221cb0ef41Sopenharmony_ci} 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciconst isYes = (c) => !!(c.get('yes') || c.get('y') || c.get('force') || c.get('f')) 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ciconst getConfig = (c = {}) => { 271cb0ef41Sopenharmony_ci // accept either a plain-jane object, or a config object with a "get" method. 281cb0ef41Sopenharmony_ci if (typeof c.get !== 'function') { 291cb0ef41Sopenharmony_ci const data = c 301cb0ef41Sopenharmony_ci return { 311cb0ef41Sopenharmony_ci get: (k) => data[k], 321cb0ef41Sopenharmony_ci toJSON: () => data, 331cb0ef41Sopenharmony_ci } 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci return c 361cb0ef41Sopenharmony_ci} 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciconst stringifyPerson = (p) => { 391cb0ef41Sopenharmony_ci if (typeof p === 'string') { 401cb0ef41Sopenharmony_ci return p 411cb0ef41Sopenharmony_ci } 421cb0ef41Sopenharmony_ci const { name = '', url, web, email, mail } = p 431cb0ef41Sopenharmony_ci const u = url || web 441cb0ef41Sopenharmony_ci const e = email || mail 451cb0ef41Sopenharmony_ci return `${name}${e ? ` <${e}>` : ''}${u ? ` (${u})` : ''}` 461cb0ef41Sopenharmony_ci} 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciasync function init (dir, input = def, c = {}) { 491cb0ef41Sopenharmony_ci const config = getConfig(c) 501cb0ef41Sopenharmony_ci const yes = isYes(config) 511cb0ef41Sopenharmony_ci const packageFile = path.resolve(dir, 'package.json') 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci const pkg = await readPkgJson(packageFile) 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci if (!semver.valid(pkg.version)) { 561cb0ef41Sopenharmony_ci delete pkg.version 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci // make sure that the input is valid. if not, use the default 601cb0ef41Sopenharmony_ci const pzData = await promzard(path.resolve(input), { 611cb0ef41Sopenharmony_ci yes, 621cb0ef41Sopenharmony_ci config, 631cb0ef41Sopenharmony_ci filename: packageFile, 641cb0ef41Sopenharmony_ci dirname: path.dirname(packageFile), 651cb0ef41Sopenharmony_ci basename: path.basename(path.dirname(packageFile)), 661cb0ef41Sopenharmony_ci package: pkg, 671cb0ef41Sopenharmony_ci }, { backupFile: def }) 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci for (const [k, v] of Object.entries(pzData)) { 701cb0ef41Sopenharmony_ci if (v != null) { 711cb0ef41Sopenharmony_ci pkg[k] = v 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci const pkgExtras = await readPkgJson(packageFile, pkg) 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci // turn the objects into somewhat more humane strings. 781cb0ef41Sopenharmony_ci if (pkgExtras.author) { 791cb0ef41Sopenharmony_ci pkgExtras.author = stringifyPerson(pkgExtras.author) 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci for (const set of ['maintainers', 'contributors']) { 831cb0ef41Sopenharmony_ci if (Array.isArray(pkgExtras[set])) { 841cb0ef41Sopenharmony_ci pkgExtras[set] = pkgExtras[set].map(stringifyPerson) 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci // no need for the readme now. 891cb0ef41Sopenharmony_ci delete pkgExtras.readme 901cb0ef41Sopenharmony_ci delete pkgExtras.readmeFilename 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci // really don't want to have this lying around in the file 931cb0ef41Sopenharmony_ci delete pkgExtras._id 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci // ditto 961cb0ef41Sopenharmony_ci delete pkgExtras.gitHead 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci // if the repo is empty, remove it. 991cb0ef41Sopenharmony_ci if (!pkgExtras.repository) { 1001cb0ef41Sopenharmony_ci delete pkgExtras.repository 1011cb0ef41Sopenharmony_ci } 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci // readJson filters out empty descriptions, but init-package-json 1041cb0ef41Sopenharmony_ci // traditionally leaves them alone 1051cb0ef41Sopenharmony_ci if (!pkgExtras.description) { 1061cb0ef41Sopenharmony_ci pkgExtras.description = pzData.description 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci // optionalDependencies don't need to be repeated in two places 1101cb0ef41Sopenharmony_ci if (pkgExtras.dependencies) { 1111cb0ef41Sopenharmony_ci if (pkgExtras.optionalDependencies) { 1121cb0ef41Sopenharmony_ci for (const name of Object.keys(pkgExtras.optionalDependencies)) { 1131cb0ef41Sopenharmony_ci delete pkgExtras.dependencies[name] 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci } 1161cb0ef41Sopenharmony_ci if (Object.keys(pkgExtras.dependencies).length === 0) { 1171cb0ef41Sopenharmony_ci delete pkgExtras.dependencies 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci } 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci const stringified = JSON.stringify(pkgExtras, null, 2) + '\n' 1221cb0ef41Sopenharmony_ci const msg = util.format('%s:\n\n%s\n', packageFile, stringified) 1231cb0ef41Sopenharmony_ci const write = () => fs.writeFile(packageFile, stringified, 'utf8') 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci if (yes) { 1261cb0ef41Sopenharmony_ci await write() 1271cb0ef41Sopenharmony_ci if (!config.get('silent')) { 1281cb0ef41Sopenharmony_ci console.log(`Wrote to ${msg}`) 1291cb0ef41Sopenharmony_ci } 1301cb0ef41Sopenharmony_ci return pkgExtras 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci console.log(`About to write to ${msg}`) 1341cb0ef41Sopenharmony_ci const ok = await read({ prompt: 'Is this OK? ', default: 'yes' }) 1351cb0ef41Sopenharmony_ci if (!ok || !ok.toLowerCase().startsWith('y')) { 1361cb0ef41Sopenharmony_ci console.log('Aborted.') 1371cb0ef41Sopenharmony_ci return 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci await write() 1411cb0ef41Sopenharmony_ci return pkgExtras 1421cb0ef41Sopenharmony_ci} 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_cimodule.exports = init 1451cb0ef41Sopenharmony_cimodule.exports.yes = isYes 146