11/* eslint-disable standard/no-callback-literal */
22module . exports = distTag
33
4- var log = require ( 'npmlog' )
5- var npa = require ( 'npm-package-arg' )
6- var semver = require ( 'semver' )
7-
8- var npm = require ( './npm.js' )
9- var mapToRegistry = require ( './utils/map-to-registry.js' )
10- var readLocalPkg = require ( './utils/read-local-package.js' )
11- var usage = require ( './utils/usage' )
12- var output = require ( './utils/output.js' )
4+ const BB = require ( 'bluebird' )
5+
6+ const figgyPudding = require ( 'figgy-pudding' )
7+ const log = require ( 'npmlog' )
8+ const npa = require ( 'npm-package-arg' )
9+ const npmConfig = require ( './config/figgy-config.js' )
10+ const output = require ( './utils/output.js' )
11+ const readLocalPkg = BB . promisify ( require ( './utils/read-local-package.js' ) )
12+ const readUserInfo = require ( './utils/read-user-info.js' )
13+ const regFetch = require ( 'npm-registry-fetch' )
14+ const semver = require ( 'semver' )
15+ const usage = require ( './utils/usage' )
16+
17+ const DistTagOpts = figgyPudding ( {
18+ tag : { }
19+ } )
1320
1421distTag . usage = usage (
1522 'dist-tag' ,
@@ -30,130 +37,135 @@ distTag.completion = function (opts, cb) {
3037 }
3138}
3239
33- function distTag ( args , cb ) {
34- var cmd = args . shift ( )
35- switch ( cmd ) {
36- case 'add' : case 'a' : case 'set' : case 's' :
37- return add ( args [ 0 ] , args [ 1 ] , cb )
38- case 'rm' : case 'r' : case 'del' : case 'd' : case 'remove' :
39- return remove ( args [ 1 ] , args [ 0 ] , cb )
40- case 'ls' : case 'l' : case 'sl' : case 'list' :
41- return list ( args [ 0 ] , cb )
42- default :
43- return cb ( 'Usage:\n' + distTag . usage )
44- }
40+ function UsageError ( ) {
41+ throw Object . assign ( new Error ( 'Usage:\n' + distTag . usage ) , {
42+ code : 'EUSAGE'
43+ } )
4544}
4645
47- function add ( spec , tag , cb ) {
48- var thing = npa ( spec || '' )
49- var pkg = thing . name
50- var version = thing . rawSpec
51- var t = ( tag || npm . config . get ( 'tag' ) ) . trim ( )
46+ function distTag ( [ cmd , pkg , tag ] , cb ) {
47+ const opts = DistTagOpts ( npmConfig ( ) )
48+ return BB . try ( ( ) => {
49+ switch ( cmd ) {
50+ case 'add' : case 'a' : case 'set' : case 's' :
51+ return add ( pkg , tag , opts )
52+ case 'rm' : case 'r' : case 'del' : case 'd' : case 'remove' :
53+ return remove ( pkg , tag , opts )
54+ case 'ls' : case 'l' : case 'sl' : case 'list' :
55+ return list ( pkg , opts )
56+ default :
57+ UsageError ( )
58+ }
59+ } ) . then (
60+ x => cb ( null , x ) ,
61+ err => {
62+ if ( err . code === 'EUSAGE' ) {
63+ cb ( err . message )
64+ } else {
65+ cb ( err )
66+ }
67+ }
68+ )
69+ }
5270
53- log . verbose ( 'dist-tag add' , t , 'to' , pkg + '@' + version )
71+ function add ( spec , tag , opts ) {
72+ spec = npa ( spec || '' )
73+ const version = spec . rawSpec
74+ const t = ( tag || opts . tag ) . trim ( )
5475
55- if ( ! pkg || ! version || ! t ) return cb ( 'Usage:\n' + distTag . usage )
76+ log . verbose ( 'dist-tag add' , t , 'to' , spec . name + '@' + version )
77+
78+ if ( ! spec || ! version || ! t ) UsageError ( )
5679
5780 if ( semver . validRange ( t ) ) {
58- var er = new Error ( 'Tag name must not be a valid SemVer range: ' + t )
59- return cb ( er )
81+ throw new Error ( 'Tag name must not be a valid SemVer range: ' + t )
6082 }
6183
62- fetchTags ( pkg , function ( er , tags ) {
63- if ( er ) return cb ( er )
64-
84+ return fetchTags ( spec , opts ) . then ( tags => {
6585 if ( tags [ t ] === version ) {
6686 log . warn ( 'dist-tag add' , t , 'is already set to version' , version )
67- return cb ( )
87+ return
6888 }
6989 tags [ t ] = version
70-
71- mapToRegistry ( pkg , npm . config , function ( er , uri , auth , base ) {
72- var params = {
73- 'package' : pkg ,
74- distTag : t ,
75- version : version ,
76- auth : auth
77- }
78-
79- npm . registry . distTags . add ( base , params , function ( er ) {
80- if ( er ) return cb ( er )
81-
82- output ( '+' + t + ': ' + pkg + '@' + version )
83- cb ( )
90+ const url = `/-/package/ ${ spec . escapedName } /dist-tags/ ${ encodeURIComponent ( t ) } `
91+ const reqOpts = opts . concat ( {
92+ method : 'PUT' ,
93+ body : JSON . stringify ( version ) ,
94+ headers : {
95+ 'content-type' : 'application/json'
96+ } ,
97+ spec
98+ } )
99+ return regFetch ( url , reqOpts ) . catch ( err => {
100+ if ( err . code !== 'EOTP' && ! ( err . code === 'E401' && / o n e - t i m e p a s s / . test ( err . body ) ) ) throw err
101+ if ( ! process . stdin . isTTY || ! process . stdout . isTTY ) throw err
102+ return readUserInfo . otp ( ) . then ( otp => {
103+ return regFetch ( url , reqOpts . concat ( { otp } ) )
84104 } )
105+ } ) . then ( ( ) => {
106+ output ( `+${ t } : ${ spec . name } @${ version } ` )
85107 } )
86108 } )
87109}
88110
89- function remove ( tag , pkg , cb ) {
90- log . verbose ( 'dist-tag del' , tag , 'from' , pkg )
91-
92- fetchTags ( pkg , function ( er , tags ) {
93- if ( er ) return cb ( er )
111+ function remove ( spec , tag , opts ) {
112+ spec = npa ( spec || '' )
113+ log . verbose ( 'dist-tag del' , tag , 'from' , spec . name )
94114
115+ return fetchTags ( spec , opts ) . then ( tags => {
95116 if ( ! tags [ tag ] ) {
96- log . info ( 'dist-tag del' , tag , 'is not a dist-tag on' , pkg )
97- return cb ( new Error ( tag + ' is not a dist-tag on ' + pkg ) )
117+ log . info ( 'dist-tag del' , tag , 'is not a dist-tag on' , spec . name )
118+ throw new Error ( tag + ' is not a dist-tag on ' + spec . name )
98119 }
99-
100- var version = tags [ tag ]
120+ const version = tags [ tag ]
101121 delete tags [ tag ]
102-
103- mapToRegistry ( pkg , npm . config , function ( er , uri , auth , base ) {
104- var params = {
105- 'package' : pkg ,
106- distTag : tag ,
107- auth : auth
108- }
109-
110- npm . registry . distTags . rm ( base , params , function ( er ) {
111- if ( er ) return cb ( er )
112-
113- output ( '-' + tag + ': ' + pkg + '@' + version )
114- cb ( )
122+ const url = `/-/package/${ spec . escapedName } /dist-tags/${ encodeURIComponent ( tag ) } `
123+ const reqOpts = opts . concat ( {
124+ method : 'DELETE'
125+ } )
126+ return regFetch ( url , reqOpts ) . catch ( err => {
127+ if ( err . code !== 'EOTP' && ! ( err . code === 'E401' && / o n e - t i m e p a s s / . test ( err . body ) ) ) throw err
128+ if ( ! process . stdin . isTTY || ! process . stdout . isTTY ) throw err
129+ return readUserInfo . otp ( ) . then ( otp => {
130+ return regFetch ( url , reqOpts . concat ( { otp} ) )
115131 } )
132+ } ) . then ( ( ) => {
133+ output ( `-${ tag } : ${ spec . name } @${ version } ` )
116134 } )
117135 } )
118136}
119137
120- function list ( pkg , cb ) {
121- if ( ! pkg ) {
122- return readLocalPkg ( function ( er , pkg ) {
123- if ( er ) return cb ( er )
124- if ( ! pkg ) return cb ( distTag . usage )
125- list ( pkg , cb )
138+ function list ( spec , opts ) {
139+ if ( ! spec ) {
140+ return readLocalPkg ( ) . then ( pkg => {
141+ if ( ! pkg ) { UsageError ( ) }
142+ return list ( pkg , opts )
126143 } )
127144 }
145+ spec = npa ( spec )
128146
129- fetchTags ( pkg , function ( er , tags ) {
130- if ( er ) {
131- log . error ( 'dist-tag ls' , "Couldn't get dist-tag data for" , pkg )
132- return cb ( er )
133- }
134- var msg = Object . keys ( tags ) . map ( function ( k ) {
135- return k + ': ' + tags [ k ]
136- } ) . sort ( ) . join ( '\n' )
147+ return fetchTags ( spec , opts ) . then ( tags => {
148+ var msg = Object . keys ( tags ) . map ( k => `${ k } : ${ tags [ k ] } ` ) . sort ( ) . join ( '\n' )
137149 output ( msg )
138- cb ( er , tags )
150+ return tags
151+ } , err => {
152+ log . error ( 'dist-tag ls' , "Couldn't get dist-tag data for" , spec )
153+ throw err
139154 } )
140155}
141156
142- function fetchTags ( pkg , cb ) {
143- mapToRegistry ( pkg , npm . config , function ( er , uri , auth , base ) {
144- if ( er ) return cb ( er )
145-
146- var params = {
147- 'package' : pkg ,
148- auth : auth
149- }
150- npm . registry . distTags . fetch ( base , params , function ( er , tags ) {
151- if ( er ) return cb ( er )
152- if ( ! tags || ! Object . keys ( tags ) . length ) {
153- return cb ( new Error ( 'No dist-tags found for ' + pkg ) )
154- }
155-
156- cb ( null , tags )
157+ function fetchTags ( spec , opts ) {
158+ return regFetch . json (
159+ `/-/package/${ spec . escapedName } /dist-tags` ,
160+ opts . concat ( {
161+ 'prefer-online' : true ,
162+ spec
157163 } )
164+ ) . then ( data => {
165+ if ( data && typeof data === 'object' ) delete data . _etag
166+ if ( ! data || ! Object . keys ( data ) . length ) {
167+ throw new Error ( 'No dist-tags found for ' + spec . name )
168+ }
169+ return data
158170 } )
159171}
0 commit comments