@@ -16,7 +16,9 @@ const lockfile = require('@yarnpkg/lockfile');
16
16
const ini = require ( 'ini' ) ;
17
17
const pacote = require ( 'pacote' ) ;
18
18
19
- type PackageManagerOptions = Record < string , unknown > ;
19
+ interface PackageManagerOptions extends Record < string , unknown > {
20
+ forceAuth ?: Record < string , unknown > ;
21
+ }
20
22
21
23
const npmPackageJsonCache = new Map < string , Promise < Partial < NpmRepositoryPackageJson > > > ( ) ;
22
24
let npmrc : PackageManagerOptions ;
@@ -41,8 +43,8 @@ function readOptions(
41
43
}
42
44
43
45
const defaultConfigLocations = [
44
- path . join ( globalPrefix , 'etc' , baseFilename ) ,
45
- path . join ( homedir ( ) , dotFilename ) ,
46
+ ( ! yarn && process . env . NPM_CONFIG_GLOBALCONFIG ) || path . join ( globalPrefix , 'etc' , baseFilename ) ,
47
+ ( ! yarn && process . env . NPM_CONFIG_USERCONFIG ) || path . join ( homedir ( ) , dotFilename ) ,
46
48
] ;
47
49
48
50
const projectConfigLocations : string [ ] = [ path . join ( cwd , dotFilename ) ] ;
@@ -67,47 +69,57 @@ function readOptions(
67
69
// See: https://github.com/npm/npm-registry-fetch/blob/ebddbe78a5f67118c1f7af2e02c8a22bcaf9e850/index.js#L99-L126
68
70
const rcConfig : PackageManagerOptions = yarn ? lockfile . parse ( data ) : ini . parse ( data ) ;
69
71
for ( const [ key , value ] of Object . entries ( rcConfig ) ) {
72
+ let substitutedValue = value ;
73
+
74
+ // Substitute any environment variable references.
75
+ if ( typeof value === 'string' ) {
76
+ substitutedValue = value . replace ( / \$ \{ ( [ ^ \} ] + ) \} / , ( _ , name ) => process . env [ name ] || '' ) ;
77
+ }
78
+
70
79
switch ( key ) {
80
+ // Unless auth options are scope with the registry url it appears that npm-registry-fetch ignores them,
81
+ // even though they are documented.
82
+ // https://github.com/npm/npm-registry-fetch/blob/8954f61d8d703e5eb7f3d93c9b40488f8b1b62ac/README.md
83
+ // https://github.com/npm/npm-registry-fetch/blob/8954f61d8d703e5eb7f3d93c9b40488f8b1b62ac/auth.js#L45-L91
84
+ case '_authToken' :
85
+ case 'token' :
86
+ case 'username' :
87
+ case 'password' :
88
+ case '_auth' :
89
+ case 'auth' :
90
+ options [ 'forceAuth' ] ??= { } ;
91
+ options [ 'forceAuth' ] [ key ] = substitutedValue ;
92
+ break ;
71
93
case 'noproxy' :
72
94
case 'no-proxy' :
73
- options [ 'noProxy' ] = value ;
95
+ options [ 'noProxy' ] = substitutedValue ;
74
96
break ;
75
97
case 'maxsockets' :
76
- options [ 'maxSockets' ] = value ;
98
+ options [ 'maxSockets' ] = substitutedValue ;
77
99
break ;
78
100
case 'https-proxy' :
79
101
case 'proxy' :
80
- options [ 'proxy' ] = value ;
102
+ options [ 'proxy' ] = substitutedValue ;
81
103
break ;
82
104
case 'strict-ssl' :
83
- options [ 'strictSSL' ] = value ;
105
+ options [ 'strictSSL' ] = substitutedValue ;
84
106
break ;
85
107
case 'local-address' :
86
- options [ 'localAddress' ] = value ;
108
+ options [ 'localAddress' ] = substitutedValue ;
87
109
break ;
88
110
case 'cafile' :
89
- if ( typeof value === 'string' ) {
90
- const cafile = path . resolve ( path . dirname ( location ) , value ) ;
111
+ if ( typeof substitutedValue === 'string' ) {
112
+ const cafile = path . resolve ( path . dirname ( location ) , substitutedValue ) ;
91
113
try {
92
114
options [ 'ca' ] = readFileSync ( cafile , 'utf8' ) . replace ( / \r ? \n / g, '\n' ) ;
93
115
} catch { }
94
116
}
95
117
break ;
96
118
default :
97
- options [ key ] = value ;
119
+ options [ key ] = substitutedValue ;
98
120
break ;
99
121
}
100
122
}
101
- } else if ( showPotentials ) {
102
- logger . info ( `Trying '${ location } '...not found.` ) ;
103
- }
104
- }
105
-
106
- // Substitute any environment variable references
107
- for ( const key in options ) {
108
- const value = options [ key ] ;
109
- if ( typeof value === 'string' ) {
110
- options [ key ] = value . replace ( / \$ \{ ( [ ^ \} ] + ) \} / , ( _ , name ) => process . env [ name ] || '' ) ;
111
123
}
112
124
}
113
125
0 commit comments