1const definitions = {}
2module.exports = definitions
3
4const Definition = require('./definition.js')
5
6const ciInfo = require('ci-info')
7const querystring = require('querystring')
8const { join } = require('path')
9
10const isWindows = process.platform === 'win32'
11
12// used by cafile flattening to flatOptions.ca
13const fs = require('fs')
14const maybeReadFile = file => {
15  try {
16    return fs.readFileSync(file, 'utf8')
17  } catch (er) {
18    if (er.code !== 'ENOENT') {
19      throw er
20    }
21    return null
22  }
23}
24
25const buildOmitList = obj => {
26  const include = obj.include || []
27  const omit = obj.omit || []
28
29  const only = obj.only
30  if (/^prod(uction)?$/.test(only) || obj.production) {
31    omit.push('dev')
32  } else if (obj.production === false) {
33    include.push('dev')
34  }
35
36  if (/^dev/.test(obj.also)) {
37    include.push('dev')
38  }
39
40  if (obj.dev) {
41    include.push('dev')
42  }
43
44  if (obj.optional === false) {
45    omit.push('optional')
46  } else if (obj.optional === true) {
47    include.push('optional')
48  }
49
50  obj.omit = [...new Set(omit)].filter(type => !include.includes(type))
51  obj.include = [...new Set(include)]
52
53  if (obj.omit.includes('dev')) {
54    process.env.NODE_ENV = 'production'
55  }
56
57  return obj.omit
58}
59
60const editor = process.env.EDITOR ||
61  process.env.VISUAL ||
62  (isWindows ? `${process.env.SYSTEMROOT}\\notepad.exe` : 'vi')
63
64const shell = isWindows ? process.env.ComSpec || 'cmd'
65  : process.env.SHELL || 'sh'
66
67const { networkInterfaces } = require('os')
68const getLocalAddresses = () => {
69  try {
70    return Object.values(networkInterfaces()).map(
71      int => int.map(({ address }) => address)
72    ).reduce((set, addrs) => set.concat(addrs), [null])
73  } catch (e) {
74    return [null]
75  }
76}
77
78const unicode = /UTF-?8$/i.test(
79  process.env.LC_ALL ||
80  process.env.LC_CTYPE ||
81  process.env.LANG
82)
83
84// use LOCALAPPDATA on Windows, if set
85// https://github.com/npm/cli/pull/899
86const cacheRoot = (isWindows && process.env.LOCALAPPDATA) || '~'
87const cacheExtra = isWindows ? 'npm-cache' : '.npm'
88const cache = `${cacheRoot}/${cacheExtra}`
89
90// TODO: refactor these type definitions so that they are less
91// weird to pull out of the config module.
92// TODO: use better type definition/validation API, nopt's is so weird.
93const {
94  semver: { type: semver },
95  Umask: { type: Umask },
96  url: { type: url },
97  path: { type: path },
98} = require('../type-defs.js')
99
100const define = (key, def) => {
101  /* istanbul ignore if - this should never happen, prevents mistakes below */
102  if (definitions[key]) {
103    throw new Error(`defining key more than once: ${key}`)
104  }
105  definitions[key] = new Definition(key, def)
106}
107
108// basic flattening function, just copy it over camelCase
109const flatten = (key, obj, flatOptions) => {
110  const camel = key.replace(/-([a-z])/g, (_0, _1) => _1.toUpperCase())
111  flatOptions[camel] = obj[key]
112}
113
114// TODO:
115// Instead of having each definition provide a flatten method,
116// provide the (?list of?) flat option field(s?) that it impacts.
117// When that config is set, we mark the relevant flatOption fields
118// dirty.  Then, a getter for that field defines how we actually
119// set it.
120//
121// So, `save-dev`, `save-optional`, `save-prod`, et al would indicate
122// that they affect the `saveType` flat option.  Then the config.flat
123// object has a `get saveType () { ... }` that looks at the "real"
124// config settings from files etc and returns the appropriate value.
125//
126// Getters will also (maybe?) give us a hook to audit flat option
127// usage, so we can document and group these more appropriately.
128//
129// This will be a problem with cases where we currently do:
130// const opts = { ...npm.flatOptions, foo: 'bar' }, but we can maybe
131// instead do `npm.config.set('foo', 'bar')` prior to passing the
132// config object down where it needs to go.
133//
134// This way, when we go hunting for "where does saveType come from anyway!?"
135// while fixing some Arborist bug, we won't have to hunt through too
136// many places.
137
138// Define all config keys we know about
139
140define('_auth', {
141  default: null,
142  type: [null, String],
143  description: `
144    A basic-auth string to use when authenticating against the npm registry.
145    This will ONLY be used to authenticate against the npm registry.  For other
146    registries you will need to scope it like "//other-registry.tld/:_auth"
147
148    Warning: This should generally not be set via a command-line option.  It
149    is safer to use a registry-provided authentication bearer token stored in
150    the ~/.npmrc file by running \`npm login\`.
151  `,
152  flatten,
153})
154
155define('access', {
156  default: null,
157  defaultDescription: `
158    'public' for new packages, existing packages it will not change the current level
159  `,
160  type: [null, 'restricted', 'public'],
161  description: `
162    If you do not want your scoped package to be publicly viewable (and
163    installable) set \`--access=restricted\`.
164
165    Unscoped packages can not be set to \`restricted\`.
166
167    Note: This defaults to not changing the current access level for existing
168    packages.  Specifying a value of \`restricted\` or \`public\` during
169    publish will change the access for an existing package the same way that
170    \`npm access set status\` would.
171  `,
172  flatten,
173})
174
175define('all', {
176  default: false,
177  type: Boolean,
178  short: 'a',
179  description: `
180    When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show
181    all outdated or installed packages, rather than only those directly
182    depended upon by the current project.
183  `,
184  flatten,
185})
186
187define('allow-same-version', {
188  default: false,
189  type: Boolean,
190  description: `
191    Prevents throwing an error when \`npm version\` is used to set the new
192    version to the same value as the current version.
193  `,
194  flatten,
195})
196
197define('also', {
198  default: null,
199  type: [null, 'dev', 'development'],
200  description: `
201    When set to \`dev\` or \`development\`, this is an alias for
202    \`--include=dev\`.
203  `,
204  deprecated: 'Please use --include=dev instead.',
205  flatten (key, obj, flatOptions) {
206    definitions.omit.flatten('omit', obj, flatOptions)
207  },
208})
209
210define('audit', {
211  default: true,
212  type: Boolean,
213  description: `
214    When "true" submit audit reports alongside the current npm command to the
215    default registry and all registries configured for scopes.  See the
216    documentation for [\`npm audit\`](/commands/npm-audit) for details on what
217    is submitted.
218  `,
219  flatten,
220})
221
222define('audit-level', {
223  default: null,
224  type: [null, 'info', 'low', 'moderate', 'high', 'critical', 'none'],
225  description: `
226    The minimum level of vulnerability for \`npm audit\` to exit with
227    a non-zero exit code.
228  `,
229  flatten,
230})
231
232define('auth-type', {
233  default: 'web',
234  type: ['legacy', 'web'],
235  description: `
236    What authentication strategy to use with \`login\`.
237    Note that if an \`otp\` config is given, this value will always be set to \`legacy\`.
238  `,
239  flatten,
240})
241
242define('before', {
243  default: null,
244  type: [null, Date],
245  description: `
246    If passed to \`npm install\`, will rebuild the npm tree such that only
247    versions that were available **on or before** the \`--before\` time get
248    installed.  If there's no versions available for the current set of
249    direct dependencies, the command will error.
250
251    If the requested version is a \`dist-tag\` and the given tag does not
252    pass the \`--before\` filter, the most recent version less than or equal
253    to that tag will be used. For example, \`foo@latest\` might install
254    \`foo@1.2\` even though \`latest\` is \`2.0\`.
255  `,
256  flatten,
257})
258
259define('bin-links', {
260  default: true,
261  type: Boolean,
262  description: `
263    Tells npm to create symlinks (or \`.cmd\` shims on Windows) for package
264    executables.
265
266    Set to false to have it not do this.  This can be used to work around the
267    fact that some file systems don't support symlinks, even on ostensibly
268    Unix systems.
269  `,
270  flatten,
271})
272
273define('browser', {
274  default: null,
275  defaultDescription: `
276    OS X: \`"open"\`, Windows: \`"start"\`, Others: \`"xdg-open"\`
277  `,
278  type: [null, Boolean, String],
279  description: `
280    The browser that is called by npm commands to open websites.
281
282    Set to \`false\` to suppress browser behavior and instead print urls to
283    terminal.
284
285    Set to \`true\` to use default system URL opener.
286  `,
287  flatten,
288})
289
290define('ca', {
291  default: null,
292  type: [null, String, Array],
293  description: `
294    The Certificate Authority signing certificate that is trusted for SSL
295    connections to the registry. Values should be in PEM format (Windows
296    calls it "Base-64 encoded X.509 (.CER)") with newlines replaced by the
297    string "\\n". For example:
298
299    \`\`\`ini
300    ca="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----"
301    \`\`\`
302
303    Set to \`null\` to only allow "known" registrars, or to a specific CA
304    cert to trust only that specific signing authority.
305
306    Multiple CAs can be trusted by specifying an array of certificates:
307
308    \`\`\`ini
309    ca[]="..."
310    ca[]="..."
311    \`\`\`
312
313    See also the \`strict-ssl\` config.
314  `,
315  flatten,
316})
317
318define('cache', {
319  default: cache,
320  defaultDescription: `
321    Windows: \`%LocalAppData%\\npm-cache\`, Posix: \`~/.npm\`
322  `,
323  type: path,
324  description: `
325    The location of npm's cache directory.
326  `,
327  flatten (key, obj, flatOptions) {
328    flatOptions.cache = join(obj.cache, '_cacache')
329    flatOptions.npxCache = join(obj.cache, '_npx')
330    flatOptions.tufCache = join(obj.cache, '_tuf')
331  },
332})
333
334define('cache-max', {
335  default: Infinity,
336  type: Number,
337  description: `
338    \`--cache-max=0\` is an alias for \`--prefer-online\`
339  `,
340  deprecated: `
341    This option has been deprecated in favor of \`--prefer-online\`
342  `,
343  flatten (key, obj, flatOptions) {
344    if (obj[key] <= 0) {
345      flatOptions.preferOnline = true
346    }
347  },
348})
349
350define('cache-min', {
351  default: 0,
352  type: Number,
353  description: `
354    \`--cache-min=9999 (or bigger)\` is an alias for \`--prefer-offline\`.
355  `,
356  deprecated: `
357    This option has been deprecated in favor of \`--prefer-offline\`.
358  `,
359  flatten (key, obj, flatOptions) {
360    if (obj[key] >= 9999) {
361      flatOptions.preferOffline = true
362    }
363  },
364})
365
366define('cafile', {
367  default: null,
368  type: path,
369  description: `
370    A path to a file containing one or multiple Certificate Authority signing
371    certificates. Similar to the \`ca\` setting, but allows for multiple
372    CA's, as well as for the CA information to be stored in a file on disk.
373  `,
374  flatten (key, obj, flatOptions) {
375    // always set to null in defaults
376    if (!obj.cafile) {
377      return
378    }
379
380    const raw = maybeReadFile(obj.cafile)
381    if (!raw) {
382      return
383    }
384
385    const delim = '-----END CERTIFICATE-----'
386    flatOptions.ca = raw.replace(/\r\n/g, '\n').split(delim)
387      .filter(section => section.trim())
388      .map(section => section.trimLeft() + delim)
389  },
390})
391
392define('call', {
393  default: '',
394  type: String,
395  short: 'c',
396  description: `
397    Optional companion option for \`npm exec\`, \`npx\` that allows for
398    specifying a custom command to be run along with the installed packages.
399
400    \`\`\`bash
401    npm exec --package yo --package generator-node --call "yo node"
402    \`\`\`
403  `,
404  flatten,
405})
406
407define('cert', {
408  default: null,
409  type: [null, String],
410  description: `
411    A client certificate to pass when accessing the registry.  Values should
412    be in PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with
413    newlines replaced by the string "\\n". For example:
414
415    \`\`\`ini
416    cert="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----"
417    \`\`\`
418
419    It is _not_ the path to a certificate file, though you can set a registry-scoped
420    "certfile" path like "//other-registry.tld/:certfile=/path/to/cert.pem".
421  `,
422  deprecated: `
423    \`key\` and \`cert\` are no longer used for most registry operations.
424    Use registry scoped \`keyfile\` and \`certfile\` instead.
425    Example:
426    //other-registry.tld/:keyfile=/path/to/key.pem
427    //other-registry.tld/:certfile=/path/to/cert.crt
428  `,
429  flatten,
430})
431
432define('cidr', {
433  default: null,
434  type: [null, String, Array],
435  description: `
436    This is a list of CIDR address to be used when configuring limited access
437    tokens with the \`npm token create\` command.
438  `,
439  flatten,
440})
441
442// This should never be directly used, the flattened value is the derived value
443// and is sent to other modules, and is also exposed as `npm.color` for use
444// inside npm itself.
445define('color', {
446  default: !process.env.NO_COLOR || process.env.NO_COLOR === '0',
447  usage: '--color|--no-color|--color always',
448  defaultDescription: `
449    true unless the NO_COLOR environ is set to something other than '0'
450  `,
451  type: ['always', Boolean],
452  description: `
453    If false, never shows colors.  If \`"always"\` then always shows colors.
454    If true, then only prints color codes for tty file descriptors.
455  `,
456  flatten (key, obj, flatOptions) {
457    flatOptions.color = !obj.color ? false
458      : obj.color === 'always' ? true
459      : !!process.stdout.isTTY
460    flatOptions.logColor = !obj.color ? false
461      : obj.color === 'always' ? true
462      : !!process.stderr.isTTY
463  },
464})
465
466define('commit-hooks', {
467  default: true,
468  type: Boolean,
469  description: `
470    Run git commit hooks when using the \`npm version\` command.
471  `,
472  flatten,
473})
474
475define('cpu', {
476  default: null,
477  type: [null, String],
478  description: `
479    Override CPU architecture of native modules to install.
480    Acceptable values are same as \`cpu\` field of package.json,
481    which comes from \`process.arch\`.
482  `,
483  flatten,
484})
485
486define('os', {
487  default: null,
488  type: [null, String],
489  description: `
490    Override OS of native modules to install.
491    Acceptable values are same as \`os\` field of package.json,
492    which comes from \`process.platform\`.
493  `,
494  flatten,
495})
496
497define('libc', {
498  default: null,
499  type: [null, String],
500  description: `
501    Override libc of native modules to install.
502    Acceptable values are same as \`libc\` field of package.json
503  `,
504  flatten,
505})
506
507define('depth', {
508  default: null,
509  defaultDescription: `
510    \`Infinity\` if \`--all\` is set, otherwise \`1\`
511  `,
512  type: [null, Number],
513  description: `
514    The depth to go when recursing packages for \`npm ls\`.
515
516    If not set, \`npm ls\` will show only the immediate dependencies of the
517    root project.  If \`--all\` is set, then npm will show all dependencies
518    by default.
519  `,
520  flatten,
521})
522
523define('description', {
524  default: true,
525  type: Boolean,
526  usage: '--no-description',
527  description: `
528    Show the description in \`npm search\`
529  `,
530  flatten (key, obj, flatOptions) {
531    flatOptions.search = flatOptions.search || { limit: 20 }
532    flatOptions.search[key] = obj[key]
533  },
534})
535
536define('dev', {
537  default: false,
538  type: Boolean,
539  description: `
540    Alias for \`--include=dev\`.
541  `,
542  deprecated: 'Please use --include=dev instead.',
543  flatten (key, obj, flatOptions) {
544    definitions.omit.flatten('omit', obj, flatOptions)
545  },
546})
547
548define('diff', {
549  default: [],
550  hint: '<package-spec>',
551  type: [String, Array],
552  description: `
553    Define arguments to compare in \`npm diff\`.
554  `,
555  flatten,
556})
557
558define('diff-ignore-all-space', {
559  default: false,
560  type: Boolean,
561  description: `
562    Ignore whitespace when comparing lines in \`npm diff\`.
563  `,
564  flatten,
565})
566
567define('diff-name-only', {
568  default: false,
569  type: Boolean,
570  description: `
571    Prints only filenames when using \`npm diff\`.
572  `,
573  flatten,
574})
575
576define('diff-no-prefix', {
577  default: false,
578  type: Boolean,
579  description: `
580    Do not show any source or destination prefix in \`npm diff\` output.
581
582    Note: this causes \`npm diff\` to ignore the \`--diff-src-prefix\` and
583    \`--diff-dst-prefix\` configs.
584  `,
585  flatten,
586})
587
588define('diff-dst-prefix', {
589  default: 'b/',
590  hint: '<path>',
591  type: String,
592  description: `
593    Destination prefix to be used in \`npm diff\` output.
594  `,
595  flatten,
596})
597
598define('diff-src-prefix', {
599  default: 'a/',
600  hint: '<path>',
601  type: String,
602  description: `
603    Source prefix to be used in \`npm diff\` output.
604  `,
605  flatten,
606})
607
608define('diff-text', {
609  default: false,
610  type: Boolean,
611  description: `
612    Treat all files as text in \`npm diff\`.
613  `,
614  flatten,
615})
616
617define('diff-unified', {
618  default: 3,
619  type: Number,
620  description: `
621    The number of lines of context to print in \`npm diff\`.
622  `,
623  flatten,
624})
625
626define('dry-run', {
627  default: false,
628  type: Boolean,
629  description: `
630    Indicates that you don't want npm to make any changes and that it should
631    only report what it would have done.  This can be passed into any of the
632    commands that modify your local installation, eg, \`install\`,
633    \`update\`, \`dedupe\`, \`uninstall\`, as well as \`pack\` and
634    \`publish\`.
635
636    Note: This is NOT honored by other network related commands, eg
637    \`dist-tags\`, \`owner\`, etc.
638  `,
639  flatten,
640})
641
642define('editor', {
643  default: editor,
644  defaultDescription: `
645    The EDITOR or VISUAL environment variables, or '%SYSTEMROOT%\\notepad.exe' on Windows,
646    or 'vi' on Unix systems
647  `,
648  type: String,
649  description: `
650    The command to run for \`npm edit\` and \`npm config edit\`.
651  `,
652  flatten,
653})
654
655define('engine-strict', {
656  default: false,
657  type: Boolean,
658  description: `
659    If set to true, then npm will stubbornly refuse to install (or even
660    consider installing) any package that claims to not be compatible with
661    the current Node.js version.
662
663    This can be overridden by setting the \`--force\` flag.
664  `,
665  flatten,
666})
667
668define('expect-results', {
669  default: null,
670  type: [null, Boolean],
671  exclusive: ['expect-result-count'],
672  description: `
673    Tells npm whether or not to expect results from the command.
674    Can be either true (expect some results) or false (expect no results).
675  `,
676})
677
678define('expect-result-count', {
679  default: null,
680  type: [null, Number],
681  hint: '<count>',
682  exclusive: ['expect-results'],
683  description: `
684    Tells to expect a specific number of results from the command.
685  `,
686})
687
688define('fetch-retries', {
689  default: 2,
690  type: Number,
691  description: `
692    The "retries" config for the \`retry\` module to use when fetching
693    packages from the registry.
694
695    npm will retry idempotent read requests to the registry in the case
696    of network failures or 5xx HTTP errors.
697  `,
698  flatten (key, obj, flatOptions) {
699    flatOptions.retry = flatOptions.retry || {}
700    flatOptions.retry.retries = obj[key]
701  },
702})
703
704define('fetch-retry-factor', {
705  default: 10,
706  type: Number,
707  description: `
708    The "factor" config for the \`retry\` module to use when fetching
709    packages.
710  `,
711  flatten (key, obj, flatOptions) {
712    flatOptions.retry = flatOptions.retry || {}
713    flatOptions.retry.factor = obj[key]
714  },
715})
716
717define('fetch-retry-maxtimeout', {
718  default: 60000,
719  defaultDescription: '60000 (1 minute)',
720  type: Number,
721  description: `
722    The "maxTimeout" config for the \`retry\` module to use when fetching
723    packages.
724  `,
725  flatten (key, obj, flatOptions) {
726    flatOptions.retry = flatOptions.retry || {}
727    flatOptions.retry.maxTimeout = obj[key]
728  },
729})
730
731define('fetch-retry-mintimeout', {
732  default: 10000,
733  defaultDescription: '10000 (10 seconds)',
734  type: Number,
735  description: `
736    The "minTimeout" config for the \`retry\` module to use when fetching
737    packages.
738  `,
739  flatten (key, obj, flatOptions) {
740    flatOptions.retry = flatOptions.retry || {}
741    flatOptions.retry.minTimeout = obj[key]
742  },
743})
744
745define('fetch-timeout', {
746  default: 5 * 60 * 1000,
747  defaultDescription: `${5 * 60 * 1000} (5 minutes)`,
748  type: Number,
749  description: `
750    The maximum amount of time to wait for HTTP requests to complete.
751  `,
752  flatten (key, obj, flatOptions) {
753    flatOptions.timeout = obj[key]
754  },
755})
756
757define('force', {
758  default: false,
759  type: Boolean,
760  short: 'f',
761  description: `
762    Removes various protections against unfortunate side effects, common
763    mistakes, unnecessary performance degradation, and malicious input.
764
765    * Allow clobbering non-npm files in global installs.
766    * Allow the \`npm version\` command to work on an unclean git repository.
767    * Allow deleting the cache folder with \`npm cache clean\`.
768    * Allow installing packages that have an \`engines\` declaration
769      requiring a different version of npm.
770    * Allow installing packages that have an \`engines\` declaration
771      requiring a different version of \`node\`, even if \`--engine-strict\`
772      is enabled.
773    * Allow \`npm audit fix\` to install modules outside your stated
774      dependency range (including SemVer-major changes).
775    * Allow unpublishing all versions of a published package.
776    * Allow conflicting peerDependencies to be installed in the root project.
777    * Implicitly set \`--yes\` during \`npm init\`.
778    * Allow clobbering existing values in \`npm pkg\`
779    * Allow unpublishing of entire packages (not just a single version).
780
781    If you don't have a clear idea of what you want to do, it is strongly
782    recommended that you do not use this option!
783  `,
784  flatten,
785})
786
787define('foreground-scripts', {
788  default: false,
789  defaultDescription: `\`false\` unless when using \`npm pack\` or \`npm publish\` where it
790  defaults to \`true\``,
791  type: Boolean,
792  description: `
793    Run all build scripts (ie, \`preinstall\`, \`install\`, and
794    \`postinstall\`) scripts for installed packages in the foreground
795    process, sharing standard input, output, and error with the main npm
796    process.
797
798    Note that this will generally make installs run slower, and be much
799    noisier, but can be useful for debugging.
800  `,
801  flatten,
802})
803
804define('format-package-lock', {
805  default: true,
806  type: Boolean,
807  description: `
808    Format \`package-lock.json\` or \`npm-shrinkwrap.json\` as a human
809    readable file.
810  `,
811  flatten,
812})
813
814define('fund', {
815  default: true,
816  type: Boolean,
817  description: `
818    When "true" displays the message at the end of each \`npm install\`
819    acknowledging the number of dependencies looking for funding.
820    See [\`npm fund\`](/commands/npm-fund) for details.
821  `,
822  flatten,
823})
824
825define('git', {
826  default: 'git',
827  type: String,
828  description: `
829    The command to use for git commands.  If git is installed on the
830    computer, but is not in the \`PATH\`, then set this to the full path to
831    the git binary.
832  `,
833  flatten,
834})
835
836define('git-tag-version', {
837  default: true,
838  type: Boolean,
839  description: `
840    Tag the commit when using the \`npm version\` command.  Setting this to
841    false results in no commit being made at all.
842  `,
843  flatten,
844})
845
846define('global', {
847  default: false,
848  type: Boolean,
849  short: 'g',
850  description: `
851    Operates in "global" mode, so that packages are installed into the
852    \`prefix\` folder instead of the current working directory.  See
853    [folders](/configuring-npm/folders) for more on the differences in
854    behavior.
855
856    * packages are installed into the \`{prefix}/lib/node_modules\` folder,
857      instead of the current working directory.
858    * bin files are linked to \`{prefix}/bin\`
859    * man pages are linked to \`{prefix}/share/man\`
860  `,
861  flatten: (key, obj, flatOptions) => {
862    flatten(key, obj, flatOptions)
863    if (flatOptions.global) {
864      flatOptions.location = 'global'
865    }
866  },
867})
868
869// the globalconfig has its default defined outside of this module
870define('globalconfig', {
871  type: path,
872  default: '',
873  defaultDescription: `
874    The global --prefix setting plus 'etc/npmrc'. For example,
875    '/usr/local/etc/npmrc'
876  `,
877  description: `
878    The config file to read for global config options.
879  `,
880  flatten,
881})
882
883define('global-style', {
884  default: false,
885  type: Boolean,
886  description: `
887    Only install direct dependencies in the top level \`node_modules\`,
888    but hoist on deeper dependencies.
889    Sets \`--install-strategy=shallow\`.
890  `,
891  deprecated: `
892    This option has been deprecated in favor of \`--install-strategy=shallow\`
893  `,
894  flatten (key, obj, flatOptions) {
895    if (obj[key]) {
896      obj['install-strategy'] = 'shallow'
897      flatOptions.installStrategy = 'shallow'
898    }
899  },
900})
901
902define('heading', {
903  default: 'npm',
904  type: String,
905  description: `
906    The string that starts all the debugging log output.
907  `,
908  flatten,
909})
910
911define('https-proxy', {
912  default: null,
913  type: [null, url],
914  description: `
915    A proxy to use for outgoing https requests. If the \`HTTPS_PROXY\` or
916    \`https_proxy\` or \`HTTP_PROXY\` or \`http_proxy\` environment variables
917    are set, proxy settings will be honored by the underlying
918    \`make-fetch-happen\` library.
919  `,
920  flatten,
921})
922
923define('if-present', {
924  default: false,
925  type: Boolean,
926  envExport: false,
927  description: `
928    If true, npm will not exit with an error code when \`run-script\` is
929    invoked for a script that isn't defined in the \`scripts\` section of
930    \`package.json\`. This option can be used when it's desirable to
931    optionally run a script when it's present and fail if the script fails.
932    This is useful, for example, when running scripts that may only apply for
933    some builds in an otherwise generic CI setup.
934  `,
935  flatten,
936})
937
938define('ignore-scripts', {
939  default: false,
940  type: Boolean,
941  description: `
942    If true, npm does not run scripts specified in package.json files.
943
944    Note that commands explicitly intended to run a particular script, such
945    as \`npm start\`, \`npm stop\`, \`npm restart\`, \`npm test\`, and \`npm
946    run-script\` will still run their intended script if \`ignore-scripts\` is
947    set, but they will *not* run any pre- or post-scripts.
948  `,
949  flatten,
950})
951
952define('include', {
953  default: [],
954  type: [Array, 'prod', 'dev', 'optional', 'peer'],
955  description: `
956    Option that allows for defining which types of dependencies to install.
957
958    This is the inverse of \`--omit=<type>\`.
959
960    Dependency types specified in \`--include\` will not be omitted,
961    regardless of the order in which omit/include are specified on the
962    command-line.
963  `,
964  flatten (key, obj, flatOptions) {
965    // just call the omit flattener, it reads from obj.include
966    definitions.omit.flatten('omit', obj, flatOptions)
967  },
968})
969
970define('include-staged', {
971  default: false,
972  type: Boolean,
973  description: `
974    Allow installing "staged" published packages, as defined by [npm RFC PR
975    #92](https://github.com/npm/rfcs/pull/92).
976
977    This is experimental, and not implemented by the npm public registry.
978  `,
979  flatten,
980})
981
982define('include-workspace-root', {
983  default: false,
984  type: Boolean,
985  envExport: false,
986  description: `
987    Include the workspace root when workspaces are enabled for a command.
988
989    When false, specifying individual workspaces via the \`workspace\` config,
990    or all workspaces via the \`workspaces\` flag, will cause npm to operate only
991    on the specified workspaces, and not on the root project.
992  `,
993  flatten,
994})
995
996define('init-author-email', {
997  default: '',
998  hint: '<email>',
999  type: String,
1000  description: `
1001    The value \`npm init\` should use by default for the package author's
1002    email.
1003  `,
1004})
1005
1006define('init-author-name', {
1007  default: '',
1008  hint: '<name>',
1009  type: String,
1010  description: `
1011    The value \`npm init\` should use by default for the package author's name.
1012  `,
1013})
1014
1015define('init-author-url', {
1016  default: '',
1017  type: ['', url],
1018  hint: '<url>',
1019  description: `
1020    The value \`npm init\` should use by default for the package author's homepage.
1021  `,
1022})
1023
1024define('init-license', {
1025  default: 'ISC',
1026  hint: '<license>',
1027  type: String,
1028  description: `
1029    The value \`npm init\` should use by default for the package license.
1030  `,
1031})
1032
1033define('init-module', {
1034  default: '~/.npm-init.js',
1035  type: path,
1036  hint: '<module>',
1037  description: `
1038    A module that will be loaded by the \`npm init\` command.  See the
1039    documentation for the
1040    [init-package-json](https://github.com/npm/init-package-json) module for
1041    more information, or [npm init](/commands/npm-init).
1042  `,
1043})
1044
1045define('init-version', {
1046  default: '1.0.0',
1047  type: semver,
1048  hint: '<version>',
1049  description: `
1050    The value that \`npm init\` should use by default for the package
1051    version number, if not already set in package.json.
1052  `,
1053})
1054
1055// these "aliases" are historically supported in .npmrc files, unfortunately
1056// They should be removed in a future npm version.
1057define('init.author.email', {
1058  default: '',
1059  type: String,
1060  deprecated: `
1061    Use \`--init-author-email\` instead.`,
1062  description: `
1063    Alias for \`--init-author-email\`
1064  `,
1065})
1066
1067define('init.author.name', {
1068  default: '',
1069  type: String,
1070  deprecated: `
1071    Use \`--init-author-name\` instead.
1072  `,
1073  description: `
1074    Alias for \`--init-author-name\`
1075  `,
1076})
1077
1078define('init.author.url', {
1079  default: '',
1080  type: ['', url],
1081  deprecated: `
1082    Use \`--init-author-url\` instead.
1083  `,
1084  description: `
1085    Alias for \`--init-author-url\`
1086  `,
1087})
1088
1089define('init.license', {
1090  default: 'ISC',
1091  type: String,
1092  deprecated: `
1093    Use \`--init-license\` instead.
1094  `,
1095  description: `
1096    Alias for \`--init-license\`
1097  `,
1098})
1099
1100define('init.module', {
1101  default: '~/.npm-init.js',
1102  type: path,
1103  deprecated: `
1104    Use \`--init-module\` instead.
1105  `,
1106  description: `
1107    Alias for \`--init-module\`
1108  `,
1109})
1110
1111define('init.version', {
1112  default: '1.0.0',
1113  type: semver,
1114  deprecated: `
1115    Use \`--init-version\` instead.
1116  `,
1117  description: `
1118    Alias for \`--init-version\`
1119  `,
1120})
1121
1122define('install-links', {
1123  default: false,
1124  type: Boolean,
1125  description: `
1126    When set file: protocol dependencies will be packed and installed as
1127    regular dependencies instead of creating a symlink. This option has
1128    no effect on workspaces.
1129  `,
1130  flatten,
1131})
1132
1133define('install-strategy', {
1134  default: 'hoisted',
1135  type: ['hoisted', 'nested', 'shallow', 'linked'],
1136  description: `
1137    Sets the strategy for installing packages in node_modules.
1138    hoisted (default): Install non-duplicated in top-level, and duplicated as
1139      necessary within directory structure.
1140    nested: (formerly --legacy-bundling) install in place, no hoisting.
1141    shallow (formerly --global-style) only install direct deps at top-level.
1142    linked: (experimental) install in node_modules/.store, link in place,
1143      unhoisted.
1144  `,
1145  flatten,
1146})
1147
1148define('json', {
1149  default: false,
1150  type: Boolean,
1151  description: `
1152    Whether or not to output JSON data, rather than the normal output.
1153
1154    * In \`npm pkg set\` it enables parsing set values with JSON.parse()
1155    before saving them to your \`package.json\`.
1156
1157    Not supported by all npm commands.
1158  `,
1159  flatten,
1160})
1161
1162define('key', {
1163  default: null,
1164  type: [null, String],
1165  description: `
1166    A client key to pass when accessing the registry.  Values should be in
1167    PEM format with newlines replaced by the string "\\n". For example:
1168
1169    \`\`\`ini
1170    key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----"
1171    \`\`\`
1172
1173    It is _not_ the path to a key file, though you can set a registry-scoped
1174    "keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem".
1175  `,
1176  deprecated: `
1177    \`key\` and \`cert\` are no longer used for most registry operations.
1178    Use registry scoped \`keyfile\` and \`certfile\` instead.
1179    Example:
1180    //other-registry.tld/:keyfile=/path/to/key.pem
1181    //other-registry.tld/:certfile=/path/to/cert.crt
1182  `,
1183  flatten,
1184})
1185
1186define('legacy-bundling', {
1187  default: false,
1188  type: Boolean,
1189  description: `
1190    Instead of hoisting package installs in \`node_modules\`, install packages
1191    in the same manner that they are depended on. This may cause very deep
1192    directory structures and duplicate package installs as there is no
1193    de-duplicating.
1194    Sets \`--install-strategy=nested\`.
1195  `,
1196  deprecated: `
1197    This option has been deprecated in favor of \`--install-strategy=nested\`
1198  `,
1199  flatten (key, obj, flatOptions) {
1200    if (obj[key]) {
1201      obj['install-strategy'] = 'nested'
1202      flatOptions.installStrategy = 'nested'
1203    }
1204  },
1205})
1206
1207define('legacy-peer-deps', {
1208  default: false,
1209  type: Boolean,
1210  description: `
1211    Causes npm to completely ignore \`peerDependencies\` when building a
1212    package tree, as in npm versions 3 through 6.
1213
1214    If a package cannot be installed because of overly strict
1215    \`peerDependencies\` that collide, it provides a way to move forward
1216    resolving the situation.
1217
1218    This differs from \`--omit=peer\`, in that \`--omit=peer\` will avoid
1219    unpacking \`peerDependencies\` on disk, but will still design a tree such
1220    that \`peerDependencies\` _could_ be unpacked in a correct place.
1221
1222    Use of \`legacy-peer-deps\` is not recommended, as it will not enforce
1223    the \`peerDependencies\` contract that meta-dependencies may rely on.
1224  `,
1225  flatten,
1226})
1227
1228define('link', {
1229  default: false,
1230  type: Boolean,
1231  description: `
1232    Used with \`npm ls\`, limiting output to only those packages that are
1233    linked.
1234  `,
1235})
1236
1237define('local-address', {
1238  default: null,
1239  type: getLocalAddresses(),
1240  typeDescription: 'IP Address',
1241  description: `
1242    The IP address of the local interface to use when making connections to
1243    the npm registry.  Must be IPv4 in versions of Node prior to 0.12.
1244  `,
1245  flatten,
1246})
1247
1248define('sbom-format', {
1249  default: null,
1250  type: [
1251    'cyclonedx',
1252    'spdx',
1253  ],
1254  description: `
1255    SBOM format to use when generating SBOMs.
1256  `,
1257  flatten,
1258})
1259
1260define('sbom-type', {
1261  default: 'library',
1262  type: [
1263    'library',
1264    'application',
1265    'framework',
1266  ],
1267  description: `
1268    The type of package described by the generated SBOM. For SPDX, this is the
1269    value for the \`primaryPackagePurpose\` field. For CycloneDX, this is the
1270    value for the \`type\` field.
1271  `,
1272  flatten,
1273})
1274
1275define('location', {
1276  default: 'user',
1277  short: 'L',
1278  type: [
1279    'global',
1280    'user',
1281    'project',
1282  ],
1283  defaultDescription: `
1284    "user" unless \`--global\` is passed, which will also set this value to "global"
1285  `,
1286  description: `
1287    When passed to \`npm config\` this refers to which config file to use.
1288
1289    When set to "global" mode, packages are installed into the \`prefix\` folder
1290    instead of the current working directory. See
1291    [folders](/configuring-npm/folders) for more on the differences in behavior.
1292
1293    * packages are installed into the \`{prefix}/lib/node_modules\` folder,
1294      instead of the current working directory.
1295    * bin files are linked to \`{prefix}/bin\`
1296    * man pages are linked to \`{prefix}/share/man\`
1297  `,
1298  flatten: (key, obj, flatOptions) => {
1299    flatten(key, obj, flatOptions)
1300    if (flatOptions.global) {
1301      flatOptions.location = 'global'
1302    }
1303    if (obj.location === 'global') {
1304      flatOptions.global = true
1305    }
1306  },
1307})
1308
1309define('lockfile-version', {
1310  default: null,
1311  type: [null, 1, 2, 3, '1', '2', '3'],
1312  defaultDescription: `
1313    Version 3 if no lockfile, auto-converting v1 lockfiles to v3, otherwise
1314    maintain current lockfile version.`,
1315  description: `
1316    Set the lockfile format version to be used in package-lock.json and
1317    npm-shrinkwrap-json files.  Possible options are:
1318
1319    1: The lockfile version used by npm versions 5 and 6.  Lacks some data that
1320    is used during the install, resulting in slower and possibly less
1321    deterministic installs.  Prevents lockfile churn when interoperating with
1322    older npm versions.
1323
1324    2: The default lockfile version used by npm version 7 and 8.  Includes both
1325    the version 1 lockfile data and version 3 lockfile data, for maximum
1326    determinism and interoperability, at the expense of more bytes on disk.
1327
1328    3: Only the new lockfile information introduced in npm version 7.  Smaller
1329    on disk than lockfile version 2, but not interoperable with older npm
1330    versions.  Ideal if all users are on npm version 7 and higher.
1331  `,
1332  flatten: (key, obj, flatOptions) => {
1333    flatOptions.lockfileVersion = obj[key] && parseInt(obj[key], 10)
1334  },
1335})
1336
1337define('loglevel', {
1338  default: 'notice',
1339  type: [
1340    'silent',
1341    'error',
1342    'warn',
1343    'notice',
1344    'http',
1345    'info',
1346    'verbose',
1347    'silly',
1348  ],
1349  description: `
1350    What level of logs to report.  All logs are written to a debug log,
1351    with the path to that file printed if the execution of a command fails.
1352
1353    Any logs of a higher level than the setting are shown. The default is
1354    "notice".
1355
1356    See also the \`foreground-scripts\` config.
1357  `,
1358  flatten (key, obj, flatOptions) {
1359    flatOptions.silent = obj[key] === 'silent'
1360  },
1361})
1362
1363define('logs-dir', {
1364  default: null,
1365  type: [null, path],
1366  defaultDescription: `
1367    A directory named \`_logs\` inside the cache
1368`,
1369  description: `
1370    The location of npm's log directory.  See [\`npm
1371    logging\`](/using-npm/logging) for more information.
1372  `,
1373})
1374
1375define('logs-max', {
1376  default: 10,
1377  type: Number,
1378  description: `
1379    The maximum number of log files to store.
1380
1381    If set to 0, no log files will be written for the current run.
1382  `,
1383})
1384
1385define('long', {
1386  default: false,
1387  type: Boolean,
1388  short: 'l',
1389  description: `
1390    Show extended information in \`ls\`, \`search\`, and \`help-search\`.
1391  `,
1392})
1393
1394define('maxsockets', {
1395  default: 15,
1396  type: Number,
1397  description: `
1398    The maximum number of connections to use per origin (protocol/host/port
1399    combination).
1400  `,
1401  flatten (key, obj, flatOptions) {
1402    flatOptions.maxSockets = obj[key]
1403  },
1404})
1405
1406define('message', {
1407  default: '%s',
1408  type: String,
1409  short: 'm',
1410  description: `
1411    Commit message which is used by \`npm version\` when creating version commit.
1412
1413    Any "%s" in the message will be replaced with the version number.
1414  `,
1415  flatten,
1416})
1417
1418define('node-options', {
1419  default: null,
1420  type: [null, String],
1421  description: `
1422    Options to pass through to Node.js via the \`NODE_OPTIONS\` environment
1423    variable.  This does not impact how npm itself is executed but it does
1424    impact how lifecycle scripts are called.
1425  `,
1426})
1427
1428define('noproxy', {
1429  default: '',
1430  defaultDescription: `
1431    The value of the NO_PROXY environment variable
1432  `,
1433  type: [String, Array],
1434  description: `
1435    Domain extensions that should bypass any proxies.
1436
1437    Also accepts a comma-delimited string.
1438  `,
1439  flatten (key, obj, flatOptions) {
1440    if (Array.isArray(obj[key])) {
1441      flatOptions.noProxy = obj[key].join(',')
1442    } else {
1443      flatOptions.noProxy = obj[key]
1444    }
1445  },
1446})
1447
1448define('offline', {
1449  default: false,
1450  type: Boolean,
1451  description: `
1452    Force offline mode: no network requests will be done during install. To allow
1453    the CLI to fill in missing cache data, see \`--prefer-offline\`.
1454  `,
1455  flatten,
1456})
1457
1458define('omit', {
1459  default: process.env.NODE_ENV === 'production' ? ['dev'] : [],
1460  defaultDescription: `
1461    'dev' if the \`NODE_ENV\` environment variable is set to 'production',
1462    otherwise empty.
1463  `,
1464  type: [Array, 'dev', 'optional', 'peer'],
1465  description: `
1466    Dependency types to omit from the installation tree on disk.
1467
1468    Note that these dependencies _are_ still resolved and added to the
1469    \`package-lock.json\` or \`npm-shrinkwrap.json\` file.  They are just
1470    not physically installed on disk.
1471
1472    If a package type appears in both the \`--include\` and \`--omit\`
1473    lists, then it will be included.
1474
1475    If the resulting omit list includes \`'dev'\`, then the \`NODE_ENV\`
1476    environment variable will be set to \`'production'\` for all lifecycle
1477    scripts.
1478  `,
1479  flatten (key, obj, flatOptions) {
1480    flatOptions.omit = buildOmitList(obj)
1481  },
1482})
1483
1484define('omit-lockfile-registry-resolved', {
1485  default: false,
1486  type: Boolean,
1487  description: `
1488    This option causes npm to create lock files without a \`resolved\` key for
1489    registry dependencies. Subsequent installs will need to resolve tarball
1490    endpoints with the configured registry, likely resulting in a longer install
1491    time.
1492  `,
1493  flatten,
1494})
1495
1496define('only', {
1497  default: null,
1498  type: [null, 'prod', 'production'],
1499  deprecated: `
1500    Use \`--omit=dev\` to omit dev dependencies from the install.
1501  `,
1502  description: `
1503    When set to \`prod\` or \`production\`, this is an alias for
1504    \`--omit=dev\`.
1505  `,
1506  flatten (key, obj, flatOptions) {
1507    definitions.omit.flatten('omit', obj, flatOptions)
1508  },
1509})
1510
1511define('optional', {
1512  default: null,
1513  type: [null, Boolean],
1514  deprecated: `
1515    Use \`--omit=optional\` to exclude optional dependencies, or
1516    \`--include=optional\` to include them.
1517
1518    Default value does install optional deps unless otherwise omitted.
1519  `,
1520  description: `
1521    Alias for --include=optional or --omit=optional
1522  `,
1523  flatten (key, obj, flatOptions) {
1524    definitions.omit.flatten('omit', obj, flatOptions)
1525  },
1526})
1527
1528define('otp', {
1529  default: null,
1530  type: [null, String],
1531  description: `
1532    This is a one-time password from a two-factor authenticator.  It's needed
1533    when publishing or changing package permissions with \`npm access\`.
1534
1535    If not set, and a registry response fails with a challenge for a one-time
1536    password, npm will prompt on the command line for one.
1537  `,
1538  flatten (key, obj, flatOptions) {
1539    flatten(key, obj, flatOptions)
1540    if (obj.otp) {
1541      obj['auth-type'] = 'legacy'
1542      flatten('auth-type', obj, flatOptions)
1543    }
1544  },
1545})
1546
1547define('package', {
1548  default: [],
1549  hint: '<package-spec>',
1550  type: [String, Array],
1551  description: `
1552    The package or packages to install for [\`npm exec\`](/commands/npm-exec)
1553  `,
1554  flatten,
1555})
1556
1557define('package-lock', {
1558  default: true,
1559  type: Boolean,
1560  description: `
1561    If set to false, then ignore \`package-lock.json\` files when installing.
1562    This will also prevent _writing_ \`package-lock.json\` if \`save\` is
1563    true.
1564  `,
1565  flatten: (key, obj, flatOptions) => {
1566    flatten(key, obj, flatOptions)
1567    if (flatOptions.packageLockOnly) {
1568      flatOptions.packageLock = true
1569    }
1570  },
1571})
1572
1573define('package-lock-only', {
1574  default: false,
1575  type: Boolean,
1576  description: `
1577    If set to true, the current operation will only use the \`package-lock.json\`,
1578    ignoring \`node_modules\`.
1579
1580    For \`update\` this means only the \`package-lock.json\` will be updated,
1581    instead of checking \`node_modules\` and downloading dependencies.
1582
1583    For \`list\` this means the output will be based on the tree described by the
1584    \`package-lock.json\`, rather than the contents of \`node_modules\`.
1585  `,
1586  flatten: (key, obj, flatOptions) => {
1587    flatten(key, obj, flatOptions)
1588    if (flatOptions.packageLockOnly) {
1589      flatOptions.packageLock = true
1590    }
1591  },
1592})
1593
1594define('pack-destination', {
1595  default: '.',
1596  type: String,
1597  description: `
1598    Directory in which \`npm pack\` will save tarballs.
1599  `,
1600  flatten,
1601})
1602
1603define('parseable', {
1604  default: false,
1605  type: Boolean,
1606  short: 'p',
1607  description: `
1608    Output parseable results from commands that write to standard output. For
1609    \`npm search\`, this will be tab-separated table format.
1610  `,
1611  flatten,
1612})
1613
1614define('prefer-dedupe', {
1615  default: false,
1616  type: Boolean,
1617  description: `
1618    Prefer to deduplicate packages if possible, rather than
1619    choosing a newer version of a dependency.
1620  `,
1621  flatten,
1622})
1623
1624define('prefer-offline', {
1625  default: false,
1626  type: Boolean,
1627  description: `
1628    If true, staleness checks for cached data will be bypassed, but missing
1629    data will be requested from the server. To force full offline mode, use
1630    \`--offline\`.
1631  `,
1632  flatten,
1633})
1634
1635define('prefer-online', {
1636  default: false,
1637  type: Boolean,
1638  description: `
1639    If true, staleness checks for cached data will be forced, making the CLI
1640    look for updates immediately even for fresh package data.
1641  `,
1642  flatten,
1643})
1644
1645// `prefix` has its default defined outside of this module
1646define('prefix', {
1647  type: path,
1648  short: 'C',
1649  default: '',
1650  defaultDescription: `
1651    In global mode, the folder where the node executable is installed.
1652    Otherwise, the nearest parent folder containing either a package.json
1653    file or a node_modules folder.
1654  `,
1655  description: `
1656    The location to install global items.  If set on the command line, then
1657    it forces non-global commands to run in the specified folder.
1658  `,
1659})
1660
1661define('preid', {
1662  default: '',
1663  hint: 'prerelease-id',
1664  type: String,
1665  description: `
1666    The "prerelease identifier" to use as a prefix for the "prerelease" part
1667    of a semver. Like the \`rc\` in \`1.2.0-rc.8\`.
1668  `,
1669  flatten,
1670})
1671
1672define('production', {
1673  default: null,
1674  type: [null, Boolean],
1675  deprecated: 'Use `--omit=dev` instead.',
1676  description: 'Alias for `--omit=dev`',
1677  flatten (key, obj, flatOptions) {
1678    definitions.omit.flatten('omit', obj, flatOptions)
1679  },
1680})
1681
1682define('progress', {
1683  default: !ciInfo.isCI,
1684  defaultDescription: `
1685    \`true\` unless running in a known CI system
1686  `,
1687  type: Boolean,
1688  description: `
1689    When set to \`true\`, npm will display a progress bar during time
1690    intensive operations, if \`process.stderr\` is a TTY.
1691
1692    Set to \`false\` to suppress the progress bar.
1693  `,
1694  flatten (key, obj, flatOptions) {
1695    flatOptions.progress = !obj.progress ? false
1696      : !!process.stderr.isTTY && process.env.TERM !== 'dumb'
1697  },
1698})
1699
1700define('provenance', {
1701  default: false,
1702  type: Boolean,
1703  exclusive: ['provenance-file'],
1704  description: `
1705    When publishing from a supported cloud CI/CD system, the package will be
1706    publicly linked to where it was built and published from.
1707  `,
1708  flatten,
1709})
1710
1711define('provenance-file', {
1712  default: null,
1713  type: path,
1714  hint: '<file>',
1715  exclusive: ['provenance'],
1716  description: `
1717    When publishing, the provenance bundle at the given path will be used.
1718  `,
1719  flatten,
1720})
1721
1722define('proxy', {
1723  default: null,
1724  type: [null, false, url], // allow proxy to be disabled explicitly
1725  description: `
1726    A proxy to use for outgoing http requests. If the \`HTTP_PROXY\` or
1727    \`http_proxy\` environment variables are set, proxy settings will be
1728    honored by the underlying \`request\` library.
1729  `,
1730  flatten,
1731})
1732
1733define('read-only', {
1734  default: false,
1735  type: Boolean,
1736  description: `
1737    This is used to mark a token as unable to publish when configuring
1738    limited access tokens with the \`npm token create\` command.
1739  `,
1740  flatten,
1741})
1742
1743define('rebuild-bundle', {
1744  default: true,
1745  type: Boolean,
1746  description: `
1747    Rebuild bundled dependencies after installation.
1748  `,
1749  flatten,
1750})
1751
1752define('registry', {
1753  default: 'https://registry.npmjs.org/',
1754  type: url,
1755  description: `
1756    The base URL of the npm registry.
1757  `,
1758  flatten,
1759})
1760
1761define('replace-registry-host', {
1762  default: 'npmjs',
1763  hint: '<npmjs|never|always> | hostname',
1764  type: ['npmjs', 'never', 'always', String],
1765  description: `
1766    Defines behavior for replacing the registry host in a lockfile with the
1767    configured registry.
1768
1769    The default behavior is to replace package dist URLs from the default
1770    registry (https://registry.npmjs.org) to the configured registry. If set to
1771    "never", then use the registry value. If set to "always", then replace the
1772    registry host with the configured host every time.
1773
1774    You may also specify a bare hostname (e.g., "registry.npmjs.org").
1775  `,
1776  flatten,
1777})
1778
1779define('save', {
1780  default: true,
1781  defaultDescription: `\`true\` unless when using \`npm update\` where it
1782  defaults to \`false\``,
1783  usage: '-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle',
1784  type: Boolean,
1785  short: 'S',
1786  description: `
1787    Save installed packages to a \`package.json\` file as dependencies.
1788
1789    When used with the \`npm rm\` command, removes the dependency from
1790    \`package.json\`.
1791
1792    Will also prevent writing to \`package-lock.json\` if set to \`false\`.
1793  `,
1794  flatten,
1795})
1796
1797define('save-bundle', {
1798  default: false,
1799  type: Boolean,
1800  short: 'B',
1801  description: `
1802    If a package would be saved at install time by the use of \`--save\`,
1803    \`--save-dev\`, or \`--save-optional\`, then also put it in the
1804    \`bundleDependencies\` list.
1805
1806    Ignored if \`--save-peer\` is set, since peerDependencies cannot be bundled.
1807  `,
1808  flatten (key, obj, flatOptions) {
1809    // XXX update arborist to just ignore it if resulting saveType is peer
1810    // otherwise this won't have the expected effect:
1811    //
1812    // npm config set save-peer true
1813    // npm i foo --save-bundle --save-prod <-- should bundle
1814    flatOptions.saveBundle = obj['save-bundle'] && !obj['save-peer']
1815  },
1816})
1817
1818// XXX: We should really deprecate all these `--save-blah` switches
1819// in favor of a single `--save-type` option.  The unfortunate shortcut
1820// we took for `--save-peer --save-optional` being `--save-type=peerOptional`
1821// makes this tricky, and likely a breaking change.
1822
1823define('save-dev', {
1824  default: false,
1825  type: Boolean,
1826  short: 'D',
1827  description: `
1828    Save installed packages to a package.json file as \`devDependencies\`.
1829  `,
1830  flatten (key, obj, flatOptions) {
1831    if (!obj[key]) {
1832      if (flatOptions.saveType === 'dev') {
1833        delete flatOptions.saveType
1834      }
1835      return
1836    }
1837
1838    flatOptions.saveType = 'dev'
1839  },
1840})
1841
1842define('save-exact', {
1843  default: false,
1844  type: Boolean,
1845  short: 'E',
1846  description: `
1847    Dependencies saved to package.json will be configured with an exact
1848    version rather than using npm's default semver range operator.
1849  `,
1850  flatten (key, obj, flatOptions) {
1851    // just call the save-prefix flattener, it reads from obj['save-exact']
1852    definitions['save-prefix'].flatten('save-prefix', obj, flatOptions)
1853  },
1854})
1855
1856define('save-optional', {
1857  default: false,
1858  type: Boolean,
1859  short: 'O',
1860  description: `
1861    Save installed packages to a package.json file as
1862    \`optionalDependencies\`.
1863  `,
1864  flatten (key, obj, flatOptions) {
1865    if (!obj[key]) {
1866      if (flatOptions.saveType === 'optional') {
1867        delete flatOptions.saveType
1868      } else if (flatOptions.saveType === 'peerOptional') {
1869        flatOptions.saveType = 'peer'
1870      }
1871      return
1872    }
1873
1874    if (flatOptions.saveType === 'peerOptional') {
1875      return
1876    }
1877
1878    if (flatOptions.saveType === 'peer') {
1879      flatOptions.saveType = 'peerOptional'
1880    } else {
1881      flatOptions.saveType = 'optional'
1882    }
1883  },
1884})
1885
1886define('save-peer', {
1887  default: false,
1888  type: Boolean,
1889  description: `
1890    Save installed packages to a package.json file as \`peerDependencies\`
1891  `,
1892  flatten (key, obj, flatOptions) {
1893    if (!obj[key]) {
1894      if (flatOptions.saveType === 'peer') {
1895        delete flatOptions.saveType
1896      } else if (flatOptions.saveType === 'peerOptional') {
1897        flatOptions.saveType = 'optional'
1898      }
1899      return
1900    }
1901
1902    if (flatOptions.saveType === 'peerOptional') {
1903      return
1904    }
1905
1906    if (flatOptions.saveType === 'optional') {
1907      flatOptions.saveType = 'peerOptional'
1908    } else {
1909      flatOptions.saveType = 'peer'
1910    }
1911  },
1912})
1913
1914define('save-prefix', {
1915  default: '^',
1916  type: String,
1917  description: `
1918    Configure how versions of packages installed to a package.json file via
1919    \`--save\` or \`--save-dev\` get prefixed.
1920
1921    For example if a package has version \`1.2.3\`, by default its version is
1922    set to \`^1.2.3\` which allows minor upgrades for that package, but after
1923    \`npm config set save-prefix='~'\` it would be set to \`~1.2.3\` which
1924    only allows patch upgrades.
1925  `,
1926  flatten (key, obj, flatOptions) {
1927    flatOptions.savePrefix = obj['save-exact'] ? '' : obj['save-prefix']
1928    obj['save-prefix'] = flatOptions.savePrefix
1929  },
1930})
1931
1932define('save-prod', {
1933  default: false,
1934  type: Boolean,
1935  short: 'P',
1936  description: `
1937    Save installed packages into \`dependencies\` specifically. This is
1938    useful if a package already exists in \`devDependencies\` or
1939    \`optionalDependencies\`, but you want to move it to be a non-optional
1940    production dependency.
1941
1942    This is the default behavior if \`--save\` is true, and neither
1943    \`--save-dev\` or \`--save-optional\` are true.
1944  `,
1945  flatten (key, obj, flatOptions) {
1946    if (!obj[key]) {
1947      if (flatOptions.saveType === 'prod') {
1948        delete flatOptions.saveType
1949      }
1950      return
1951    }
1952
1953    flatOptions.saveType = 'prod'
1954  },
1955})
1956
1957define('scope', {
1958  default: '',
1959  defaultDescription: `
1960    the scope of the current project, if any, or ""
1961  `,
1962  type: String,
1963  hint: '<@scope>',
1964  description: `
1965    Associate an operation with a scope for a scoped registry.
1966
1967    Useful when logging in to or out of a private registry:
1968
1969    \`\`\`
1970    # log in, linking the scope to the custom registry
1971    npm login --scope=@mycorp --registry=https://registry.mycorp.com
1972
1973    # log out, removing the link and the auth token
1974    npm logout --scope=@mycorp
1975    \`\`\`
1976
1977    This will cause \`@mycorp\` to be mapped to the registry for future
1978    installation of packages specified according to the pattern
1979    \`@mycorp/package\`.
1980
1981    This will also cause \`npm init\` to create a scoped package.
1982
1983    \`\`\`
1984    # accept all defaults, and create a package named "@foo/whatever",
1985    # instead of just named "whatever"
1986    npm init --scope=@foo --yes
1987    \`\`\`
1988  `,
1989  flatten (key, obj, flatOptions) {
1990    const value = obj[key]
1991    const scope = value && !/^@/.test(value) ? `@${value}` : value
1992    flatOptions.scope = scope
1993    // projectScope is kept for compatibility with npm-registry-fetch
1994    flatOptions.projectScope = scope
1995  },
1996})
1997
1998define('script-shell', {
1999  default: null,
2000  defaultDescription: `
2001    '/bin/sh' on POSIX systems, 'cmd.exe' on Windows
2002  `,
2003  type: [null, String],
2004  description: `
2005    The shell to use for scripts run with the \`npm exec\`,
2006    \`npm run\` and \`npm init <package-spec>\` commands.
2007  `,
2008  flatten (key, obj, flatOptions) {
2009    flatOptions.scriptShell = obj[key] || undefined
2010  },
2011})
2012
2013define('searchexclude', {
2014  default: '',
2015  type: String,
2016  description: `
2017    Space-separated options that limit the results from search.
2018  `,
2019  flatten (key, obj, flatOptions) {
2020    flatOptions.search = flatOptions.search || { limit: 20 }
2021    flatOptions.search.exclude = obj[key].toLowerCase()
2022  },
2023})
2024
2025define('searchlimit', {
2026  default: 20,
2027  type: Number,
2028  description: `
2029    Number of items to limit search results to. Will not apply at all to
2030    legacy searches.
2031  `,
2032  flatten (key, obj, flatOptions) {
2033    flatOptions.search = flatOptions.search || {}
2034    flatOptions.search.limit = obj[key]
2035  },
2036})
2037
2038define('searchopts', {
2039  default: '',
2040  type: String,
2041  description: `
2042    Space-separated options that are always passed to search.
2043  `,
2044  flatten (key, obj, flatOptions) {
2045    flatOptions.search = flatOptions.search || { limit: 20 }
2046    flatOptions.search.opts = querystring.parse(obj[key])
2047  },
2048})
2049
2050define('searchstaleness', {
2051  default: 15 * 60,
2052  type: Number,
2053  description: `
2054    The age of the cache, in seconds, before another registry request is made
2055    if using legacy search endpoint.
2056  `,
2057  flatten (key, obj, flatOptions) {
2058    flatOptions.search = flatOptions.search || { limit: 20 }
2059    flatOptions.search.staleness = obj[key]
2060  },
2061})
2062
2063define('shell', {
2064  default: shell,
2065  defaultDescription: `
2066    SHELL environment variable, or "bash" on Posix, or "cmd.exe" on Windows
2067  `,
2068  type: String,
2069  description: `
2070    The shell to run for the \`npm explore\` command.
2071  `,
2072  flatten,
2073})
2074
2075define('shrinkwrap', {
2076  default: true,
2077  type: Boolean,
2078  deprecated: `
2079    Use the --package-lock setting instead.
2080  `,
2081  description: `
2082    Alias for --package-lock
2083  `,
2084  flatten (key, obj, flatOptions) {
2085    obj['package-lock'] = obj.shrinkwrap
2086    definitions['package-lock'].flatten('package-lock', obj, flatOptions)
2087  },
2088})
2089
2090define('sign-git-commit', {
2091  default: false,
2092  type: Boolean,
2093  description: `
2094    If set to true, then the \`npm version\` command will commit the new
2095    package version using \`-S\` to add a signature.
2096
2097    Note that git requires you to have set up GPG keys in your git configs
2098    for this to work properly.
2099  `,
2100  flatten,
2101})
2102
2103define('sign-git-tag', {
2104  default: false,
2105  type: Boolean,
2106  description: `
2107    If set to true, then the \`npm version\` command will tag the version
2108    using \`-s\` to add a signature.
2109
2110    Note that git requires you to have set up GPG keys in your git configs
2111    for this to work properly.
2112  `,
2113  flatten,
2114})
2115
2116define('strict-peer-deps', {
2117  default: false,
2118  type: Boolean,
2119  description: `
2120    If set to \`true\`, and \`--legacy-peer-deps\` is not set, then _any_
2121    conflicting \`peerDependencies\` will be treated as an install failure,
2122    even if npm could reasonably guess the appropriate resolution based on
2123    non-peer dependency relationships.
2124
2125    By default, conflicting \`peerDependencies\` deep in the dependency graph
2126    will be resolved using the nearest non-peer dependency specification,
2127    even if doing so will result in some packages receiving a peer dependency
2128    outside the range set in their package's \`peerDependencies\` object.
2129
2130    When such an override is performed, a warning is printed, explaining the
2131    conflict and the packages involved.  If \`--strict-peer-deps\` is set,
2132    then this warning is treated as a failure.
2133  `,
2134  flatten,
2135})
2136
2137define('strict-ssl', {
2138  default: true,
2139  type: Boolean,
2140  description: `
2141    Whether or not to do SSL key validation when making requests to the
2142    registry via https.
2143
2144    See also the \`ca\` config.
2145  `,
2146  flatten (key, obj, flatOptions) {
2147    flatOptions.strictSSL = obj[key]
2148  },
2149})
2150
2151define('tag', {
2152  default: 'latest',
2153  type: String,
2154  description: `
2155    If you ask npm to install a package and don't tell it a specific version,
2156    then it will install the specified tag.
2157
2158    Also the tag that is added to the package@version specified by the \`npm
2159    tag\` command, if no explicit tag is given.
2160
2161    When used by the \`npm diff\` command, this is the tag used to fetch the
2162    tarball that will be compared with the local files by default.
2163  `,
2164  flatten (key, obj, flatOptions) {
2165    flatOptions.defaultTag = obj[key]
2166  },
2167})
2168
2169define('tag-version-prefix', {
2170  default: 'v',
2171  type: String,
2172  description: `
2173    If set, alters the prefix used when tagging a new version when performing
2174    a version increment using  \`npm version\`. To remove the prefix
2175    altogether, set it to the empty string: \`""\`.
2176
2177    Because other tools may rely on the convention that npm version tags look
2178    like \`v1.0.0\`, _only use this property if it is absolutely necessary_.
2179    In particular, use care when overriding this setting for public packages.
2180  `,
2181  flatten,
2182})
2183
2184define('timing', {
2185  default: false,
2186  type: Boolean,
2187  description: `
2188    If true, writes timing information to a process specific json file in
2189    the cache or \`logs-dir\`. The file name ends with \`-timing.json\`.
2190
2191    You can quickly view it with this [json](https://npm.im/json) command
2192    line: \`cat ~/.npm/_logs/*-timing.json | npm exec -- json -g\`.
2193
2194    Timing information will also be reported in the terminal. To suppress this
2195    while still writing the timing file, use \`--silent\`.
2196  `,
2197})
2198
2199define('umask', {
2200  default: 0,
2201  type: Umask,
2202  description: `
2203    The "umask" value to use when setting the file creation mode on files and
2204    folders.
2205
2206    Folders and executables are given a mode which is \`0o777\` masked
2207    against this value.  Other files are given a mode which is \`0o666\`
2208    masked against this value.
2209
2210    Note that the underlying system will _also_ apply its own umask value to
2211    files and folders that are created, and npm does not circumvent this, but
2212    rather adds the \`--umask\` config to it.
2213
2214    Thus, the effective default umask value on most POSIX systems is 0o22,
2215    meaning that folders and executables are created with a mode of 0o755 and
2216    other files are created with a mode of 0o644.
2217  `,
2218  flatten,
2219})
2220
2221define('unicode', {
2222  default: unicode,
2223  defaultDescription: `
2224    false on windows, true on mac/unix systems with a unicode locale, as
2225    defined by the \`LC_ALL\`, \`LC_CTYPE\`, or \`LANG\` environment variables.
2226  `,
2227  type: Boolean,
2228  description: `
2229    When set to true, npm uses unicode characters in the tree output.  When
2230    false, it uses ascii characters instead of unicode glyphs.
2231  `,
2232  flatten,
2233})
2234
2235define('update-notifier', {
2236  default: true,
2237  type: Boolean,
2238  description: `
2239    Set to false to suppress the update notification when using an older
2240    version of npm than the latest.
2241  `,
2242})
2243
2244define('usage', {
2245  default: false,
2246  type: Boolean,
2247  short: ['?', 'H', 'h'],
2248  description: `
2249    Show short usage output about the command specified.
2250  `,
2251})
2252
2253define('user-agent', {
2254  default: 'npm/{npm-version} ' +
2255           'node/{node-version} ' +
2256           '{platform} ' +
2257           '{arch} ' +
2258           'workspaces/{workspaces} ' +
2259           '{ci}',
2260  type: String,
2261  description: `
2262    Sets the User-Agent request header.  The following fields are replaced
2263    with their actual counterparts:
2264
2265    * \`{npm-version}\` - The npm version in use
2266    * \`{node-version}\` - The Node.js version in use
2267    * \`{platform}\` - The value of \`process.platform\`
2268    * \`{arch}\` - The value of \`process.arch\`
2269    * \`{workspaces}\` - Set to \`true\` if the \`workspaces\` or \`workspace\`
2270      options are set.
2271    * \`{ci}\` - The value of the \`ci-name\` config, if set, prefixed with
2272      \`ci/\`, or an empty string if \`ci-name\` is empty.
2273  `,
2274  flatten (key, obj, flatOptions) {
2275    const value = obj[key]
2276    const ciName = ciInfo.name?.toLowerCase().split(' ').join('-') || null
2277    let inWorkspaces = false
2278    if (obj.workspaces || obj.workspace && obj.workspace.length) {
2279      inWorkspaces = true
2280    }
2281    flatOptions.userAgent =
2282      value.replace(/\{node-version\}/gi, process.version)
2283        .replace(/\{npm-version\}/gi, obj['npm-version'])
2284        .replace(/\{platform\}/gi, process.platform)
2285        .replace(/\{arch\}/gi, process.arch)
2286        .replace(/\{workspaces\}/gi, inWorkspaces)
2287        .replace(/\{ci\}/gi, ciName ? `ci/${ciName}` : '')
2288        .trim()
2289
2290    // We can't clobber the original or else subsequent flattening will fail
2291    // (i.e. when we change the underlying config values)
2292    // obj[key] = flatOptions.userAgent
2293
2294    // user-agent is a unique kind of config item that gets set from a template
2295    // and ends up translated.  Because of this, the normal "should we set this
2296    // to process.env also doesn't work
2297    process.env.npm_config_user_agent = flatOptions.userAgent
2298  },
2299})
2300
2301define('userconfig', {
2302  default: '~/.npmrc',
2303  type: path,
2304  description: `
2305    The location of user-level configuration settings.
2306
2307    This may be overridden by the \`npm_config_userconfig\` environment
2308    variable or the \`--userconfig\` command line option, but may _not_
2309    be overridden by settings in the \`globalconfig\` file.
2310  `,
2311})
2312
2313define('version', {
2314  default: false,
2315  type: Boolean,
2316  short: 'v',
2317  description: `
2318    If true, output the npm version and exit successfully.
2319
2320    Only relevant when specified explicitly on the command line.
2321  `,
2322})
2323
2324define('versions', {
2325  default: false,
2326  type: Boolean,
2327  description: `
2328    If true, output the npm version as well as node's \`process.versions\`
2329    map and the version in the current working directory's \`package.json\`
2330    file if one exists, and exit successfully.
2331
2332    Only relevant when specified explicitly on the command line.
2333  `,
2334})
2335
2336define('viewer', {
2337  default: isWindows ? 'browser' : 'man',
2338  defaultDescription: `
2339    "man" on Posix, "browser" on Windows
2340  `,
2341  type: String,
2342  description: `
2343    The program to use to view help content.
2344
2345    Set to \`"browser"\` to view html help content in the default web browser.
2346  `,
2347})
2348
2349define('which', {
2350  default: null,
2351  hint: '<fundingSourceNumber>',
2352  type: [null, Number],
2353  description: `
2354    If there are multiple funding sources, which 1-indexed source URL to open.
2355  `,
2356})
2357
2358define('workspace', {
2359  default: [],
2360  type: [String, Array],
2361  hint: '<workspace-name>',
2362  short: 'w',
2363  envExport: false,
2364  description: `
2365    Enable running a command in the context of the configured workspaces of the
2366    current project while filtering by running only the workspaces defined by
2367    this configuration option.
2368
2369    Valid values for the \`workspace\` config are either:
2370
2371    * Workspace names
2372    * Path to a workspace directory
2373    * Path to a parent workspace directory (will result in selecting all
2374      workspaces within that folder)
2375
2376    When set for the \`npm init\` command, this may be set to the folder of
2377    a workspace which does not yet exist, to create the folder and set it
2378    up as a brand new workspace within the project.
2379  `,
2380  flatten: (key, obj, flatOptions) => {
2381    definitions['user-agent'].flatten('user-agent', obj, flatOptions)
2382  },
2383})
2384
2385define('workspaces', {
2386  default: null,
2387  type: [null, Boolean],
2388  short: 'ws',
2389  envExport: false,
2390  description: `
2391    Set to true to run the command in the context of **all** configured
2392    workspaces.
2393
2394    Explicitly setting this to false will cause commands like \`install\` to
2395    ignore workspaces altogether.
2396    When not set explicitly:
2397
2398    - Commands that operate on the \`node_modules\` tree (install, update,
2399      etc.) will link workspaces into the \`node_modules\` folder.
2400    - Commands that do other things (test, exec, publish, etc.) will operate
2401      on the root project, _unless_ one or more workspaces are specified in
2402      the \`workspace\` config.
2403  `,
2404  flatten: (key, obj, flatOptions) => {
2405    definitions['user-agent'].flatten('user-agent', obj, flatOptions)
2406
2407    // TODO: this is a derived value, and should be reworked when we have a
2408    // pattern for derived value
2409
2410    // workspacesEnabled is true whether workspaces is null or true
2411    // commands contextually work with workspaces or not regardless of
2412    // configuration, so we need an option specifically to disable workspaces
2413    flatOptions.workspacesEnabled = obj[key] !== false
2414  },
2415})
2416
2417define('workspaces-update', {
2418  default: true,
2419  type: Boolean,
2420  description: `
2421    If set to true, the npm cli will run an update after operations that may
2422    possibly change the workspaces installed to the \`node_modules\` folder.
2423  `,
2424  flatten,
2425})
2426
2427define('yes', {
2428  default: null,
2429  type: [null, Boolean],
2430  short: 'y',
2431  description: `
2432    Automatically answer "yes" to any prompts that npm might print on
2433    the command line.
2434  `,
2435})
2436