@@ -29,10 +29,10 @@ function publish (manifest, tarball, opts) {
29
29
return new opts . Promise ( resolve => resolve ( ) ) . then ( ( ) => {
30
30
validate ( 'OSO|OOO' , [ manifest , tarball , opts ] )
31
31
if ( manifest . private ) {
32
- throw new Error (
32
+ throw Object . assign ( new Error (
33
33
'This package has been marked as private\n' +
34
34
"Remove the 'private' field from the package.json to publish it."
35
- )
35
+ ) , { code : 'EPRIVATE' } )
36
36
}
37
37
const spec = npa . resolve ( manifest . name , manifest . version )
38
38
const reg = npmFetch . pickRegistry ( spec , opts )
@@ -42,7 +42,10 @@ function publish (manifest, tarball, opts) {
42
42
// registry-frontdoor cares about the access level, which is only
43
43
// configurable for scoped packages
44
44
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
+ )
46
49
}
47
50
48
51
return slurpTarball ( tarball , opts ) . then ( tardata => {
@@ -91,7 +94,12 @@ function patchedManifest (spec, auth, base, opts) {
91
94
92
95
fixer . fixNameField ( manifest , { strict : true , allowLegacyCase : true } )
93
96
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
+ }
95
103
manifest . version = version
96
104
return manifest
97
105
}
@@ -147,23 +155,24 @@ function patchMetadata (current, newData, opts) {
147
155
return semver . clean ( v , true )
148
156
} ) . concat ( Object . keys ( current . time || { } ) . map ( v => {
149
157
if ( semver . valid ( v , true ) ) { return semver . clean ( v , true ) }
150
- } ) . filter ( v => v ) )
158
+ } ) ) . filter ( v => v )
151
159
152
- if ( curVers . indexOf ( newData . version ) !== - 1 ) {
160
+ const newVersion = Object . keys ( newData . versions ) [ 0 ]
161
+
162
+ if ( curVers . indexOf ( newVersion ) !== - 1 ) {
153
163
throw ConflictError ( newData . name , newData . version )
154
164
}
155
165
156
- const newVersion = newData . version
157
-
166
+ current . versions = current . versions || { }
158
167
current . versions [ newVersion ] = newData . versions [ newVersion ]
159
- current . _attachments = current . _attachments || { }
160
168
for ( var i in newData ) {
161
169
switch ( i ) {
162
170
// objects that copy over the new stuffs
163
171
case 'dist-tags' :
164
172
case 'versions' :
165
173
case '_attachments' :
166
174
for ( var j in newData [ i ] ) {
175
+ current [ i ] = current [ i ] || { }
167
176
current [ i ] [ j ] = newData [ i ] [ j ]
168
177
}
169
178
break
@@ -177,7 +186,7 @@ function patchMetadata (current, newData, opts) {
177
186
current [ i ] = newData [ i ]
178
187
}
179
188
}
180
- const maint = JSON . parse ( JSON . stringify ( newData . maintainers ) )
189
+ const maint = newData . maintainers && JSON . parse ( JSON . stringify ( newData . maintainers ) )
181
190
newData . versions [ newVersion ] . maintainers = maint
182
191
return current
183
192
}
@@ -187,8 +196,13 @@ function slurpTarball (tarSrc, opts) {
187
196
return opts . Promise . resolve ( tarSrc )
188
197
} else if ( typeof tarSrc === 'string' ) {
189
198
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' ) {
191
200
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
+ } ) )
192
206
}
193
207
}
194
208
0 commit comments