diff --git a/node_modules/@npmcli/config/lib/env-replace.js b/node_modules/@npmcli/config/lib/env-replace.js index 464dc550b00fb..a6e4b2968d04e 100644 --- a/node_modules/@npmcli/config/lib/env-replace.js +++ b/node_modules/@npmcli/config/lib/env-replace.js @@ -3,11 +3,12 @@ const envExpr = /(\\*)\$\{([^}]+)\}/g module.exports = (f, env) => f.replace(envExpr, (orig, esc, name) => { - const val = env[name] !== undefined ? env[name] : `\$\{${name}\}` + const val = env[name] !== undefined ? env[name] : `$\{${name}}` // consume the escape chars that are relevant. - if (esc.length % 2) + if (esc.length % 2) { return orig.substr((esc.length + 1) / 2) + } return (esc.substr(esc.length / 2)) + val }) diff --git a/node_modules/@npmcli/config/lib/index.js b/node_modules/@npmcli/config/lib/index.js index 293fad2ec56c3..dc839a5389c3a 100644 --- a/node_modules/@npmcli/config/lib/index.js +++ b/node_modules/@npmcli/config/lib/index.js @@ -3,6 +3,8 @@ const walkUp = require('walk-up-path') const ini = require('ini') const nopt = require('nopt') const mkdirp = require('mkdirp-infer-owner') +const mapWorkspaces = require('@npmcli/map-workspaces') +const rpj = require('read-package-json-fast') /* istanbul ignore next */ const myUid = process.getuid && process.getuid() @@ -91,7 +93,6 @@ class Config { execPath = process.execPath, cwd = process.cwd(), }) { - // turn the definitions into nopt's weirdo syntax this.definitions = definitions const types = {} @@ -100,8 +101,9 @@ class Config { for (const [key, def] of Object.entries(definitions)) { defaults[key] = def.default types[key] = def.type - if (def.deprecated) + if (def.deprecated) { this.deprecated[key] = def.deprecated.trim().replace(/\n +/, '\n') + } } // populated the first time we flatten the object @@ -162,41 +164,48 @@ class Config { // return the location where key is found. find (key) { - if (!this.loaded) + if (!this.loaded) { throw new Error('call config.load() before reading values') + } return this[_find](key) } + [_find] (key) { // have to look in reverse order const entries = [...this.data.entries()] for (let i = entries.length - 1; i > -1; i--) { const [where, { data }] = entries[i] - if (hasOwnProperty(data, key)) + if (hasOwnProperty(data, key)) { return where + } } return null } get (key, where) { - if (!this.loaded) + if (!this.loaded) { throw new Error('call config.load() before reading values') + } return this[_get](key, where) } + // we need to get values sometimes, so use this internal one to do so // while in the process of loading. [_get] (key, where = null) { if (where !== null && !confTypes.has(where)) { throw new Error('invalid config location param: ' + where) } - const { data, source } = this.data.get(where || 'cli') + const { data } = this.data.get(where || 'cli') return where === null || hasOwnProperty(data, key) ? data[key] : undefined } set (key, val, where = 'cli') { - if (!this.loaded) + if (!this.loaded) { throw new Error('call config.load() before setting values') - if (!confTypes.has(where)) + } + if (!confTypes.has(where)) { throw new Error('invalid config location param: ' + where) + } this[_checkDeprecated](key) const { data } = this.data.get(where) data[key] = val @@ -209,8 +218,9 @@ class Config { } get flat () { - if (this[_flatOptions]) + if (this[_flatOptions]) { return this[_flatOptions] + } // create the object for flat options passed to deps process.emit('time', 'config:load:flatten') @@ -225,16 +235,19 @@ class Config { } delete (key, where = 'cli') { - if (!this.loaded) + if (!this.loaded) { throw new Error('call config.load() before deleting values') - if (!confTypes.has(where)) + } + if (!confTypes.has(where)) { throw new Error('invalid config location param: ' + where) + } delete this.data.get(where).data[key] } async load () { - if (this.loaded) + if (this.loaded) { throw new Error('attempting to load npm config multiple times') + } process.emit('time', 'config:load') // first load the defaults, which sets the global prefix @@ -282,7 +295,9 @@ class Config { const creds = this.getCredentialsByURI(reg) // ignore this error because a failed set will strip out anything that // might be a security hazard, which was the intention. - try { this.setCredentialsByURI(reg, creds) } catch (_) {} + try { + this.setCredentialsByURI(reg, creds) + } catch (_) {} process.emit('timeEnd', 'config:load:credentials') // set proper globalPrefix now that everything is loaded @@ -319,14 +334,16 @@ class Config { } loadHome () { - if (this.env.HOME) + if (this.env.HOME) { return this.home = this.env.HOME + } this.home = homedir() } loadGlobalPrefix () { - if (this.globalPrefix) + if (this.globalPrefix) { throw new Error('cannot load default global prefix more than once') + } if (this.env.PREFIX) { this.globalPrefix = this.env.PREFIX @@ -338,17 +355,18 @@ class Config { this.globalPrefix = dirname(dirname(this.execPath)) // destdir only is respected on Unix - if (this.env.DESTDIR) + if (this.env.DESTDIR) { this.globalPrefix = join(this.env.DESTDIR, this.globalPrefix) + } } } loadEnv () { - const prefix = 'npm_config_' const conf = Object.create(null) for (const [envKey, envVal] of Object.entries(this.env)) { - if (!/^npm_config_/i.test(envKey) || envVal === '') + if (!/^npm_config_/i.test(envKey) || envVal === '') { continue + } const key = envKey.substr('npm_config_'.length) .replace(/(?!^)_/g, '-') // don't replace _ at the start of the key .toLowerCase() @@ -368,9 +386,10 @@ class Config { } get valid () { - for (const [where, {valid}] of this.data.entries()) { - if (valid === false || valid === null && !this.validate(where)) + for (const [where, { valid }] of this.data.entries()) { + if (valid === false || valid === null && !this.validate(where)) { return false + } } return true } @@ -378,11 +397,12 @@ class Config { validate (where) { if (!where) { let valid = true - for (const [where, obj] of this.data.entries()) { + for (const [where] of this.data.entries()) { // no need to validate our defaults, we know they're fine // cli was already validated when parsed the first time - if (where === 'default' || where === 'builtin' || where === 'cli') + if (where === 'default' || where === 'builtin' || where === 'cli') { continue + } const ret = this.validate(where) valid = valid && ret } @@ -424,14 +444,15 @@ class Config { this.data.get(where)[_valid] = false if (Array.isArray(type)) { - if (type.includes(typeDefs.url.type)) + if (type.includes(typeDefs.url.type)) { type = typeDefs.url.type - else { + } else { /* istanbul ignore if - no actual configs matching this, but * path types SHOULD be handled this way, like URLs, for the * same reason */ - if (type.includes(typeDefs.path.type)) + if (type.includes(typeDefs.path.type)) { type = typeDefs.path.type + } } } @@ -469,15 +490,17 @@ class Config { this.sources.set(source, where) if (er) { conf.loadError = er - if (er.code !== 'ENOENT') + if (er.code !== 'ENOENT') { this.log.verbose('config', `error loading ${where} config`, er) + } } else { conf.raw = obj for (const [key, value] of Object.entries(obj)) { const k = envReplace(key, this.env) const v = this.parseField(value, k) - if (where !== 'default') + if (where !== 'default') { this[_checkDeprecated](k, where, obj, [key, value]) + } conf.data[k] = v } } @@ -528,9 +551,9 @@ class Config { // up loading the "project" config where the "userconfig" will be, // which causes some calamaties. So, we only load project config if // it doesn't match what the userconfig will be. - if (projectFile !== this[_get]('userconfig')) + if (projectFile !== this[_get]('userconfig')) { return this[_loadFile](projectFile, 'project') - else { + } else { this.data.get('project').source = '(same as "user" config, ignored)' this.sources.set(this.data.get('project').source, 'project') } @@ -543,23 +566,65 @@ class Config { return } + const cliWorkspaces = this[_get]('workspaces', 'cli') + for (const p of walkUp(this.cwd)) { - // walk up until we have a nm dir or a pj file - const hasAny = (await Promise.all([ - stat(resolve(p, 'node_modules')) - .then(st => st.isDirectory()) - .catch(() => false), - stat(resolve(p, 'package.json')) - .then(st => st.isFile()) - .catch(() => false), - ])).some(is => is) - if (hasAny) { + const hasNodeModules = await stat(resolve(p, 'node_modules')) + .then((st) => st.isDirectory()) + .catch(() => false) + + const hasPackageJson = await stat(resolve(p, 'package.json')) + .then((st) => st.isFile()) + .catch(() => false) + + if (!this.localPrefix && (hasNodeModules || hasPackageJson)) { this.localPrefix = p - return + + // if workspaces are disabled, return now + if (cliWorkspaces === false) { + return + } + + // otherwise, continue the loop + continue + } + + if (this.localPrefix && hasPackageJson) { + // if we already set localPrefix but this dir has a package.json + // then we need to see if `p` is a workspace root by reading its package.json + // however, if reading it fails then we should just move on + const pkg = await rpj(resolve(p, 'package.json')).catch(() => false) + if (!pkg) { + continue + } + + const workspaces = await mapWorkspaces({ cwd: p, pkg }) + for (const w of workspaces.values()) { + if (w === this.localPrefix) { + // see if there's a .npmrc file in the workspace, if so log a warning + const hasNpmrc = await stat(resolve(this.localPrefix, '.npmrc')) + .then((st) => st.isFile()) + .catch(() => false) + + if (hasNpmrc) { + this.log.warn(`ignoring workspace config at ${this.localPrefix}/.npmrc`) + } + + // set the workspace in the default layer, which allows it to be overridden easily + const { data } = this.data.get('default') + data.workspace = [this.localPrefix] + this.localPrefix = p + this.log.info(`found workspace root at ${this.localPrefix}`) + // we found a root, so we return now + return + } + } } } - this.localPrefix = this.cwd + if (!this.localPrefix) { + this.localPrefix = this.cwd + } } loadUserConfig () { @@ -571,10 +636,12 @@ class Config { } async save (where) { - if (!this.loaded) + if (!this.loaded) { throw new Error('call config.load() before saving') - if (!confFileTypes.has(where)) + } + if (!confFileTypes.has(where)) { throw new Error('invalid config location param: ' + where) + } const conf = this.data.get(where) conf[_raw] = { ...conf.data } conf[_loadError] = null @@ -586,7 +653,9 @@ class Config { // we ignore this error because the failed set already removed // anything that might be a security hazard, and it won't be // saved back to the .npmrc file, so we're good. - try { this.setCredentialsByURI(reg, creds) } catch (_) {} + try { + this.setCredentialsByURI(reg, creds) + } catch (_) {} } const iniData = ini.stringify(conf.data).trim() + '\n' @@ -602,8 +671,9 @@ class Config { /* istanbul ignore if - this is best-effort and a pita to test */ if (myUid === 0) { const st = await stat(dir).catch(() => null) - if (st && (st.uid !== myUid || st.gid !== myGid)) + if (st && (st.uid !== myUid || st.gid !== myGid)) { await chown(conf.source, st.uid, st.gid).catch(() => {}) + } } const mode = where === 'user' ? 0o600 : 0o666 await chmod(conf.source, mode) @@ -651,8 +721,9 @@ class Config { email = email || this.get('email', 'user') || this.get(`${nerfed}:email`, 'user') - if (email) + if (email) { this.set('email', email, 'user') + } } // field that hasn't been used as documented for a LONG time, @@ -668,10 +739,12 @@ class Config { this.delete(`${nerfed}:_password`, 'user') this.delete(`${nerfed}:username`, 'user') } else if (username || password) { - if (!username) + if (!username) { throw new Error('must include username') - if (!password) + } + if (!password) { throw new Error('must include password') + } this.delete(`${nerfed}:_authToken`, 'user') this.set(`${nerfed}:username`, username, 'user') // note: not encrypted, no idea why we bothered to do this, but oh well @@ -689,8 +762,9 @@ class Config { const creds = {} const email = this.get(`${nerfed}:email`) || this.get('email') - if (email) + if (email) { creds.email = email + } const tokenReg = this.get(`${nerfed}:_authToken`) || this.get(`${nerfed}:_authtoken`) || @@ -725,8 +799,9 @@ class Config { // at this point, we can only use the values if the URI is the // default registry. const defaultNerf = nerfDart(this.get('registry')) - if (nerfed !== defaultNerf) + if (nerfed !== defaultNerf) { return creds + } const userDef = this.get('username') const passDef = this.get('_password') @@ -741,8 +816,9 @@ class Config { // Handle the old-style _auth= style for the default // registry, if set. const auth = this.get('_auth') - if (!auth) + if (!auth) { return creds + } const authDecode = Buffer.from(auth, 'base64').toString('utf8') const authSplit = authDecode.split(':') @@ -755,7 +831,9 @@ class Config { // set up the environment object we have with npm_config_* environs // for all configs that are different from their default values, and // set EDITOR and HOME. - setEnvs () { setEnvs(this) } + setEnvs () { + setEnvs(this) + } } const _data = Symbol('data') @@ -781,25 +859,37 @@ class ConfigData { } set source (s) { - if (this[_source]) + if (this[_source]) { throw new Error('cannot set ConfigData source more than once') + } this[_source] = s } - get source () { return this[_source] } + + get source () { + return this[_source] + } set loadError (e) { - if (this[_loadError] || this[_raw]) + if (this[_loadError] || this[_raw]) { throw new Error('cannot set ConfigData loadError after load') + } this[_loadError] = e } - get loadError () { return this[_loadError] } + + get loadError () { + return this[_loadError] + } set raw (r) { - if (this[_raw] || this[_loadError]) + if (this[_raw] || this[_loadError]) { throw new Error('cannot set ConfigData raw after load') + } this[_raw] = r } - get raw () { return this[_raw] } + + get raw () { + return this[_raw] + } } module.exports = Config diff --git a/node_modules/@npmcli/config/lib/parse-field.js b/node_modules/@npmcli/config/lib/parse-field.js index 95b8d9f272003..9428996c98a35 100644 --- a/node_modules/@npmcli/config/lib/parse-field.js +++ b/node_modules/@npmcli/config/lib/parse-field.js @@ -6,10 +6,11 @@ const { resolve } = require('path') const { parse: umaskParse } = require('./umask.js') const parseField = (f, key, opts, listElement = false) => { - if (typeof f !== 'string' && !Array.isArray(f)) + if (typeof f !== 'string' && !Array.isArray(f)) { return f + } - const { platform, types, log, home, env } = opts + const { platform, types, home, env } = opts // type can be array or a single thing. coerce to array. const typeList = new Set([].concat(types[key])) @@ -20,8 +21,9 @@ const parseField = (f, key, opts, listElement = false) => { const isNumber = typeList.has(typeDefs.Number.type) const isList = !listElement && typeList.has(Array) - if (Array.isArray(f)) + if (Array.isArray(f)) { return !isList ? f : f.map(field => parseField(field, key, opts, true)) + } // now we know it's a string f = f.trim() @@ -29,12 +31,14 @@ const parseField = (f, key, opts, listElement = false) => { // list types get put in the environment separated by double-\n // usually a single \n would suffice, but ca/cert configs can contain // line breaks and multiple entries. - if (isList) + if (isList) { return parseField(f.split('\n\n'), key, opts) + } // --foo is like --foo=true for boolean types - if (isBool && !isString && f === '') + if (isBool && !isString && f === '') { return true + } // string types can be the string 'true', 'false', etc. // otherwise, parse these values out @@ -51,10 +55,11 @@ const parseField = (f, key, opts, listElement = false) => { if (isPath) { const homePattern = platform === 'win32' ? /^~(\/|\\)/ : /^~\// - if (homePattern.test(f) && home) + if (homePattern.test(f) && home) { f = resolve(home, f.substr(2)) - else + } else { f = resolve(f) + } } if (isUmask) { @@ -66,8 +71,9 @@ const parseField = (f, key, opts, listElement = false) => { } } - if (isNumber && !isNaN(f)) + if (isNumber && !isNaN(f)) { f = +f + } return f } diff --git a/node_modules/@npmcli/config/lib/set-envs.js b/node_modules/@npmcli/config/lib/set-envs.js index 8eed0221ba80e..0f5781aaf3395 100644 --- a/node_modules/@npmcli/config/lib/set-envs.js +++ b/node_modules/@npmcli/config/lib/set-envs.js @@ -22,15 +22,17 @@ const sameConfigValue = (def, val) => : sameArrayValue(def, val) const sameArrayValue = (def, val) => { - if (def.length !== val.length) + if (def.length !== val.length) { return false + } for (let i = 0; i < def.length; i++) { /* istanbul ignore next - there are no array configs where the default * is not an empty array, so this loop is a no-op, but it's the correct * thing to do if we ever DO add a config like that. */ - if (def[i] !== val[i]) + if (def[i] !== val[i]) { return false + } } return true } @@ -38,16 +40,15 @@ const sameArrayValue = (def, val) => { const setEnv = (env, rawKey, rawVal) => { const val = envVal(rawVal) const key = envKey(rawKey, val) - if (key && val !== null) + if (key && val !== null) { env[key] = val + } } const setEnvs = (config) => { // This ensures that all npm config values that are not the defaults are // shared appropriately with child processes, without false positives. const { - globalPrefix, - platform, env, defaults, definitions, @@ -68,19 +69,22 @@ const setEnvs = (config) => { const envSet = new Set(Object.keys(envConf)) for (const key in cliConf) { const { deprecated, envExport = true } = definitions[key] || {} - if (deprecated || envExport === false) + if (deprecated || envExport === false) { continue + } if (sameConfigValue(defaults[key], cliConf[key])) { // config is the default, if the env thought different, then we // have to set it BACK to the default in the environment. - if (!sameConfigValue(envConf[key], cliConf[key])) + if (!sameConfigValue(envConf[key], cliConf[key])) { setEnv(env, key, cliConf[key]) + } } else { // config is not the default. if the env wasn't the one to set // it that way, then we have to put it in the env - if (!(envSet.has(key) && !cliSet.has(key))) + if (!(envSet.has(key) && !cliSet.has(key))) { setEnv(env, key, cliConf[key]) + } } } @@ -88,16 +92,19 @@ const setEnvs = (config) => { env.HOME = config.home env.npm_config_global_prefix = config.globalPrefix env.npm_config_local_prefix = config.localPrefix - if (cliConf.editor) + if (cliConf.editor) { env.EDITOR = cliConf.editor + } // note: this doesn't afect the *current* node process, of course, since // it's already started, but it does affect the options passed to scripts. - if (cliConf['node-options']) + if (cliConf['node-options']) { env.NODE_OPTIONS = cliConf['node-options'] + } - if (require.main && require.main.filename) + if (require.main && require.main.filename) { env.npm_execpath = require.main.filename + } env.NODE = env.npm_node_execpath = config.execPath } diff --git a/node_modules/@npmcli/config/lib/type-defs.js b/node_modules/@npmcli/config/lib/type-defs.js index 049945a3e5812..20a827c3d164e 100644 --- a/node_modules/@npmcli/config/lib/type-defs.js +++ b/node_modules/@npmcli/config/lib/type-defs.js @@ -5,15 +5,17 @@ const { Umask, validate: validateUmask } = require('./umask.js') const semver = require('semver') const validateSemver = (data, k, val) => { const valid = semver.valid(val) - if (!valid) + if (!valid) { return false + } data[k] = valid } const noptValidatePath = nopt.typeDefs.path.validate const validatePath = (data, k, val) => { - if (typeof val !== 'string') + if (typeof val !== 'string') { return false + } return noptValidatePath(data, k, val) } diff --git a/node_modules/@npmcli/config/lib/type-description.js b/node_modules/@npmcli/config/lib/type-description.js index 828a747db4aac..f5e0d164f9edc 100644 --- a/node_modules/@npmcli/config/lib/type-description.js +++ b/node_modules/@npmcli/config/lib/type-description.js @@ -2,15 +2,18 @@ // returns a string for one thing, or an array of descriptions const typeDefs = require('./type-defs.js') const typeDescription = t => { - if (!t || typeof t !== 'function' && typeof t !== 'object') + if (!t || typeof t !== 'function' && typeof t !== 'object') { return t + } - if (Array.isArray(t)) + if (Array.isArray(t)) { return t.map(t => typeDescription(t)) + } for (const { type, description } of Object.values(typeDefs)) { - if (type === t) + if (type === t) { return description || type + } } return t diff --git a/node_modules/@npmcli/config/lib/umask.js b/node_modules/@npmcli/config/lib/umask.js index b445c6fca95bf..195fad2386702 100644 --- a/node_modules/@npmcli/config/lib/umask.js +++ b/node_modules/@npmcli/config/lib/umask.js @@ -1,18 +1,21 @@ class Umask {} const parse = val => { if (typeof val === 'string') { - if (/^0o?[0-7]+$/.test(val)) + if (/^0o?[0-7]+$/.test(val)) { return parseInt(val.replace(/^0o?/, ''), 8) - else if (/^[1-9][0-9]*$/.test(val)) + } else if (/^[1-9][0-9]*$/.test(val)) { return parseInt(val, 10) - else + } else { throw new Error(`invalid umask value: ${val}`) + } } - if (typeof val !== 'number') + if (typeof val !== 'number') { throw new Error(`invalid umask value: ${val}`) + } val = Math.floor(val) - if (val < 0 || val > 511) + if (val < 0 || val > 511) { throw new Error(`invalid umask value: ${val}`) + } return val } diff --git a/node_modules/@npmcli/config/package.json b/node_modules/@npmcli/config/package.json index 83d8a349d224d..b0722db413e5b 100644 --- a/node_modules/@npmcli/config/package.json +++ b/node_modules/@npmcli/config/package.json @@ -1,7 +1,8 @@ { "name": "@npmcli/config", - "version": "2.4.0", + "version": "3.0.0", "files": [ + "bin", "lib" ], "main": "lib/index.js", @@ -10,30 +11,41 @@ "type": "git", "url": "git+https://github.com/npm/config" }, - "author": "Isaac Z. Schlueter (https://izs.me)", + "author": "GitHub Inc.", "license": "ISC", "scripts": { "test": "tap", "snap": "tap", "preversion": "npm test", "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" + "prepublishOnly": "git push origin --follow-tags", + "lint": "eslint '**/*.js'", + "postlint": "npm-template-check", + "lintfix": "npm run lint -- --fix", + "posttest": "npm run lint", + "template-copy": "npm-template-copy --force" }, "tap": { "check-coverage": true, "coverage-map": "map.js" }, "devDependencies": { + "@npmcli/template-oss": "^2.5.1", "tap": "^15.0.4" }, "dependencies": { + "@npmcli/map-workspaces": "^2.0.0", "ini": "^2.0.0", "mkdirp-infer-owner": "^2.0.0", "nopt": "^5.0.0", + "read-package-json-fast": "^2.0.3", "semver": "^7.3.4", "walk-up-path": "^1.0.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16" + }, + "templateOSS": { + "version": "2.6.0" } } diff --git a/package-lock.json b/package-lock.json index f7bc4ff7b9486..cecb7124cf49d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,7 +89,7 @@ "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^4.3.1", "@npmcli/ci-detect": "^1.4.0", - "@npmcli/config": "^2.4.0", + "@npmcli/config": "^3.0.0", "@npmcli/map-workspaces": "^2.0.0", "@npmcli/package-json": "^1.0.1", "@npmcli/run-script": "^2.0.0", @@ -812,19 +812,21 @@ "inBundle": true }, "node_modules/@npmcli/config": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-2.4.0.tgz", - "integrity": "sha512-fwxu/zaZnvBJohXM3igzqa3P1IVYWi5N343XcKvKkJbAx+rTqegS5tAul4NLiMPQh6WoS5a4er6oo/ieUx1f4g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-3.0.0.tgz", + "integrity": "sha512-2cYe2MCGintq1s6izbLYO2gAHZwNFQ92lIb5QhtpRizwHwqrV9v4+xNpvx1EBaEaqTHFR4QuozgZLA1scao/5Q==", "inBundle": true, "dependencies": { + "@npmcli/map-workspaces": "^2.0.0", "ini": "^2.0.0", "mkdirp-infer-owner": "^2.0.0", "nopt": "^5.0.0", + "read-package-json-fast": "^2.0.3", "semver": "^7.3.4", "walk-up-path": "^1.0.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16" } }, "node_modules/@npmcli/disparity-colors": { @@ -11486,13 +11488,15 @@ "integrity": "sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q==" }, "@npmcli/config": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-2.4.0.tgz", - "integrity": "sha512-fwxu/zaZnvBJohXM3igzqa3P1IVYWi5N343XcKvKkJbAx+rTqegS5tAul4NLiMPQh6WoS5a4er6oo/ieUx1f4g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-3.0.0.tgz", + "integrity": "sha512-2cYe2MCGintq1s6izbLYO2gAHZwNFQ92lIb5QhtpRizwHwqrV9v4+xNpvx1EBaEaqTHFR4QuozgZLA1scao/5Q==", "requires": { + "@npmcli/map-workspaces": "^2.0.0", "ini": "^2.0.0", "mkdirp-infer-owner": "^2.0.0", "nopt": "^5.0.0", + "read-package-json-fast": "^2.0.3", "semver": "^7.3.4", "walk-up-path": "^1.0.0" } diff --git a/package.json b/package.json index 9cfeb2e620851..3f3f27c4c0288 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^4.3.1", "@npmcli/ci-detect": "^1.4.0", - "@npmcli/config": "^2.4.0", + "@npmcli/config": "^3.0.0", "@npmcli/map-workspaces": "^2.0.0", "@npmcli/package-json": "^1.0.1", "@npmcli/run-script": "^2.0.0",