@@ -4,8 +4,67 @@ const log = require('proc-log')
44const localeCompare = require ( '@isaacs/string-locale-compare' ) ( 'en' )
55
66const add = ( { pkg, add, saveBundle, saveType } ) => {
7- for ( const spec of add ) {
8- addSingle ( { pkg, spec, saveBundle, saveType } )
7+ for ( const { name, rawSpec } of add ) {
8+ // if the user does not give us a type, we infer which type(s)
9+ // to keep based on the same order of priority we do when
10+ // building the tree as defined in the _loadDeps method of
11+ // the node class.
12+ if ( ! saveType ) {
13+ saveType = inferSaveType ( pkg , name )
14+ }
15+
16+ if ( saveType === 'prod' ) {
17+ // a production dependency can only exist as production (rpj ensures it
18+ // doesn't coexist w/ optional)
19+ deleteSubKey ( pkg , 'devDependencies' , name , 'dependencies' )
20+ deleteSubKey ( pkg , 'peerDependencies' , name , 'dependencies' )
21+ } else if ( saveType === 'dev' ) {
22+ // a dev dependency may co-exist as peer, or optional, but not production
23+ deleteSubKey ( pkg , 'dependencies' , name , 'devDependencies' )
24+ } else if ( saveType === 'optional' ) {
25+ // an optional dependency may co-exist as dev (rpj ensures it doesn't
26+ // coexist w/ prod)
27+ deleteSubKey ( pkg , 'peerDependencies' , name , 'optionalDependencies' )
28+ } else { // peer or peerOptional is all that's left
29+ // a peer dependency may coexist as dev
30+ deleteSubKey ( pkg , 'dependencies' , name , 'peerDependencies' )
31+ deleteSubKey ( pkg , 'optionalDependencies' , name , 'peerDependencies' )
32+ }
33+
34+ const depType = saveTypeMap . get ( saveType )
35+
36+ pkg [ depType ] = pkg [ depType ] || { }
37+ if ( rawSpec !== '' || pkg [ depType ] [ name ] === undefined ) {
38+ pkg [ depType ] [ name ] = rawSpec || '*'
39+ }
40+ if ( saveType === 'optional' ) {
41+ // Affordance for previous npm versions that require this behaviour
42+ pkg . dependencies = pkg . dependencies || { }
43+ pkg . dependencies [ name ] = pkg . optionalDependencies [ name ]
44+ }
45+
46+ if ( saveType === 'peer' || saveType === 'peerOptional' ) {
47+ const pdm = pkg . peerDependenciesMeta || { }
48+ if ( saveType === 'peer' && pdm [ name ] && pdm [ name ] . optional ) {
49+ pdm [ name ] . optional = false
50+ } else if ( saveType === 'peerOptional' ) {
51+ pdm [ name ] = pdm [ name ] || { }
52+ pdm [ name ] . optional = true
53+ pkg . peerDependenciesMeta = pdm
54+ }
55+ // peerDeps are often also a devDep, so that they can be tested when
56+ // using package managers that don't auto-install peer deps
57+ if ( pkg . devDependencies && pkg . devDependencies [ name ] !== undefined ) {
58+ pkg . devDependencies [ name ] = pkg . peerDependencies [ name ]
59+ }
60+ }
61+
62+ if ( saveBundle && saveType !== 'peer' && saveType !== 'peerOptional' ) {
63+ // keep it sorted, keep it unique
64+ const bd = new Set ( pkg . bundleDependencies || [ ] )
65+ bd . add ( name )
66+ pkg . bundleDependencies = [ ...bd ] . sort ( localeCompare )
67+ }
968 }
1069
1170 return pkg
@@ -21,71 +80,6 @@ const saveTypeMap = new Map([
2180 [ 'peer' , 'peerDependencies' ] ,
2281] )
2382
24- const addSingle = ( { pkg, spec, saveBundle, saveType } ) => {
25- const { name, rawSpec } = spec
26-
27- // if the user does not give us a type, we infer which type(s)
28- // to keep based on the same order of priority we do when
29- // building the tree as defined in the _loadDeps method of
30- // the node class.
31- if ( ! saveType ) {
32- saveType = inferSaveType ( pkg , spec . name )
33- }
34-
35- if ( saveType === 'prod' ) {
36- // a production dependency can only exist as production (rpj ensures it
37- // doesn't coexist w/ optional)
38- deleteSubKey ( pkg , 'devDependencies' , name , 'dependencies' )
39- deleteSubKey ( pkg , 'peerDependencies' , name , 'dependencies' )
40- } else if ( saveType === 'dev' ) {
41- // a dev dependency may co-exist as peer, or optional, but not production
42- deleteSubKey ( pkg , 'dependencies' , name , 'devDependencies' )
43- } else if ( saveType === 'optional' ) {
44- // an optional dependency may co-exist as dev (rpj ensures it doesn't
45- // coexist w/ prod)
46- deleteSubKey ( pkg , 'peerDependencies' , name , 'optionalDependencies' )
47- } else { // peer or peerOptional is all that's left
48- // a peer dependency may coexist as dev
49- deleteSubKey ( pkg , 'dependencies' , name , 'peerDependencies' )
50- deleteSubKey ( pkg , 'optionalDependencies' , name , 'peerDependencies' )
51- }
52-
53- const depType = saveTypeMap . get ( saveType )
54-
55- pkg [ depType ] = pkg [ depType ] || { }
56- if ( rawSpec !== '' || pkg [ depType ] [ name ] === undefined ) {
57- pkg [ depType ] [ name ] = rawSpec || '*'
58- }
59- if ( saveType === 'optional' ) {
60- // Affordance for previous npm versions that require this behaviour
61- pkg . dependencies = pkg . dependencies || { }
62- pkg . dependencies [ name ] = pkg . optionalDependencies [ name ]
63- }
64-
65- if ( saveType === 'peer' || saveType === 'peerOptional' ) {
66- const pdm = pkg . peerDependenciesMeta || { }
67- if ( saveType === 'peer' && pdm [ name ] && pdm [ name ] . optional ) {
68- pdm [ name ] . optional = false
69- } else if ( saveType === 'peerOptional' ) {
70- pdm [ name ] = pdm [ name ] || { }
71- pdm [ name ] . optional = true
72- pkg . peerDependenciesMeta = pdm
73- }
74- // peerDeps are often also a devDep, so that they can be tested when
75- // using package managers that don't auto-install peer deps
76- if ( pkg . devDependencies && pkg . devDependencies [ name ] !== undefined ) {
77- pkg . devDependencies [ name ] = pkg . peerDependencies [ name ]
78- }
79- }
80-
81- if ( saveBundle && saveType !== 'peer' && saveType !== 'peerOptional' ) {
82- // keep it sorted, keep it unique
83- const bd = new Set ( pkg . bundleDependencies || [ ] )
84- bd . add ( spec . name )
85- pkg . bundleDependencies = [ ...bd ] . sort ( localeCompare )
86- }
87- }
88-
8983// Finds where the package is already in the spec and infers saveType from that
9084const inferSaveType = ( pkg , name ) => {
9185 for ( const saveType of saveTypeMap . keys ( ) ) {
@@ -103,9 +97,8 @@ const inferSaveType = (pkg, name) => {
10397 return 'prod'
10498}
10599
106- const { hasOwnProperty } = Object . prototype
107100const hasSubKey = ( pkg , depType , name ) => {
108- return pkg [ depType ] && hasOwnProperty . call ( pkg [ depType ] , name )
101+ return pkg [ depType ] && Object . prototype . hasOwnProperty . call ( pkg [ depType ] , name )
109102}
110103
111104// Removes a subkey and warns about it if it's being replaced
0 commit comments