Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
init-package-json.js148 linesDownload Raw Back to lib
1
2const promzard = require('promzard')
3const path = require('path')
4const semver = require('semver')
5const { read } = require('read')
6const util = require('util')
7const PackageJson = require('@npmcli/package-json')
8
9const def = require.resolve('./default-input.js')
10
11const extras = [
12  'bundleDependencies',
13  'gypfile',
14  'serverjs',
15  'scriptpath',
16  'readme',
17  'bin',
18  'githead',
19  'fillTypes',
20  'normalizeData',
21]
22
23const isYes = (c) => !!(c.get('yes') || c.get('y') || c.get('force') || c.get('f'))
24
25const getConfig = (c) => {
26  // accept either a plain-jane object, or a config object with a "get" method.
27  if (typeof c.get !== 'function') {
28    const data = c
29    return {
30      get: (k) => data[k],
31      toJSON: () => data,
32    }
33  }
34  return c
35}
36
37// Coverage disabled because this is just walking back the fixPeople
38// normalization from the normalizeData step and we don't need to re-test all
39// of those paths.
40/* istanbul ignore next */
41const stringifyPerson = (p) => {
42  const { name, url, web, email, mail } = p
43  const u = url || web
44  const e = email || mail
45  return `${name}${e ? ` <${e}>` : ''}${u ? ` (${u})` : ''}`
46}
47async function init (dir,
48  // TODO test for non-default definitions
49  /* istanbul ignore next */
50  input = def,
51  c = {}) {
52  const config = getConfig(c)
53  const yes = isYes(config)
54  const packageFile = path.resolve(dir, 'package.json')
55
56  // read what's already there to inform our prompts
57  const pkg = await PackageJson.load(dir, { create: true })
58  await pkg.normalize()
59
60  if (!semver.valid(pkg.content.version)) {
61    delete pkg.content.version
62  }
63
64  // make sure that the input is valid. if not, use the default
65  const pzData = await promzard(path.resolve(input), {
66    yes,
67    config,
68    filename: packageFile,
69    dirname: dir,
70    basename: path.basename(dir),
71    package: pkg.content,
72  }, { backupFile: def })
73
74  for (const [k, v] of Object.entries(pzData)) {
75    if (v != null) {
76      pkg.content[k] = v
77    }
78  }
79
80  await pkg.normalize({ steps: extras })
81
82  // turn the objects back into somewhat more humane strings.
83  // "normalizeData" does this and there isn't a way to choose which of those steps happen
84  if (pkg.content.author) {
85    pkg.content.author = stringifyPerson(pkg.content.author)
86  }
87
88  // no need for the readme now.
89  delete pkg.content.readme
90  delete pkg.content.readmeFilename
91
92  // really don't want to have this lying around in the file
93  delete pkg.content._id
94
95  // ditto
96  delete pkg.content.gitHead
97
98  // if the repo is empty, remove it.
99  if (!pkg.content.repository) {
100    delete pkg.content.repository
101  }
102
103  // readJson filters out empty descriptions, but init-package-json
104  // traditionally leaves them alone
105  if (!pkg.content.description) {
106    pkg.content.description = pzData.description
107  }
108
109  // optionalDependencies don't need to be repeated in two places
110  if (pkg.content.dependencies) {
111    if (pkg.content.optionalDependencies) {
112      for (const name of Object.keys(pkg.content.optionalDependencies)) {
113        delete pkg.content.dependencies[name]
114      }
115    }
116    if (Object.keys(pkg.content.dependencies).length === 0) {
117      delete pkg.content.dependencies
118    }
119  }
120
121  const stringified = JSON.stringify(pkg.content, null, 2) + '\n'
122  const msg = util.format('%s:\n\n%s\n', packageFile, stringified)
123
124  if (yes) {
125    await pkg.save()
126    if (!config.get('silent')) {
127      // eslint-disable-next-line no-console
128      console.log(`Wrote to ${msg}`)
129    }
130    return pkg.content
131  }
132
133  // eslint-disable-next-line no-console
134  console.log(`About to write to ${msg}`)
135  const ok = await read({ prompt: 'Is this OK? ', default: 'yes' })
136  if (!ok || !ok.toLowerCase().startsWith('y')) {
137    // eslint-disable-next-line no-console
138    console.log('Aborted.')
139    return
140  }
141
142  await pkg.save({ sort: true })
143  return pkg.content
144}
145
146module.exports = init
147module.exports.yes = isYes
148 
codekingpro/portable-devtools · Team Ai