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