@@ -3,25 +3,11 @@ const path = require('path')
3
3
const libaccess = require ( 'libnpmaccess' )
4
4
const readPackageJson = require ( 'read-package-json-fast' )
5
5
6
- const npm = require ( './npm.js' )
7
6
const output = require ( './utils/output.js' )
8
7
const otplease = require ( './utils/otplease.js' )
9
8
const usageUtil = require ( './utils/usage.js' )
10
9
const getIdentity = require ( './utils/get-identity.js' )
11
10
12
- const usage = usageUtil (
13
- 'access' ,
14
- 'npm access public [<package>]\n' +
15
- 'npm access restricted [<package>]\n' +
16
- 'npm access grant <read-only|read-write> <scope:team> [<package>]\n' +
17
- 'npm access revoke <scope:team> [<package>]\n' +
18
- 'npm access 2fa-required [<package>]\n' +
19
- 'npm access 2fa-not-required [<package>]\n' +
20
- 'npm access ls-packages [<user>|<scope>|<scope:team>]\n' +
21
- 'npm access ls-collaborators [<package> [<user>]]\n' +
22
- 'npm access edit [<package>]'
23
- )
24
-
25
11
const subcommands = [
26
12
'public' ,
27
13
'restricted' ,
@@ -34,152 +20,195 @@ const subcommands = [
34
20
'2fa-not-required' ,
35
21
]
36
22
37
- const UsageError = ( msg ) =>
38
- Object . assign ( new Error ( `\nUsage: ${ msg } \n\n` + usage ) , {
39
- code : 'EUSAGE' ,
40
- } )
41
-
42
- const cmd = ( args , cb ) =>
43
- access ( args )
44
- . then ( x => cb ( null , x ) )
45
- . catch ( err => err . code === 'EUSAGE'
46
- ? cb ( err . message )
47
- : cb ( err )
23
+ class Access {
24
+ constructor ( npm ) {
25
+ this . npm = npm
26
+ }
27
+
28
+ get usage ( ) {
29
+ return usageUtil (
30
+ 'access' ,
31
+ 'npm access public [<package>]\n' +
32
+ 'npm access restricted [<package>]\n' +
33
+ 'npm access grant <read-only|read-write> <scope:team> [<package>]\n' +
34
+ 'npm access revoke <scope:team> [<package>]\n' +
35
+ 'npm access 2fa-required [<package>]\n' +
36
+ 'npm access 2fa-not-required [<package>]\n' +
37
+ 'npm access ls-packages [<user>|<scope>|<scope:team>]\n' +
38
+ 'npm access ls-collaborators [<package> [<user>]]\n' +
39
+ 'npm access edit [<package>]'
48
40
)
41
+ }
49
42
50
- const access = async ( [ cmd , ...args ] , cb ) => {
51
- const fn = subcommands . includes ( cmd ) && access [ cmd ]
43
+ async completion ( opts ) {
44
+ const argv = opts . conf . argv . remain
45
+ if ( argv . length === 2 )
46
+ return subcommands
47
+
48
+ switch ( argv [ 2 ] ) {
49
+ case 'grant' :
50
+ if ( argv . length === 3 )
51
+ return [ 'read-only' , 'read-write' ]
52
+ else
53
+ return [ ]
54
+
55
+ case 'public' :
56
+ case 'restricted' :
57
+ case 'ls-packages' :
58
+ case 'ls-collaborators' :
59
+ case 'edit' :
60
+ case '2fa-required' :
61
+ case '2fa-not-required' :
62
+ case 'revoke' :
63
+ return [ ]
64
+ default :
65
+ throw new Error ( argv [ 2 ] + ' not recognized' )
66
+ }
67
+ }
52
68
53
- if ( ! cmd )
54
- throw UsageError ( 'Subcommand is required.' )
69
+ exec ( args , cb ) {
70
+ this . access ( args )
71
+ . then ( x => cb ( null , x ) )
72
+ . catch ( err => err . code === 'EUSAGE'
73
+ ? cb ( err . message )
74
+ : cb ( err )
75
+ )
76
+ }
55
77
56
- if ( ! fn )
57
- throw UsageError ( `${ cmd } is not a recognized subcommand.` )
78
+ async access ( [ cmd , ...args ] ) {
79
+ if ( ! cmd )
80
+ throw this . usageError ( 'Subcommand is required.' )
58
81
59
- return fn ( args , { ... npm . flatOptions } )
60
- }
82
+ if ( ! subcommands . includes ( cmd ) || ! this [ cmd ] )
83
+ throw this . usageError ( ` ${ cmd } is not a recognized subcommand.` )
61
84
62
- const completion = async ( opts ) => {
63
- const argv = opts . conf . argv . remain
64
- if ( argv . length === 2 )
65
- return subcommands
85
+ return this [ cmd ] ( args , { ...this . npm . flatOptions } )
86
+ }
66
87
67
- switch ( argv [ 2 ] ) {
68
- case 'grant' :
69
- if ( argv . length === 3 )
70
- return [ 'read-only' , 'read-write' ]
71
- else
72
- return [ ]
88
+ public ( [ pkg ] , opts ) {
89
+ return this . modifyPackage ( pkg , opts , libaccess . public )
90
+ }
73
91
74
- case 'public' :
75
- case 'restricted' :
76
- case 'ls-packages' :
77
- case 'ls-collaborators' :
78
- case 'edit' :
79
- case '2fa-required' :
80
- case '2fa-not-required' :
81
- case 'revoke' :
82
- return [ ]
83
- default :
84
- throw new Error ( argv [ 2 ] + ' not recognized' )
92
+ restricted ( [ pkg ] , opts ) {
93
+ return this . modifyPackage ( pkg , opts , libaccess . restricted )
85
94
}
86
- }
87
95
88
- access . public = ( [ pkg ] , opts ) =>
89
- modifyPackage ( pkg , opts , libaccess . public )
96
+ async grant ( [ perms , scopeteam , pkg ] , opts ) {
97
+ if ( ! perms || ( perms !== 'read-only' && perms !== 'read-write' ) )
98
+ throw this . usageError ( 'First argument must be either `read-only` or `read-write`.' )
90
99
91
- access . restricted = ( [ pkg ] , opts ) =>
92
- modifyPackage ( pkg , opts , libaccess . restricted )
100
+ if ( ! scopeteam )
101
+ throw this . usageError ( '`<scope:team>` argument is required.' )
93
102
94
- access . grant = async ( [ perms , scopeteam , pkg ] , opts ) => {
95
- if ( ! perms || ( perms !== 'read-only' && perms !== 'read-write' ) )
96
- throw UsageError ( 'First argument must be either `read-only` or `read-write`.' )
103
+ const [ , scope , team ] = scopeteam . match ( / ^ @ ? ( [ ^ : ] + ) : ( .* ) $ / ) || [ ]
97
104
98
- if ( ! scopeteam )
99
- throw UsageError ( '`<scope:team>` argument is required.' )
105
+ if ( ! scope && ! team ) {
106
+ throw this . usageError (
107
+ 'Second argument used incorrect format.\n' +
108
+ 'Example: @example:developers'
109
+ )
110
+ }
100
111
101
- const [ , scope , team ] = scopeteam . match ( / ^ @ ? ( [ ^ : ] + ) : ( .* ) $ / ) || [ ]
112
+ return this . modifyPackage ( pkg , opts , ( pkgName , opts ) =>
113
+ libaccess . grant ( pkgName , scopeteam , perms , opts ) , false )
114
+ }
102
115
103
- if ( ! scope && ! team ) {
104
- throw UsageError (
105
- 'Second argument used incorrect format.\n' +
106
- 'Example: @example:developers'
107
- )
116
+ async revoke ( [ scopeteam , pkg ] , opts ) {
117
+ if ( ! scopeteam )
118
+ throw this . usageError ( '`<scope:team>` argument is required.' )
119
+
120
+ const [ , scope , team ] = scopeteam . match ( / ^ @ ? ( [ ^ : ] + ) : ( .* ) $ / ) || [ ]
121
+
122
+ if ( ! scope || ! team ) {
123
+ throw this . usageError (
124
+ 'First argument used incorrect format.\n' +
125
+ 'Example: @example:developers'
126
+ )
127
+ }
128
+
129
+ return this . modifyPackage ( pkg , opts , ( pkgName , opts ) =>
130
+ libaccess . revoke ( pkgName , scopeteam , opts ) )
108
131
}
109
132
110
- return modifyPackage ( pkg , opts , ( pkgName , opts ) =>
111
- libaccess . grant ( pkgName , scopeteam , perms , opts ) , false )
112
- }
133
+ get [ '2fa-required' ] ( ) {
134
+ return this . tfaRequired
135
+ }
113
136
114
- access . revoke = async ( [ scopeteam , pkg ] , opts ) => {
115
- if ( ! scopeteam )
116
- throw UsageError ( '`<scope:team>` argument is required.' )
137
+ tfaRequired ( [ pkg ] , opts ) {
138
+ return this . modifyPackage ( pkg , opts , libaccess . tfaRequired , false )
139
+ }
117
140
118
- const [ , scope , team ] = scopeteam . match ( / ^ @ ? ( [ ^ : ] + ) : ( .* ) $ / ) || [ ]
141
+ get [ '2fa-not-required' ] ( ) {
142
+ return this . tfaNotRequired
143
+ }
119
144
120
- if ( ! scope || ! team ) {
121
- throw UsageError (
122
- 'First argument used incorrect format.\n' +
123
- 'Example: @example:developers'
124
- )
145
+ tfaNotRequired ( [ pkg ] , opts ) {
146
+ return this . modifyPackage ( pkg , opts , libaccess . tfaNotRequired , false )
125
147
}
126
148
127
- return modifyPackage ( pkg , opts , ( pkgName , opts ) =>
128
- libaccess . revoke ( pkgName , scopeteam , opts ) )
129
- }
149
+ get [ 'ls-packages' ] ( ) {
150
+ return this . lsPackages
151
+ }
130
152
131
- access [ '2fa-required' ] = access . tfaRequired = ( [ pkg ] , opts ) =>
132
- modifyPackage ( pkg , opts , libaccess . tfaRequired , false )
153
+ async lsPackages ( [ owner ] , opts ) {
154
+ if ( ! owner )
155
+ owner = await getIdentity ( this . npm , opts )
133
156
134
- access [ '2fa-not-required' ] = access . tfaNotRequired = ( [ pkg ] , opts ) =>
135
- modifyPackage ( pkg , opts , libaccess . tfaNotRequired , false )
157
+ const pkgs = await libaccess . lsPackages ( owner , opts )
136
158
137
- access [ 'ls-packages' ] = access . lsPackages = async ( [ owner ] , opts ) => {
138
- if ( ! owner )
139
- owner = await getIdentity ( opts )
159
+ // TODO - print these out nicely (breaking change)
160
+ output ( JSON . stringify ( pkgs , null , 2 ) )
161
+ }
140
162
141
- const pkgs = await libaccess . lsPackages ( owner , opts )
163
+ get [ 'ls-collaborators' ] ( ) {
164
+ return this . lsCollaborators
165
+ }
142
166
143
- // TODO - print these out nicely (breaking change)
144
- output ( JSON . stringify ( pkgs , null , 2 ) )
145
- }
167
+ async lsCollaborators ( [ pkg , usr ] , opts ) {
168
+ const pkgName = await this . getPackage ( pkg , false )
169
+ const collabs = await libaccess . lsCollaborators ( pkgName , usr , opts )
146
170
147
- access [ 'ls-collaborators' ] = access . lsCollaborators = async ( [ pkg , usr ] , opts ) => {
148
- const pkgName = await getPackage ( pkg , false )
149
- const collabs = await libaccess . lsCollaborators ( pkgName , usr , opts )
171
+ // TODO - print these out nicely (breaking change)
172
+ output ( JSON . stringify ( collabs , null , 2 ) )
173
+ }
150
174
151
- // TODO - print these out nicely (breaking change)
152
- output ( JSON . stringify ( collabs , null , 2 ) )
153
- }
175
+ async edit ( ) {
176
+ throw new Error ( 'edit subcommand is not implemented yet' )
177
+ }
154
178
155
- access . edit = ( ) =>
156
- Promise . reject ( new Error ( 'edit subcommand is not implemented yet' ) )
157
-
158
- const modifyPackage = ( pkg , opts , fn , requireScope = true ) =>
159
- getPackage ( pkg , requireScope )
160
- . then ( pkgName => otplease ( opts , opts => fn ( pkgName , opts ) ) )
161
-
162
- const getPackage = async ( name , requireScope ) => {
163
- if ( name && name . trim ( ) )
164
- return name . trim ( )
165
- else {
166
- try {
167
- const pkg = await readPackageJson ( path . resolve ( npm . prefix , 'package.json' ) )
168
- name = pkg . name
169
- } catch ( err ) {
170
- if ( err . code === 'ENOENT' ) {
171
- throw new Error (
172
- 'no package name passed to command and no package.json found'
173
- )
174
- } else
175
- throw err
179
+ modifyPackage ( pkg , opts , fn , requireScope = true ) {
180
+ return this . getPackage ( pkg , requireScope )
181
+ . then ( pkgName => otplease ( opts , opts => fn ( pkgName , opts ) ) )
182
+ }
183
+
184
+ async getPackage ( name , requireScope ) {
185
+ if ( name && name . trim ( ) )
186
+ return name . trim ( )
187
+ else {
188
+ try {
189
+ const pkg = await readPackageJson ( path . resolve ( this . npm . prefix , 'package.json' ) )
190
+ name = pkg . name
191
+ } catch ( err ) {
192
+ if ( err . code === 'ENOENT' ) {
193
+ throw new Error (
194
+ 'no package name passed to command and no package.json found'
195
+ )
196
+ } else
197
+ throw err
198
+ }
199
+
200
+ if ( requireScope && ! name . match ( / ^ @ [ ^ / ] + \/ .* $ / ) )
201
+ throw this . usageError ( 'This command is only available for scoped packages.' )
202
+ else
203
+ return name
176
204
}
205
+ }
177
206
178
- if ( requireScope && ! name . match ( / ^ @ [ ^ / ] + \/ . * $ / ) )
179
- throw UsageError ( 'This command is only available for scoped packages.' )
180
- else
181
- return name
207
+ usageError ( msg ) {
208
+ return Object . assign ( new Error ( `\nUsage: ${ msg } \n\n` + this . usage ) , {
209
+ code : 'EUSAGE' ,
210
+ } )
182
211
}
183
212
}
184
213
185
- module . exports = Object . assign ( cmd , { usage , completion , subcommands } )
214
+ module . exports = Access
0 commit comments