1
1
2
2
const promzard = require ( 'promzard' )
3
3
const path = require ( 'path' )
4
- const fs = require ( 'fs/promises' )
5
4
const semver = require ( 'semver' )
6
- const read = require ( 'read' )
5
+ const { read } = require ( 'read' )
7
6
const util = require ( 'util' )
8
- const rpj = require ( 'read- package-json' )
7
+ const PackageJson = require ( '@npmcli/ package-json' )
9
8
10
9
const def = require . resolve ( './default-input.js' )
11
10
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
+ ]
23
22
24
23
const isYes = ( c ) => ! ! ( c . get ( 'yes' ) || c . get ( 'y' ) || c . get ( 'force' ) || c . get ( 'f' ) )
25
24
26
- const getConfig = ( c = { } ) => {
25
+ const getConfig = ( c ) => {
27
26
// accept either a plain-jane object, or a config object with a "get" method.
28
27
if ( typeof c . get !== 'function' ) {
29
28
const data = c
@@ -35,99 +34,99 @@ const getConfig = (c = {}) => {
35
34
return c
36
35
}
37
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 */
38
41
const 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
43
43
const u = url || web
44
44
const e = email || mail
45
45
return `${ name } ${ e ? ` <${ e } >` : '' } ${ u ? ` (${ u } )` : '' } `
46
46
}
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 = { } ) {
49
52
const config = getConfig ( c )
50
53
const yes = isYes ( config )
51
54
const packageFile = path . resolve ( dir , 'package.json' )
52
55
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 ( )
54
59
55
- if ( ! semver . valid ( pkg . version ) ) {
56
- delete pkg . version
60
+ if ( ! semver . valid ( pkg . content . version ) ) {
61
+ delete pkg . content . version
57
62
}
58
63
59
64
// make sure that the input is valid. if not, use the default
60
65
const pzData = await promzard ( path . resolve ( input ) , {
61
66
yes,
62
67
config,
63
68
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 ,
67
72
} , { backupFile : def } )
68
73
69
74
for ( const [ k , v ] of Object . entries ( pzData ) ) {
70
75
if ( v != null ) {
71
- pkg [ k ] = v
76
+ pkg . content [ k ] = v
72
77
}
73
78
}
74
79
75
- const pkgExtras = await readPkgJson ( packageFile , pkg )
80
+ await pkg . normalize ( { steps : extras } )
76
81
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 )
86
86
}
87
87
88
88
// no need for the readme now.
89
- delete pkgExtras . readme
90
- delete pkgExtras . readmeFilename
89
+ delete pkg . content . readme
90
+ delete pkg . content . readmeFilename
91
91
92
92
// really don't want to have this lying around in the file
93
- delete pkgExtras . _id
93
+ delete pkg . content . _id
94
94
95
95
// ditto
96
- delete pkgExtras . gitHead
96
+ delete pkg . content . gitHead
97
97
98
98
// 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
101
101
}
102
102
103
103
// readJson filters out empty descriptions, but init-package-json
104
104
// traditionally leaves them alone
105
- if ( ! pkgExtras . description ) {
106
- pkgExtras . description = pzData . description
105
+ if ( ! pkg . content . description ) {
106
+ pkg . content . description = pzData . description
107
107
}
108
108
109
109
// 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 ]
114
114
}
115
115
}
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
118
118
}
119
119
}
120
120
121
- const stringified = JSON . stringify ( pkgExtras , null , 2 ) + '\n'
121
+ const stringified = JSON . stringify ( pkg . content , null , 2 ) + '\n'
122
122
const msg = util . format ( '%s:\n\n%s\n' , packageFile , stringified )
123
- const write = ( ) => fs . writeFile ( packageFile , stringified , 'utf8' )
124
123
125
124
if ( yes ) {
126
- await write ( )
125
+ await pkg . save ( )
127
126
if ( ! config . get ( 'silent' ) ) {
128
127
console . log ( `Wrote to ${ msg } ` )
129
128
}
130
- return pkgExtras
129
+ return pkg . content
131
130
}
132
131
133
132
console . log ( `About to write to ${ msg } ` )
@@ -137,8 +136,8 @@ async function init (dir, input = def, c = {}) {
137
136
return
138
137
}
139
138
140
- await write ( )
141
- return pkgExtras
139
+ await pkg . save ( )
140
+ return pkg . content
142
141
}
143
142
144
143
module . exports = init
0 commit comments