@@ -29,10 +29,10 @@ function publish (manifest, tarball, opts) {
2929 return new opts . Promise ( resolve => resolve ( ) ) . then ( ( ) => {
3030 validate ( 'OSO|OOO' , [ manifest , tarball , opts ] )
3131 if ( manifest . private ) {
32- throw new Error (
32+ throw Object . assign ( new Error (
3333 'This package has been marked as private\n' +
3434 "Remove the 'private' field from the package.json to publish it."
35- )
35+ ) , { code : 'EPRIVATE' } )
3636 }
3737 const spec = npa . resolve ( manifest . name , manifest . version )
3838 const reg = npmFetch . pickRegistry ( spec , opts )
@@ -42,7 +42,10 @@ function publish (manifest, tarball, opts) {
4242 // registry-frontdoor cares about the access level, which is only
4343 // configurable for scoped packages
4444 if ( ! spec . scope && opts . access === 'restricted' ) {
45- throw new Error ( "Can't restrict access to unscoped packages." )
45+ throw Object . assign (
46+ new Error ( "Can't restrict access to unscoped packages." ) ,
47+ { code : 'EUNSCOPED' }
48+ )
4649 }
4750
4851 return slurpTarball ( tarball , opts ) . then ( tardata => {
@@ -91,7 +94,12 @@ function patchedManifest (spec, auth, base, opts) {
9194
9295 fixer . fixNameField ( manifest , { strict : true , allowLegacyCase : true } )
9396 const version = semver . clean ( manifest . version )
94- if ( ! version ) { throw new Error ( 'invalid semver: ' + manifest . version ) }
97+ if ( ! version ) {
98+ throw Object . assign (
99+ new Error ( 'invalid semver: ' + manifest . version ) ,
100+ { code : 'EBADSEMVER' }
101+ )
102+ }
95103 manifest . version = version
96104 return manifest
97105}
@@ -147,23 +155,24 @@ function patchMetadata (current, newData, opts) {
147155 return semver . clean ( v , true )
148156 } ) . concat ( Object . keys ( current . time || { } ) . map ( v => {
149157 if ( semver . valid ( v , true ) ) { return semver . clean ( v , true ) }
150- } ) . filter ( v => v ) )
158+ } ) ) . filter ( v => v )
151159
152- if ( curVers . indexOf ( newData . version ) !== - 1 ) {
160+ const newVersion = Object . keys ( newData . versions ) [ 0 ]
161+
162+ if ( curVers . indexOf ( newVersion ) !== - 1 ) {
153163 throw ConflictError ( newData . name , newData . version )
154164 }
155165
156- const newVersion = newData . version
157-
166+ current . versions = current . versions || { }
158167 current . versions [ newVersion ] = newData . versions [ newVersion ]
159- current . _attachments = current . _attachments || { }
160168 for ( var i in newData ) {
161169 switch ( i ) {
162170 // objects that copy over the new stuffs
163171 case 'dist-tags' :
164172 case 'versions' :
165173 case '_attachments' :
166174 for ( var j in newData [ i ] ) {
175+ current [ i ] = current [ i ] || { }
167176 current [ i ] [ j ] = newData [ i ] [ j ]
168177 }
169178 break
@@ -177,7 +186,7 @@ function patchMetadata (current, newData, opts) {
177186 current [ i ] = newData [ i ]
178187 }
179188 }
180- const maint = JSON . parse ( JSON . stringify ( newData . maintainers ) )
189+ const maint = newData . maintainers && JSON . parse ( JSON . stringify ( newData . maintainers ) )
181190 newData . versions [ newVersion ] . maintainers = maint
182191 return current
183192}
@@ -187,8 +196,13 @@ function slurpTarball (tarSrc, opts) {
187196 return opts . Promise . resolve ( tarSrc )
188197 } else if ( typeof tarSrc === 'string' ) {
189198 return opts . Promise . resolve ( Buffer . from ( tarSrc , 'base64' ) )
190- } else if ( typeof tarSrc === 'object' && typeof tarSrc . pipe === 'function' ) {
199+ } else if ( typeof tarSrc . pipe === 'function' ) {
191200 return getStream . buffer ( tarSrc )
201+ } else {
202+ return opts . Promise . reject ( Object . assign (
203+ new Error ( 'invalid tarball argument. Must be a Buffer, a base64 string, or a binary stream' ) , {
204+ code : 'EBADTAR'
205+ } ) )
192206 }
193207}
194208
0 commit comments