@npmcli/config 1.2.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +57 -58
- package/lib/set-envs.js +6 -0
- package/package.json +1 -1
- package/lib/get-user-agent.js +0 -13
package/lib/index.js
CHANGED
|
@@ -47,7 +47,6 @@ const envReplace = require('./env-replace.js')
|
|
|
47
47
|
const parseField = require('./parse-field.js')
|
|
48
48
|
const typeDescription = require('./type-description.js')
|
|
49
49
|
const setEnvs = require('./set-envs.js')
|
|
50
|
-
const getUserAgent = require('./get-user-agent.js')
|
|
51
50
|
|
|
52
51
|
// types that can be saved back to
|
|
53
52
|
const confFileTypes = new Set([
|
|
@@ -69,6 +68,9 @@ const _get = Symbol('get')
|
|
|
69
68
|
const _find = Symbol('find')
|
|
70
69
|
const _loadObject = Symbol('loadObject')
|
|
71
70
|
const _loadFile = Symbol('loadFile')
|
|
71
|
+
const _checkDeprecated = Symbol('checkDeprecated')
|
|
72
|
+
const _flatten = Symbol('flatten')
|
|
73
|
+
const _flatOptions = Symbol('flatOptions')
|
|
72
74
|
|
|
73
75
|
class Config {
|
|
74
76
|
static get typeDefs () {
|
|
@@ -76,9 +78,9 @@ class Config {
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
constructor ({
|
|
79
|
-
|
|
81
|
+
definitions,
|
|
80
82
|
shorthands,
|
|
81
|
-
|
|
83
|
+
flatten,
|
|
82
84
|
npmPath,
|
|
83
85
|
|
|
84
86
|
// options just to override in tests, mostly
|
|
@@ -89,10 +91,27 @@ class Config {
|
|
|
89
91
|
execPath = process.execPath,
|
|
90
92
|
cwd = process.cwd(),
|
|
91
93
|
}) {
|
|
92
|
-
|
|
94
|
+
|
|
95
|
+
// turn the definitions into nopt's weirdo syntax
|
|
96
|
+
this.definitions = definitions
|
|
97
|
+
const types = {}
|
|
98
|
+
const defaults = {}
|
|
99
|
+
this.deprecated = {}
|
|
100
|
+
for (const [key, def] of Object.entries(definitions)) {
|
|
101
|
+
defaults[key] = def.default
|
|
102
|
+
types[key] = def.type
|
|
103
|
+
if (def.deprecated)
|
|
104
|
+
this.deprecated[key] = def.deprecated.trim().replace(/\n +/, '\n')
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// populated the first time we flatten the object
|
|
108
|
+
this[_flatOptions] = null
|
|
109
|
+
this[_flatten] = flatten
|
|
93
110
|
this.types = types
|
|
94
111
|
this.shorthands = shorthands
|
|
95
112
|
this.defaults = defaults
|
|
113
|
+
|
|
114
|
+
this.npmPath = npmPath
|
|
96
115
|
this.log = log
|
|
97
116
|
this.argv = argv
|
|
98
117
|
this.env = env
|
|
@@ -183,10 +202,31 @@ class Config {
|
|
|
183
202
|
if (!email)
|
|
184
203
|
throw new Error('Cannot set _auth without first setting email')
|
|
185
204
|
}
|
|
186
|
-
this
|
|
205
|
+
this[_checkDeprecated](key)
|
|
206
|
+
const { data } = this.data.get(where)
|
|
207
|
+
data[key] = val
|
|
187
208
|
|
|
188
209
|
// this is now dirty, the next call to this.valid will have to check it
|
|
189
210
|
this.data.get(where)[_valid] = null
|
|
211
|
+
|
|
212
|
+
// the flat options are invalidated, regenerate next time they're needed
|
|
213
|
+
this[_flatOptions] = null
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
get flat () {
|
|
217
|
+
if (this[_flatOptions])
|
|
218
|
+
return this[_flatOptions]
|
|
219
|
+
|
|
220
|
+
// create the object for flat options passed to deps
|
|
221
|
+
process.emit('time', 'config:load:flatten')
|
|
222
|
+
this[_flatOptions] = {}
|
|
223
|
+
// walk from least priority to highest
|
|
224
|
+
for (const { data } of this.data.values()) {
|
|
225
|
+
this[_flatten](data, this[_flatOptions])
|
|
226
|
+
}
|
|
227
|
+
process.emit('timeEnd', 'config:load:flatten')
|
|
228
|
+
|
|
229
|
+
return this[_flatOptions]
|
|
190
230
|
}
|
|
191
231
|
|
|
192
232
|
delete (key, where = 'cli') {
|
|
@@ -233,11 +273,6 @@ class Config {
|
|
|
233
273
|
await this.loadGlobalConfig()
|
|
234
274
|
process.emit('timeEnd', 'config:load:global')
|
|
235
275
|
|
|
236
|
-
// now the extras
|
|
237
|
-
process.emit('time', 'config:load:cafile')
|
|
238
|
-
await this.loadCAFile()
|
|
239
|
-
process.emit('timeEnd', 'config:load:cafile')
|
|
240
|
-
|
|
241
276
|
// warn if anything is not valid
|
|
242
277
|
process.emit('time', 'config:load:validate')
|
|
243
278
|
this.validate()
|
|
@@ -250,10 +285,6 @@ class Config {
|
|
|
250
285
|
// set proper globalPrefix now that everything is loaded
|
|
251
286
|
this.globalPrefix = this.get('prefix')
|
|
252
287
|
|
|
253
|
-
process.emit('time', 'config:load:setUserAgent')
|
|
254
|
-
this.setUserAgent()
|
|
255
|
-
process.emit('timeEnd', 'config:load:setUserAgent')
|
|
256
|
-
|
|
257
288
|
process.emit('time', 'config:load:setEnvs')
|
|
258
289
|
this.setEnvs()
|
|
259
290
|
process.emit('timeEnd', 'config:load:setEnvs')
|
|
@@ -376,13 +407,13 @@ class Config {
|
|
|
376
407
|
this.data.get(where)[_valid] = false
|
|
377
408
|
|
|
378
409
|
if (Array.isArray(type)) {
|
|
379
|
-
if (type.
|
|
410
|
+
if (type.includes(typeDefs.url.type))
|
|
380
411
|
type = typeDefs.url.type
|
|
381
412
|
else {
|
|
382
413
|
/* istanbul ignore if - no actual configs matching this, but
|
|
383
414
|
* path types SHOULD be handled this way, like URLs, for the
|
|
384
415
|
* same reason */
|
|
385
|
-
if (type.
|
|
416
|
+
if (type.includes(typeDefs.path.type))
|
|
386
417
|
type = typeDefs.path.type
|
|
387
418
|
}
|
|
388
419
|
}
|
|
@@ -428,11 +459,21 @@ class Config {
|
|
|
428
459
|
for (const [key, value] of Object.entries(obj)) {
|
|
429
460
|
const k = envReplace(key, this.env)
|
|
430
461
|
const v = this.parseField(value, k)
|
|
462
|
+
if (where !== 'default')
|
|
463
|
+
this[_checkDeprecated](k, where, obj, [key, value])
|
|
431
464
|
conf.data[k] = v
|
|
432
465
|
}
|
|
433
466
|
}
|
|
434
467
|
}
|
|
435
468
|
|
|
469
|
+
[_checkDeprecated] (key, where, obj, kv) {
|
|
470
|
+
// XXX a future npm version will make this a warning.
|
|
471
|
+
// An even more future npm version will make this an error.
|
|
472
|
+
if (this.deprecated[key]) {
|
|
473
|
+
this.log.verbose('config', key, this.deprecated[key])
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
436
477
|
// Parse a field, coercing it to the best type available.
|
|
437
478
|
parseField (f, key, listElement = false) {
|
|
438
479
|
return parseField(f, key, this, listElement)
|
|
@@ -675,48 +716,6 @@ class Config {
|
|
|
675
716
|
return creds
|
|
676
717
|
}
|
|
677
718
|
|
|
678
|
-
async loadCAFile () {
|
|
679
|
-
const where = this[_find]('cafile')
|
|
680
|
-
|
|
681
|
-
/* istanbul ignore if - it'll always be set in the defaults */
|
|
682
|
-
if (!where)
|
|
683
|
-
return
|
|
684
|
-
|
|
685
|
-
const cafile = this[_get]('cafile', where)
|
|
686
|
-
const ca = this[_get]('ca', where)
|
|
687
|
-
|
|
688
|
-
// if you have a ca, or cafile is set to null, then nothing to do here.
|
|
689
|
-
if (ca || !cafile)
|
|
690
|
-
return
|
|
691
|
-
|
|
692
|
-
const raw = await readFile(cafile, 'utf8').catch(er => {
|
|
693
|
-
if (er.code !== 'ENOENT')
|
|
694
|
-
throw er
|
|
695
|
-
})
|
|
696
|
-
if (!raw)
|
|
697
|
-
return
|
|
698
|
-
|
|
699
|
-
const delim = '-----END CERTIFICATE-----'
|
|
700
|
-
const output = raw.replace(/\r\n/g, '\n').split(delim)
|
|
701
|
-
.filter(section => section.trim())
|
|
702
|
-
.map(section => section.trimLeft() + delim)
|
|
703
|
-
|
|
704
|
-
// make it non-enumerable so we don't save it back by accident
|
|
705
|
-
const { data } = this.data.get(where)
|
|
706
|
-
Object.defineProperty(data, 'ca', {
|
|
707
|
-
value: output,
|
|
708
|
-
enumerable: false,
|
|
709
|
-
configurable: true,
|
|
710
|
-
writable: true,
|
|
711
|
-
})
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
// the user-agent configuration is a template that gets populated
|
|
715
|
-
// with some variables, that takes place here
|
|
716
|
-
setUserAgent () {
|
|
717
|
-
this.set('user-agent', getUserAgent(this))
|
|
718
|
-
}
|
|
719
|
-
|
|
720
719
|
// set up the environment object we have with npm_config_* environs
|
|
721
720
|
// for all configs that are different from their default values, and
|
|
722
721
|
// set EDITOR and HOME.
|
package/lib/set-envs.js
CHANGED
|
@@ -50,11 +50,13 @@ const setEnvs = (config) => {
|
|
|
50
50
|
platform,
|
|
51
51
|
env,
|
|
52
52
|
defaults,
|
|
53
|
+
definitions,
|
|
53
54
|
list: [cliConf, envConf],
|
|
54
55
|
} = config
|
|
55
56
|
|
|
56
57
|
env.INIT_CWD = process.cwd()
|
|
57
58
|
|
|
59
|
+
// if the key is deprecated, skip it always.
|
|
58
60
|
// if the key is the default value,
|
|
59
61
|
// if the environ is NOT the default value,
|
|
60
62
|
// set the environ
|
|
@@ -65,6 +67,10 @@ const setEnvs = (config) => {
|
|
|
65
67
|
const cliSet = new Set(Object.keys(cliConf))
|
|
66
68
|
const envSet = new Set(Object.keys(envConf))
|
|
67
69
|
for (const key in cliConf) {
|
|
70
|
+
const { deprecated } = definitions[key] || {}
|
|
71
|
+
if (deprecated)
|
|
72
|
+
continue
|
|
73
|
+
|
|
68
74
|
if (sameConfigValue(defaults[key], cliConf[key])) {
|
|
69
75
|
// config is the default, if the env thought different, then we
|
|
70
76
|
// have to set it BACK to the default in the environment.
|
package/package.json
CHANGED
package/lib/get-user-agent.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// Accepts a config object, returns a user-agent string
|
|
2
|
-
const getUserAgent = (config) => {
|
|
3
|
-
const ciName = config.get('ci-name')
|
|
4
|
-
return (config.get('user-agent') || '')
|
|
5
|
-
.replace(/\{node-version\}/gi, config.get('node-version'))
|
|
6
|
-
.replace(/\{npm-version\}/gi, config.get('npm-version'))
|
|
7
|
-
.replace(/\{platform\}/gi, process.platform)
|
|
8
|
-
.replace(/\{arch\}/gi, process.arch)
|
|
9
|
-
.replace(/\{ci\}/gi, ciName ? `ci/${ciName}` : '')
|
|
10
|
-
.trim()
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
module.exports = getUserAgent
|