11cb0ef41Sopenharmony_ciconst { mkdir, readFile, writeFile } = require('fs/promises') 21cb0ef41Sopenharmony_ciconst { dirname, resolve } = require('path') 31cb0ef41Sopenharmony_ciconst { spawn } = require('child_process') 41cb0ef41Sopenharmony_ciconst { EOL } = require('os') 51cb0ef41Sopenharmony_ciconst ini = require('ini') 61cb0ef41Sopenharmony_ciconst localeCompare = require('@isaacs/string-locale-compare')('en') 71cb0ef41Sopenharmony_ciconst pkgJson = require('@npmcli/package-json') 81cb0ef41Sopenharmony_ciconst { defaults, definitions } = require('@npmcli/config/lib/definitions') 91cb0ef41Sopenharmony_ciconst log = require('../utils/log-shim.js') 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci// These are the configs that we can nerf-dart. Not all of them currently even 121cb0ef41Sopenharmony_ci// *have* config definitions so we have to explicitly validate them here 131cb0ef41Sopenharmony_ciconst nerfDarts = [ 141cb0ef41Sopenharmony_ci '_auth', 151cb0ef41Sopenharmony_ci '_authToken', 161cb0ef41Sopenharmony_ci 'username', 171cb0ef41Sopenharmony_ci '_password', 181cb0ef41Sopenharmony_ci 'email', 191cb0ef41Sopenharmony_ci 'certfile', 201cb0ef41Sopenharmony_ci 'keyfile', 211cb0ef41Sopenharmony_ci] 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci// take an array of `[key, value, k2=v2, k3, v3, ...]` and turn into 241cb0ef41Sopenharmony_ci// { key: value, k2: v2, k3: v3 } 251cb0ef41Sopenharmony_ciconst keyValues = args => { 261cb0ef41Sopenharmony_ci const kv = {} 271cb0ef41Sopenharmony_ci for (let i = 0; i < args.length; i++) { 281cb0ef41Sopenharmony_ci const arg = args[i].split('=') 291cb0ef41Sopenharmony_ci const key = arg.shift() 301cb0ef41Sopenharmony_ci const val = arg.length ? arg.join('=') 311cb0ef41Sopenharmony_ci : i < args.length - 1 ? args[++i] 321cb0ef41Sopenharmony_ci : '' 331cb0ef41Sopenharmony_ci kv[key.trim()] = val.trim() 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci return kv 361cb0ef41Sopenharmony_ci} 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciconst publicVar = k => { 391cb0ef41Sopenharmony_ci // _password 401cb0ef41Sopenharmony_ci if (k.startsWith('_')) { 411cb0ef41Sopenharmony_ci return false 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci // //localhost:8080/:_password 441cb0ef41Sopenharmony_ci if (k.startsWith('//') && k.includes(':_')) { 451cb0ef41Sopenharmony_ci return false 461cb0ef41Sopenharmony_ci } 471cb0ef41Sopenharmony_ci return true 481cb0ef41Sopenharmony_ci} 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ciconst BaseCommand = require('../base-command.js') 511cb0ef41Sopenharmony_ciclass Config extends BaseCommand { 521cb0ef41Sopenharmony_ci static description = 'Manage the npm configuration files' 531cb0ef41Sopenharmony_ci static name = 'config' 541cb0ef41Sopenharmony_ci static usage = [ 551cb0ef41Sopenharmony_ci 'set <key>=<value> [<key>=<value> ...]', 561cb0ef41Sopenharmony_ci 'get [<key> [<key> ...]]', 571cb0ef41Sopenharmony_ci 'delete <key> [<key> ...]', 581cb0ef41Sopenharmony_ci 'list [--json]', 591cb0ef41Sopenharmony_ci 'edit', 601cb0ef41Sopenharmony_ci 'fix', 611cb0ef41Sopenharmony_ci ] 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci static params = [ 641cb0ef41Sopenharmony_ci 'json', 651cb0ef41Sopenharmony_ci 'global', 661cb0ef41Sopenharmony_ci 'editor', 671cb0ef41Sopenharmony_ci 'location', 681cb0ef41Sopenharmony_ci 'long', 691cb0ef41Sopenharmony_ci ] 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci static ignoreImplicitWorkspace = false 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci static skipConfigValidation = true 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci static async completion (opts) { 761cb0ef41Sopenharmony_ci const argv = opts.conf.argv.remain 771cb0ef41Sopenharmony_ci if (argv[1] !== 'config') { 781cb0ef41Sopenharmony_ci argv.unshift('config') 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci if (argv.length === 2) { 821cb0ef41Sopenharmony_ci const cmds = ['get', 'set', 'delete', 'ls', 'rm', 'edit', 'fix'] 831cb0ef41Sopenharmony_ci if (opts.partialWord !== 'l') { 841cb0ef41Sopenharmony_ci cmds.push('list') 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci return cmds 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci const action = argv[2] 911cb0ef41Sopenharmony_ci switch (action) { 921cb0ef41Sopenharmony_ci case 'set': 931cb0ef41Sopenharmony_ci // todo: complete with valid values, if possible. 941cb0ef41Sopenharmony_ci if (argv.length > 3) { 951cb0ef41Sopenharmony_ci return [] 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci // fallthrough 991cb0ef41Sopenharmony_ci /* eslint no-fallthrough:0 */ 1001cb0ef41Sopenharmony_ci case 'get': 1011cb0ef41Sopenharmony_ci case 'delete': 1021cb0ef41Sopenharmony_ci case 'rm': 1031cb0ef41Sopenharmony_ci return Object.keys(definitions) 1041cb0ef41Sopenharmony_ci case 'edit': 1051cb0ef41Sopenharmony_ci case 'list': 1061cb0ef41Sopenharmony_ci case 'ls': 1071cb0ef41Sopenharmony_ci case 'fix': 1081cb0ef41Sopenharmony_ci default: 1091cb0ef41Sopenharmony_ci return [] 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci } 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci async exec ([action, ...args]) { 1141cb0ef41Sopenharmony_ci log.disableProgress() 1151cb0ef41Sopenharmony_ci try { 1161cb0ef41Sopenharmony_ci switch (action) { 1171cb0ef41Sopenharmony_ci case 'set': 1181cb0ef41Sopenharmony_ci await this.set(args) 1191cb0ef41Sopenharmony_ci break 1201cb0ef41Sopenharmony_ci case 'get': 1211cb0ef41Sopenharmony_ci await this.get(args) 1221cb0ef41Sopenharmony_ci break 1231cb0ef41Sopenharmony_ci case 'delete': 1241cb0ef41Sopenharmony_ci case 'rm': 1251cb0ef41Sopenharmony_ci case 'del': 1261cb0ef41Sopenharmony_ci await this.del(args) 1271cb0ef41Sopenharmony_ci break 1281cb0ef41Sopenharmony_ci case 'list': 1291cb0ef41Sopenharmony_ci case 'ls': 1301cb0ef41Sopenharmony_ci await (this.npm.flatOptions.json ? this.listJson() : this.list()) 1311cb0ef41Sopenharmony_ci break 1321cb0ef41Sopenharmony_ci case 'edit': 1331cb0ef41Sopenharmony_ci await this.edit() 1341cb0ef41Sopenharmony_ci break 1351cb0ef41Sopenharmony_ci case 'fix': 1361cb0ef41Sopenharmony_ci await this.fix() 1371cb0ef41Sopenharmony_ci break 1381cb0ef41Sopenharmony_ci default: 1391cb0ef41Sopenharmony_ci throw this.usageError() 1401cb0ef41Sopenharmony_ci } 1411cb0ef41Sopenharmony_ci } finally { 1421cb0ef41Sopenharmony_ci log.enableProgress() 1431cb0ef41Sopenharmony_ci } 1441cb0ef41Sopenharmony_ci } 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci async set (args) { 1471cb0ef41Sopenharmony_ci if (!args.length) { 1481cb0ef41Sopenharmony_ci throw this.usageError() 1491cb0ef41Sopenharmony_ci } 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci const where = this.npm.flatOptions.location 1521cb0ef41Sopenharmony_ci for (const [key, val] of Object.entries(keyValues(args))) { 1531cb0ef41Sopenharmony_ci log.info('config', 'set %j %j', key, val) 1541cb0ef41Sopenharmony_ci const baseKey = key.split(':').pop() 1551cb0ef41Sopenharmony_ci if (!this.npm.config.definitions[baseKey] && !nerfDarts.includes(baseKey)) { 1561cb0ef41Sopenharmony_ci throw new Error(`\`${baseKey}\` is not a valid npm option`) 1571cb0ef41Sopenharmony_ci } 1581cb0ef41Sopenharmony_ci const deprecated = this.npm.config.definitions[baseKey]?.deprecated 1591cb0ef41Sopenharmony_ci if (deprecated) { 1601cb0ef41Sopenharmony_ci throw new Error( 1611cb0ef41Sopenharmony_ci `The \`${baseKey}\` option is deprecated, and can not be set in this way${deprecated}` 1621cb0ef41Sopenharmony_ci ) 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci if (val === '') { 1661cb0ef41Sopenharmony_ci this.npm.config.delete(key, where) 1671cb0ef41Sopenharmony_ci } else { 1681cb0ef41Sopenharmony_ci this.npm.config.set(key, val, where) 1691cb0ef41Sopenharmony_ci } 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci if (!this.npm.config.validate(where)) { 1721cb0ef41Sopenharmony_ci log.warn('config', 'omitting invalid config values') 1731cb0ef41Sopenharmony_ci } 1741cb0ef41Sopenharmony_ci } 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci await this.npm.config.save(where) 1771cb0ef41Sopenharmony_ci } 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci async get (keys) { 1801cb0ef41Sopenharmony_ci if (!keys.length) { 1811cb0ef41Sopenharmony_ci return this.list() 1821cb0ef41Sopenharmony_ci } 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci const out = [] 1851cb0ef41Sopenharmony_ci for (const key of keys) { 1861cb0ef41Sopenharmony_ci if (!publicVar(key)) { 1871cb0ef41Sopenharmony_ci throw new Error(`The ${key} option is protected, and can not be retrieved in this way`) 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci const pref = keys.length > 1 ? `${key}=` : '' 1911cb0ef41Sopenharmony_ci out.push(pref + this.npm.config.get(key)) 1921cb0ef41Sopenharmony_ci } 1931cb0ef41Sopenharmony_ci this.npm.output(out.join('\n')) 1941cb0ef41Sopenharmony_ci } 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ci async del (keys) { 1971cb0ef41Sopenharmony_ci if (!keys.length) { 1981cb0ef41Sopenharmony_ci throw this.usageError() 1991cb0ef41Sopenharmony_ci } 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci const where = this.npm.flatOptions.location 2021cb0ef41Sopenharmony_ci for (const key of keys) { 2031cb0ef41Sopenharmony_ci this.npm.config.delete(key, where) 2041cb0ef41Sopenharmony_ci } 2051cb0ef41Sopenharmony_ci await this.npm.config.save(where) 2061cb0ef41Sopenharmony_ci } 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci async edit () { 2091cb0ef41Sopenharmony_ci const e = this.npm.flatOptions.editor 2101cb0ef41Sopenharmony_ci const where = this.npm.flatOptions.location 2111cb0ef41Sopenharmony_ci const file = this.npm.config.data.get(where).source 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci // save first, just to make sure it's synced up 2141cb0ef41Sopenharmony_ci // this also removes all the comments from the last time we edited it. 2151cb0ef41Sopenharmony_ci await this.npm.config.save(where) 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci const data = ( 2181cb0ef41Sopenharmony_ci await readFile(file, 'utf8').catch(() => '') 2191cb0ef41Sopenharmony_ci ).replace(/\r\n/g, '\n') 2201cb0ef41Sopenharmony_ci const entries = Object.entries(defaults) 2211cb0ef41Sopenharmony_ci const defData = entries.reduce((str, [key, val]) => { 2221cb0ef41Sopenharmony_ci const obj = { [key]: val } 2231cb0ef41Sopenharmony_ci const i = ini.stringify(obj) 2241cb0ef41Sopenharmony_ci .replace(/\r\n/g, '\n') // normalizes output from ini.stringify 2251cb0ef41Sopenharmony_ci .replace(/\n$/m, '') 2261cb0ef41Sopenharmony_ci .replace(/^/g, '; ') 2271cb0ef41Sopenharmony_ci .replace(/\n/g, '\n; ') 2281cb0ef41Sopenharmony_ci .split('\n') 2291cb0ef41Sopenharmony_ci return str + '\n' + i 2301cb0ef41Sopenharmony_ci }, '') 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_ci const tmpData = `;;;; 2331cb0ef41Sopenharmony_ci; npm ${where}config file: ${file} 2341cb0ef41Sopenharmony_ci; this is a simple ini-formatted file 2351cb0ef41Sopenharmony_ci; lines that start with semi-colons are comments 2361cb0ef41Sopenharmony_ci; run \`npm help 7 config\` for documentation of the various options 2371cb0ef41Sopenharmony_ci; 2381cb0ef41Sopenharmony_ci; Configs like \`@scope:registry\` map a scope to a given registry url. 2391cb0ef41Sopenharmony_ci; 2401cb0ef41Sopenharmony_ci; Configs like \`//<hostname>/:_authToken\` are auth that is restricted 2411cb0ef41Sopenharmony_ci; to the registry host specified. 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci${data.split('\n').sort(localeCompare).join('\n').trim()} 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci;;;; 2461cb0ef41Sopenharmony_ci; all available options shown below with default values 2471cb0ef41Sopenharmony_ci;;;; 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_ci${defData} 2501cb0ef41Sopenharmony_ci`.split('\n').join(EOL) 2511cb0ef41Sopenharmony_ci await mkdir(dirname(file), { recursive: true }) 2521cb0ef41Sopenharmony_ci await writeFile(file, tmpData, 'utf8') 2531cb0ef41Sopenharmony_ci await new Promise((res, rej) => { 2541cb0ef41Sopenharmony_ci const [bin, ...args] = e.split(/\s+/) 2551cb0ef41Sopenharmony_ci const editor = spawn(bin, [...args, file], { stdio: 'inherit' }) 2561cb0ef41Sopenharmony_ci editor.on('exit', (code) => { 2571cb0ef41Sopenharmony_ci if (code) { 2581cb0ef41Sopenharmony_ci return rej(new Error(`editor process exited with code: ${code}`)) 2591cb0ef41Sopenharmony_ci } 2601cb0ef41Sopenharmony_ci return res() 2611cb0ef41Sopenharmony_ci }) 2621cb0ef41Sopenharmony_ci }) 2631cb0ef41Sopenharmony_ci } 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ci async fix () { 2661cb0ef41Sopenharmony_ci let problems 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci try { 2691cb0ef41Sopenharmony_ci this.npm.config.validate() 2701cb0ef41Sopenharmony_ci return // if validate doesn't throw we have nothing to do 2711cb0ef41Sopenharmony_ci } catch (err) { 2721cb0ef41Sopenharmony_ci // coverage skipped because we don't need to test rethrowing errors 2731cb0ef41Sopenharmony_ci // istanbul ignore next 2741cb0ef41Sopenharmony_ci if (err.code !== 'ERR_INVALID_AUTH') { 2751cb0ef41Sopenharmony_ci throw err 2761cb0ef41Sopenharmony_ci } 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ci problems = err.problems 2791cb0ef41Sopenharmony_ci } 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci if (!this.npm.config.isDefault('location')) { 2821cb0ef41Sopenharmony_ci problems = problems.filter((problem) => { 2831cb0ef41Sopenharmony_ci return problem.where === this.npm.config.get('location') 2841cb0ef41Sopenharmony_ci }) 2851cb0ef41Sopenharmony_ci } 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci this.npm.config.repair(problems) 2881cb0ef41Sopenharmony_ci const locations = [] 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci this.npm.output('The following configuration problems have been repaired:\n') 2911cb0ef41Sopenharmony_ci const summary = problems.map(({ action, from, to, key, where }) => { 2921cb0ef41Sopenharmony_ci // coverage disabled for else branch because it is intentionally omitted 2931cb0ef41Sopenharmony_ci // istanbul ignore else 2941cb0ef41Sopenharmony_ci if (action === 'rename') { 2951cb0ef41Sopenharmony_ci // we keep track of which configs were modified here so we know what to save later 2961cb0ef41Sopenharmony_ci locations.push(where) 2971cb0ef41Sopenharmony_ci return `~ \`${from}\` renamed to \`${to}\` in ${where} config` 2981cb0ef41Sopenharmony_ci } else if (action === 'delete') { 2991cb0ef41Sopenharmony_ci locations.push(where) 3001cb0ef41Sopenharmony_ci return `- \`${key}\` deleted from ${where} config` 3011cb0ef41Sopenharmony_ci } 3021cb0ef41Sopenharmony_ci }).join('\n') 3031cb0ef41Sopenharmony_ci this.npm.output(summary) 3041cb0ef41Sopenharmony_ci 3051cb0ef41Sopenharmony_ci return await Promise.all(locations.map((location) => this.npm.config.save(location))) 3061cb0ef41Sopenharmony_ci } 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci async list () { 3091cb0ef41Sopenharmony_ci const msg = [] 3101cb0ef41Sopenharmony_ci // long does not have a flattener 3111cb0ef41Sopenharmony_ci const long = this.npm.config.get('long') 3121cb0ef41Sopenharmony_ci for (const [where, { data, source }] of this.npm.config.data.entries()) { 3131cb0ef41Sopenharmony_ci if (where === 'default' && !long) { 3141cb0ef41Sopenharmony_ci continue 3151cb0ef41Sopenharmony_ci } 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci const keys = Object.keys(data).sort(localeCompare) 3181cb0ef41Sopenharmony_ci if (!keys.length) { 3191cb0ef41Sopenharmony_ci continue 3201cb0ef41Sopenharmony_ci } 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ci msg.push(`; "${where}" config from ${source}`, '') 3231cb0ef41Sopenharmony_ci for (const k of keys) { 3241cb0ef41Sopenharmony_ci const v = publicVar(k) ? JSON.stringify(data[k]) : '(protected)' 3251cb0ef41Sopenharmony_ci const src = this.npm.config.find(k) 3261cb0ef41Sopenharmony_ci const overridden = src !== where 3271cb0ef41Sopenharmony_ci msg.push((overridden ? '; ' : '') + 3281cb0ef41Sopenharmony_ci `${k} = ${v} ${overridden ? `; overridden by ${src}` : ''}`) 3291cb0ef41Sopenharmony_ci } 3301cb0ef41Sopenharmony_ci msg.push('') 3311cb0ef41Sopenharmony_ci } 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_ci if (!long) { 3341cb0ef41Sopenharmony_ci msg.push( 3351cb0ef41Sopenharmony_ci `; node bin location = ${process.execPath}`, 3361cb0ef41Sopenharmony_ci `; node version = ${process.version}`, 3371cb0ef41Sopenharmony_ci `; npm local prefix = ${this.npm.localPrefix}`, 3381cb0ef41Sopenharmony_ci `; npm version = ${this.npm.version}`, 3391cb0ef41Sopenharmony_ci `; cwd = ${process.cwd()}`, 3401cb0ef41Sopenharmony_ci `; HOME = ${process.env.HOME}`, 3411cb0ef41Sopenharmony_ci '; Run `npm config ls -l` to show all defaults.' 3421cb0ef41Sopenharmony_ci ) 3431cb0ef41Sopenharmony_ci msg.push('') 3441cb0ef41Sopenharmony_ci } 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_ci if (!this.npm.global) { 3471cb0ef41Sopenharmony_ci const { content } = await pkgJson.normalize(this.npm.prefix).catch(() => ({ content: {} })) 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ci if (content.publishConfig) { 3501cb0ef41Sopenharmony_ci const pkgPath = resolve(this.npm.prefix, 'package.json') 3511cb0ef41Sopenharmony_ci msg.push(`; "publishConfig" from ${pkgPath}`) 3521cb0ef41Sopenharmony_ci msg.push('; This set of config values will be used at publish-time.', '') 3531cb0ef41Sopenharmony_ci const pkgKeys = Object.keys(content.publishConfig).sort(localeCompare) 3541cb0ef41Sopenharmony_ci for (const k of pkgKeys) { 3551cb0ef41Sopenharmony_ci const v = publicVar(k) ? JSON.stringify(content.publishConfig[k]) : '(protected)' 3561cb0ef41Sopenharmony_ci msg.push(`${k} = ${v}`) 3571cb0ef41Sopenharmony_ci } 3581cb0ef41Sopenharmony_ci msg.push('') 3591cb0ef41Sopenharmony_ci } 3601cb0ef41Sopenharmony_ci } 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci this.npm.output(msg.join('\n').trim()) 3631cb0ef41Sopenharmony_ci } 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ci async listJson () { 3661cb0ef41Sopenharmony_ci const publicConf = {} 3671cb0ef41Sopenharmony_ci for (const key in this.npm.config.list[0]) { 3681cb0ef41Sopenharmony_ci if (!publicVar(key)) { 3691cb0ef41Sopenharmony_ci continue 3701cb0ef41Sopenharmony_ci } 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci publicConf[key] = this.npm.config.get(key) 3731cb0ef41Sopenharmony_ci } 3741cb0ef41Sopenharmony_ci this.npm.output(JSON.stringify(publicConf, null, 2)) 3751cb0ef41Sopenharmony_ci } 3761cb0ef41Sopenharmony_ci} 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_cimodule.exports = Config 379