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