11
22const promzard = require ( 'promzard' )
33const path = require ( 'path' )
4- const fs = require ( 'fs/promises' )
54const semver = require ( 'semver' )
6- const read = require ( 'read' )
5+ const { read } = require ( 'read' )
76const util = require ( 'util' )
8- const rpj = require ( 'read- package-json' )
7+ const PackageJson = require ( '@npmcli/ package-json' )
98
109const def = require . resolve ( './default-input.js' )
1110
12- // to validate the data object at the end as a worthwhile package
13- // and assign default values for things.
14- const _extraSet = rpj . extraSet
15- const _rpj = util . promisify ( rpj )
16- const _rpjExtras = util . promisify ( rpj . extras )
17- const readPkgJson = async ( file , pkg ) => {
18- // only do a few of these. no need for mans or contributors if they're in the files
19- rpj . extraSet = _extraSet . filter ( f => f . name !== 'authors' && f . name !== 'mans' )
20- const p = pkg ? _rpjExtras ( file , pkg ) : _rpj ( file )
21- return p . catch ( ( ) => ( { } ) ) . finally ( ( ) => rpj . extraSet = _extraSet )
22- }
11+ const extras = [
12+ 'bundleDependencies' ,
13+ 'gypfile' ,
14+ 'serverjs' ,
15+ 'scriptpath' ,
16+ 'readme' ,
17+ 'bin' ,
18+ 'githead' ,
19+ 'fillTypes' ,
20+ 'normalizeData' ,
21+ ]
2322
2423const isYes = ( c ) => ! ! ( c . get ( 'yes' ) || c . get ( 'y' ) || c . get ( 'force' ) || c . get ( 'f' ) )
2524
26- const getConfig = ( c = { } ) => {
25+ const getConfig = ( c ) => {
2726 // accept either a plain-jane object, or a config object with a "get" method.
2827 if ( typeof c . get !== 'function' ) {
2928 const data = c
@@ -35,99 +34,99 @@ const getConfig = (c = {}) => {
3534 return c
3635}
3736
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 */
3841const stringifyPerson = ( p ) => {
39- if ( typeof p === 'string' ) {
40- return p
41- }
42- const { name = '' , url, web, email, mail } = p
42+ const { name, url, web, email, mail } = p
4343 const u = url || web
4444 const e = email || mail
4545 return `${ name } ${ e ? ` <${ e } >` : '' } ${ u ? ` (${ u } )` : '' } `
4646}
47-
48- async function init ( dir , input = def , c = { } ) {
47+ async function init ( dir ,
48+ // TODO test for non-default definitions
49+ /* istanbul ignore next */
50+ input = def ,
51+ c = { } ) {
4952 const config = getConfig ( c )
5053 const yes = isYes ( config )
5154 const packageFile = path . resolve ( dir , 'package.json' )
5255
53- const pkg = await readPkgJson ( packageFile )
56+ // read what's already there to inform our prompts
57+ const pkg = await PackageJson . load ( dir , { create : true } )
58+ await pkg . normalize ( )
5459
55- if ( ! semver . valid ( pkg . version ) ) {
56- delete pkg . version
60+ if ( ! semver . valid ( pkg . content . version ) ) {
61+ delete pkg . content . version
5762 }
5863
5964 // make sure that the input is valid. if not, use the default
6065 const pzData = await promzard ( path . resolve ( input ) , {
6166 yes,
6267 config,
6368 filename : packageFile ,
64- dirname : path . dirname ( packageFile ) ,
65- basename : path . basename ( path . dirname ( packageFile ) ) ,
66- package : pkg ,
69+ dirname : dir ,
70+ basename : path . basename ( dir ) ,
71+ package : pkg . content ,
6772 } , { backupFile : def } )
6873
6974 for ( const [ k , v ] of Object . entries ( pzData ) ) {
7075 if ( v != null ) {
71- pkg [ k ] = v
76+ pkg . content [ k ] = v
7277 }
7378 }
7479
75- const pkgExtras = await readPkgJson ( packageFile , pkg )
80+ await pkg . normalize ( { steps : extras } )
7681
77- // turn the objects into somewhat more humane strings.
78- if ( pkgExtras . author ) {
79- pkgExtras . author = stringifyPerson ( pkgExtras . author )
80- }
81-
82- for ( const set of [ 'maintainers' , 'contributors' ] ) {
83- if ( Array . isArray ( pkgExtras [ set ] ) ) {
84- pkgExtras [ set ] = pkgExtras [ set ] . map ( stringifyPerson )
85- }
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 )
8686 }
8787
8888 // no need for the readme now.
89- delete pkgExtras . readme
90- delete pkgExtras . readmeFilename
89+ delete pkg . content . readme
90+ delete pkg . content . readmeFilename
9191
9292 // really don't want to have this lying around in the file
93- delete pkgExtras . _id
93+ delete pkg . content . _id
9494
9595 // ditto
96- delete pkgExtras . gitHead
96+ delete pkg . content . gitHead
9797
9898 // if the repo is empty, remove it.
99- if ( ! pkgExtras . repository ) {
100- delete pkgExtras . repository
99+ if ( ! pkg . content . repository ) {
100+ delete pkg . content . repository
101101 }
102102
103103 // readJson filters out empty descriptions, but init-package-json
104104 // traditionally leaves them alone
105- if ( ! pkgExtras . description ) {
106- pkgExtras . description = pzData . description
105+ if ( ! pkg . content . description ) {
106+ pkg . content . description = pzData . description
107107 }
108108
109109 // optionalDependencies don't need to be repeated in two places
110- if ( pkgExtras . dependencies ) {
111- if ( pkgExtras . optionalDependencies ) {
112- for ( const name of Object . keys ( pkgExtras . optionalDependencies ) ) {
113- delete pkgExtras . dependencies [ name ]
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 ]
114114 }
115115 }
116- if ( Object . keys ( pkgExtras . dependencies ) . length === 0 ) {
117- delete pkgExtras . dependencies
116+ if ( Object . keys ( pkg . content . dependencies ) . length === 0 ) {
117+ delete pkg . content . dependencies
118118 }
119119 }
120120
121- const stringified = JSON . stringify ( pkgExtras , null , 2 ) + '\n'
121+ const stringified = JSON . stringify ( pkg . content , null , 2 ) + '\n'
122122 const msg = util . format ( '%s:\n\n%s\n' , packageFile , stringified )
123- const write = ( ) => fs . writeFile ( packageFile , stringified , 'utf8' )
124123
125124 if ( yes ) {
126- await write ( )
125+ await pkg . save ( )
127126 if ( ! config . get ( 'silent' ) ) {
128127 console . log ( `Wrote to ${ msg } ` )
129128 }
130- return pkgExtras
129+ return pkg . content
131130 }
132131
133132 console . log ( `About to write to ${ msg } ` )
@@ -137,8 +136,8 @@ async function init (dir, input = def, c = {}) {
137136 return
138137 }
139138
140- await write ( )
141- return pkgExtras
139+ await pkg . save ( )
140+ return pkg . content
142141}
143142
144143module . exports = init
0 commit comments