codekingpro/portable-devtools
114k
1const Definition = require('./definition.js')
2
3const ciInfo = require('ci-info')
4const querystring = require('node:querystring')
5const { join } = require('node:path')
6
7const isWindows = process.platform === 'win32'
8
9// used by cafile flattening to flatOptions.ca
10const { readFileSync } = require('node:fs')
11const maybeReadFile = file => {
12 try {
13 return readFileSync(file, 'utf8')
14 } catch (er) {
15 if (er.code !== 'ENOENT') {
16 throw er
17 }
18 return null
19 }
20}
21
22const buildOmitList = obj => {
23 const include = obj.include || []
24 const omit = obj.omit || []
25
26 const only = obj.only
27 if (/^prod(uction)?$/.test(only) || obj.production) {
28 omit.push('dev')
29 } else if (obj.production === false) {
30 include.push('dev')
31 }
32
33 if (/^dev/.test(obj.also)) {
34 include.push('dev')
35 }
36
37 if (obj.dev) {
38 include.push('dev')
39 }
40
41 if (obj.optional === false) {
42 omit.push('optional')
43 } else if (obj.optional === true) {
44 include.push('optional')
45 }
46
47 obj.omit = [...new Set(omit)].filter(type => !include.includes(type))
48 obj.include = [...new Set(include)]
49
50 if (obj.omit.includes('dev')) {
51 process.env.NODE_ENV = 'production'
52 }
53
54 return obj.omit
55}
56
57const editor = process.env.EDITOR ||
58 process.env.VISUAL ||
59 (isWindows ? `${process.env.SYSTEMROOT}\\notepad.exe` : 'vi')
60
61const shell = isWindows ? process.env.ComSpec || 'cmd'
62 : process.env.SHELL || 'sh'
63
64const { networkInterfaces } = require('node:os')
65const getLocalAddresses = () => {
66 try {
67 return Object.values(networkInterfaces()).map(
68 int => int.map(({ address }) => address)
69 ).reduce((set, addrs) => set.concat(addrs), [null])
70 } catch (e) {
71 return [null]
72 }
73}
74
75const unicode = /UTF-?8$/i.test(
76 process.env.LC_ALL ||
77 process.env.LC_CTYPE ||
78 process.env.LANG
79)
80
81// use LOCALAPPDATA on Windows, if set
82// https://github.com/npm/cli/pull/899
83const cacheRoot = (isWindows && process.env.LOCALAPPDATA) || '~'
84const cacheExtra = isWindows ? 'npm-cache' : '.npm'
85const cache = `${cacheRoot}/${cacheExtra}`
86
87// TODO: refactor these type definitions so that they are less
88// weird to pull out of the config module.
89// TODO: use better type definition/validation API, nopt's is so weird.
90const {
91 semver: { type: Semver },
92 Umask: { type: Umask },
93 url: { type: url },
94 path: { type: path },
95} = require('../type-defs.js')
96
97// basic flattening function, just copy it over camelCase
98const flatten = (key, obj, flatOptions) => {
99 const camel = key.replace(/-([a-z])/g, (_0, _1) => _1.toUpperCase())
100 flatOptions[camel] = obj[key]
101}
102
103// TODO:
104// Instead of having each definition provide a flatten method,
105// provide the (?list of?) flat option field(s?) that it impacts.
106// When that config is set, we mark the relevant flatOption fields
107// dirty. Then, a getter for that field defines how we actually
108// set it.
109//
110// So, `save-dev`, `save-optional`, `save-prod`, et al would indicate
111// that they affect the `saveType` flat option. Then the config.flat
112// object has a `get saveType () { ... }` that looks at the "real"
113// config settings from files etc and returns the appropriate value.
114//
115// Getters will also (maybe?) give us a hook to audit flat option
116// usage, so we can document and group these more appropriately.
117//
118// This will be a problem with cases where we currently do:
119// const opts = { ...npm.flatOptions, foo: 'bar' }, but we can maybe
120// instead do `npm.config.set('foo', 'bar')` prior to passing the
121// config object down where it needs to go.
122//
123// This way, when we go hunting for "where does saveType come from anyway!?"
124// while fixing some Arborist bug, we won't have to hunt through too
125// many places.
126
127// XXX: We should really deprecate all these `--save-blah` switches
128// in favor of a single `--save-type` option. The unfortunate shortcut
129// we took for `--save-peer --save-optional` being `--save-type=peerOptional`
130// makes this tricky, and likely a breaking change.
131
132// Define all config keys we know about. They are indexed by their own key for
133// ease of lookup later. This duplication is an optimization so that we don't
134// have to do an extra function call just to "reuse" the key in both places.
135
136const definitions = {
137 _auth: new Definition('_auth', {
138 default: null,
139 type: [null, String],
140 description: `
141 A basic-auth string to use when authenticating against the npm registry.
142 This will ONLY be used to authenticate against the npm registry. For other
143 registries you will need to scope it like "//other-registry.tld/:_auth"
144
145 Warning: This should generally not be set via a command-line option. It
146 is safer to use a registry-provided authentication bearer token stored in
147 the ~/.npmrc file by running \`npm login\`.
148 `,
149 flatten,
150 }),
151 access: new Definition('access', {
152 default: null,
153 defaultDescription: `
154 'public' for new packages, existing packages it will not change the current level
155 `,
156 type: [null, 'restricted', 'public'],
157 description: `
158 If you do not want your scoped package to be publicly viewable (and
159 installable) set \`--access=restricted\`.
160
161 Unscoped packages cannot be set to \`restricted\`.
162
163 Note: This defaults to not changing the current access level for existing
164 packages. Specifying a value of \`restricted\` or \`public\` during
165 publish will change the access for an existing package the same way that
166 \`npm access set status\` would.
167 `,
168 flatten,
169 }),
170 all: new Definition('all', {
171 default: false,
172 type: Boolean,
173 short: 'a',
174 description: `
175 When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show
176 all outdated or installed packages, rather than only those directly
177 depended upon by the current project.
178 `,
179 flatten,
180 }),
181 'allow-same-version': new Definition('allow-same-version', {
182 default: false,
183 type: Boolean,
184 description: `
185 Prevents throwing an error when \`npm version\` is used to set the new
186 version to the same value as the current version.
187 `,
188 flatten,
189 }),
190 'allow-git': new Definition('allow-git', {
191 default: 'all',
192 type: ['all', 'none', 'root'],
193 description: `
194 Limits the ability for npm to fetch dependencies from git references.
195 That is, dependencies that point to a git repo instead of a version or semver range.
196 Please note that this could leave your tree incomplete and some packages may not function as intended or designed.
197
198 \`all\` allows any git dependencies to be fetched and installed.
199 \`none\` prevents any git dependencies from being fetched and installed.
200 \`root\` only allows git dependencies defined in your project's package.json to be fetched installed. Also allows git dependencies to be fetched for other commands like \`npm view\`
201 `,
202 flatten,
203 }),
204 also: new Definition('also', {
205 default: null,
206 type: [null, 'dev', 'development'],
207 description: `
208 When set to \`dev\` or \`development\`, this is an alias for
209 \`--include=dev\`.
210 `,
211 deprecated: 'Please use --include=dev instead.',
212 flatten (key, obj, flatOptions) {
213 definitions.omit.flatten('omit', obj, flatOptions)
214 },
215 }),
216 audit: new Definition('audit', {
217 default: true,
218 type: Boolean,
219 description: `
220 When "true" submit audit reports alongside the current npm command to the
221 default registry and all registries configured for scopes. See the
222 documentation for [\`npm audit\`](/commands/npm-audit) for details on what
223 is submitted.
224 `,
225 flatten,
226 }),
227 'audit-level': new Definition('audit-level', {
228 default: null,
229 type: [null, 'info', 'low', 'moderate', 'high', 'critical', 'none'],
230 description: `
231 The minimum level of vulnerability for \`npm audit\` to exit with
232 a non-zero exit code.
233 `,
234 flatten,
235 }),
236 'auth-type': new Definition('auth-type', {
237 default: 'web',
238 type: ['legacy', 'web'],
239 description: `
240 What authentication strategy to use with \`login\`.
241 Note that if an \`otp\` config is given, this value will always be set to \`legacy\`.
242 `,
243 flatten,
244 }),
245 before: new Definition('before', {
246 default: null,
247 hint: '<date>',
248 type: [null, Date],
249 exclusive: ['min-release-age'],
250 description: `
251 If passed to \`npm install\`, will rebuild the npm tree such that only
252 versions that were available **on or before** the given date are
253 installed. If there are no versions available for the current set of
254 dependencies, the command will error.
255
256 If the requested version is a \`dist-tag\` and the given tag does not
257 pass the \`--before\` filter, the most recent version less than or equal
258 to that tag will be used. For example, \`foo@latest\` might install
259 \`foo@1.2\` even though \`latest\` is \`2.0\`.
260 `,
261 flatten,
262 }),
263 'bin-links': new Definition('bin-links', {
264 default: true,
265 type: Boolean,
266 description: `
267 Tells npm to create symlinks (or \`.cmd\` shims on Windows) for package
268 executables.
269
270 Set to false to have it not do this. This can be used to work around the
271 fact that some file systems don't support symlinks, even on ostensibly
272 Unix systems.
273 `,
274 flatten,
275 }),
276 browser: new Definition('browser', {
277 default: null,
278 defaultDescription: `
279 macOS: \`"open"\`, Windows: \`"start"\`, Others: \`"xdg-open"\`
280 `,
281 type: [null, Boolean, String],
282 description: `
283 The browser that is called by npm commands to open websites.
284
285 Set to \`false\` to suppress browser behavior and instead print urls to
286 terminal.
287
288 Set to \`true\` to use default system URL opener.
289 `,
290 flatten,
291 }),
292 'bypass-2fa': new Definition('bypass-2fa', {
293 default: false,
294 type: Boolean,
295 description: `
296 When creating a Granular Access Token with \`npm token create\`,
297 setting this to true will allow the token to bypass two-factor
298 authentication. This is useful for automation and CI/CD workflows.
299 `,
300 flatten,
301 }),
302 ca: new Definition('ca', {
303 default: null,
304 type: [null, String, Array],
305 description: `
306 The Certificate Authority signing certificate that is trusted for SSL
307 connections to the registry. Values should be in PEM format (Windows
308 calls it "Base-64 encoded X.509 (.CER)") with newlines replaced by the
309 string "\\n". For example:
310
311 \`\`\`ini
312 ca="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----"
313 \`\`\`
314
315 Set to \`null\` to only allow "known" registrars, or to a specific CA
316 cert to trust only that specific signing authority.
317
318 Multiple CAs can be trusted by specifying an array of certificates:
319
320 \`\`\`ini
321 ca[]="..."
322 ca[]="..."
323 \`\`\`
324
325 See also the \`strict-ssl\` config.
326 `,
327 flatten,
328 }),
329 cache: new Definition('cache', {
330 default: cache,
331 defaultDescription: `
332 Windows: \`%LocalAppData%\\npm-cache\`, Posix: \`~/.npm\`
333 `,
334 type: path,
335 description: `
336 The location of npm's cache directory.
337 `,
338 flatten (key, obj, flatOptions) {
339 flatOptions.cache = join(obj.cache, '_cacache')
340 flatOptions.npxCache = join(obj.cache, '_npx')
341 flatOptions.tufCache = join(obj.cache, '_tuf')
342 },
343 }),
344 'cache-max': new Definition('cache-max', {
345 default: Infinity,
346 type: Number,
347 description: `
348 \`--cache-max=0\` is an alias for \`--prefer-online\`
349 `,
350 deprecated: `
351 This option has been deprecated in favor of \`--prefer-online\`
352 `,
353 flatten (key, obj, flatOptions) {
354 if (obj[key] <= 0) {
355 flatOptions.preferOnline = true
356 }
357 },
358 }),
359 'cache-min': new Definition('cache-min', {
360 default: 0,
361 type: Number,
362 description: `
363 \`--cache-min=9999 (or bigger)\` is an alias for \`--prefer-offline\`.
364 `,
365 deprecated: `
366 This option has been deprecated in favor of \`--prefer-offline\`.
367 `,
368 flatten (key, obj, flatOptions) {
369 if (obj[key] >= 9999) {
370 flatOptions.preferOffline = true
371 }
372 },
373 }),
374 cafile: new Definition('cafile', {
375 default: null,
376 type: path,
377 description: `
378 A path to a file containing one or multiple Certificate Authority signing
379 certificates. Similar to the \`ca\` setting, but allows for multiple
380 CA's, as well as for the CA information to be stored in a file on disk.
381 `,
382 flatten (key, obj, flatOptions) {
383 // always set to null in defaults
384 if (!obj.cafile) {
385 return
386 }
387
388 const raw = maybeReadFile(obj.cafile)
389 if (!raw) {
390 return
391 }
392
393 const delim = '-----END CERTIFICATE-----'
394 flatOptions.ca = raw.replace(/\r\n/g, '\n').split(delim)
395 .filter(section => section.trim())
396 .map(section => section.trimLeft() + delim)
397 },
398 }),
399 call: new Definition('call', {
400 default: '',
401 type: String,
402 short: 'c',
403 description: `
404 Optional companion option for \`npm exec\`, \`npx\` that allows for
405 specifying a custom command to be run along with the installed packages.
406
407 \`\`\`bash
408 npm exec --package yo --package generator-node --call "yo node"
409 \`\`\`
410 `,
411 flatten,
412 }),
413 cert: new Definition('cert', {
414 default: null,
415 type: [null, String],
416 description: `
417 A client certificate to pass when accessing the registry. Values should
418 be in PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with
419 newlines replaced by the string "\\n". For example:
420
421 \`\`\`ini
422 cert="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----"
423 \`\`\`
424
425 It is _not_ the path to a certificate file, though you can set a registry-scoped
426 "certfile" path like "//other-registry.tld/:certfile=/path/to/cert.pem".
427 `,
428 deprecated: `
429 \`key\` and \`cert\` are no longer used for most registry operations.
430 Use registry scoped \`keyfile\` and \`certfile\` instead.
431 Example:
432 //other-registry.tld/:keyfile=/path/to/key.pem
433 //other-registry.tld/:certfile=/path/to/cert.crt
434 `,
435 flatten,
436 }),
437 cidr: new Definition('cidr', {
438 default: null,
439 type: [null, String, Array],
440 description: `
441 This is a list of CIDR address to be used when configuring limited access
442 tokens with the \`npm token create\` command.
443 `,
444 flatten,
445 }),
446 // This should never be directly used, the flattened value is the derived value
447 // and is sent to other modules, and is also exposed as `npm.color` for use
448 // inside npm itself.
449 color: new Definition('color', {
450 default: !process.env.NO_COLOR || process.env.NO_COLOR === '0',
451 usage: '--color|--no-color|--color always',
452 defaultDescription: `
453 true unless the NO_COLOR environ is set to something other than '0'
454 `,
455 type: ['always', Boolean],
456 description: `
457 If false, never shows colors. If \`"always"\` then always shows colors.
458 If true, then only prints color codes for tty file descriptors.
459 `,
460 flatten (key, obj, flatOptions) {
461 flatOptions.color = !obj.color ? false
462 : obj.color === 'always' ? true
463 : !!process.stdout.isTTY
464 flatOptions.logColor = !obj.color ? false
465 : obj.color === 'always' ? true
466 : !!process.stderr.isTTY
467 },
468 }),
469 'commit-hooks': new Definition('commit-hooks', {
470 default: true,
471 type: Boolean,
472 description: `
473 Run git commit hooks when using the \`npm version\` command.
474 `,
475 flatten,
476 }),
477 cpu: new Definition('cpu', {
478 default: null,
479 type: [null, String],
480 description: `
481 Override CPU architecture of native modules to install.
482 Acceptable values are same as \`cpu\` field of package.json,
483 which comes from \`process.arch\`.
484 `,
485 flatten,
486 }),
487 depth: new Definition('depth', {
488 default: null,
489 defaultDescription: `
490 \`Infinity\` if \`--all\` is set; otherwise, \`0\`
491 `,
492 type: [null, Number],
493 description: `
494 The depth to go when recursing packages for \`npm ls\`.
495
496 If not set, \`npm ls\` will show only the immediate dependencies of the
497 root project. If \`--all\` is set, then npm will show all dependencies
498 by default.
499 `,
500 flatten,
501 }),
502 description: new Definition('description', {
503 default: true,
504 type: Boolean,
505 usage: '--no-description',
506 description: `
507 Show the description in \`npm search\`
508 `,
509 flatten (key, obj, flatOptions) {
510 flatOptions.search = flatOptions.search || { limit: 20 }
511 flatOptions.search[key] = obj[key]
512 },
513 }),
514 dev: new Definition('dev', {
515 default: false,
516 type: Boolean,
517 description: `
518 Alias for \`--include=dev\`.
519 `,
520 deprecated: 'Please use --include=dev instead.',
521 flatten (key, obj, flatOptions) {
522 definitions.omit.flatten('omit', obj, flatOptions)
523 },
524 }),
525 diff: new Definition('diff', {
526 default: [],
527 hint: '<package-spec>',
528 type: [String, Array],
529 description: `
530 Define arguments to compare in \`npm diff\`.
531 `,
532 flatten,
533 }),
534 'diff-ignore-all-space': new Definition('diff-ignore-all-space', {
535 default: false,
536 type: Boolean,
537 description: `
538 Ignore whitespace when comparing lines in \`npm diff\`.
539 `,
540 flatten,
541 }),
542 'diff-name-only': new Definition('diff-name-only', {
543 default: false,
544 type: Boolean,
545 description: `
546 Prints only filenames when using \`npm diff\`.
547 `,
548 flatten,
549 }),
550 'diff-no-prefix': new Definition('diff-no-prefix', {
551 default: false,
552 type: Boolean,
553 description: `
554 Do not show any source or destination prefix in \`npm diff\` output.
555
556 Note: this causes \`npm diff\` to ignore the \`--diff-src-prefix\` and
557 \`--diff-dst-prefix\` configs.
558 `,
559 flatten,
560 }),
561 'diff-dst-prefix': new Definition('diff-dst-prefix', {
562 default: 'b/',
563 hint: '<path>',
564 type: String,
565 description: `
566 Destination prefix to be used in \`npm diff\` output.
567 `,
568 flatten,
569 }),
570 'diff-src-prefix': new Definition('diff-src-prefix', {
571 default: 'a/',
572 hint: '<path>',
573 type: String,
574 description: `
575 Source prefix to be used in \`npm diff\` output.
576 `,
577 flatten,
578 }),
579 'diff-text': new Definition('diff-text', {
580 default: false,
581 type: Boolean,
582 description: `
583 Treat all files as text in \`npm diff\`.
584 `,
585 flatten,
586 }),
587 'diff-unified': new Definition('diff-unified', {
588 default: 3,
589 type: Number,
590 description: `
591 The number of lines of context to print in \`npm diff\`.
592 `,
593 flatten,
594 }),
595 'dry-run': new Definition('dry-run', {
596 default: false,
597 type: Boolean,
598 description: `
599 Indicates that you don't want npm to make any changes and that it should
600 only report what it would have done. This can be passed into any of the
601 commands that modify your local installation, eg, \`install\`,
602 \`update\`, \`dedupe\`, \`uninstall\`, as well as \`pack\` and
603 \`publish\`.
604
605 Note: This is NOT honored by other network related commands, eg
606 \`dist-tags\`, \`owner\`, etc.
607 `,
608 flatten,
609 }),
610 editor: new Definition('editor', {
611 default: editor,
612 defaultDescription: `
613 The EDITOR or VISUAL environment variables, or '%SYSTEMROOT%\\notepad.exe' on Windows,
614 or 'vi' on Unix systems
615 `,
616 type: String,
617 description: `
618 The command to run for \`npm edit\` and \`npm config edit\`.
619 `,
620 flatten,
621 }),
622 'engine-strict': new Definition('engine-strict', {
623 default: false,
624 type: Boolean,
625 description: `
626 If set to true, then npm will stubbornly refuse to install (or even
627 consider installing) any package that claims to not be compatible with
628 the current Node.js version.
629
630 This can be overridden by setting the \`--force\` flag.
631 `,
632 flatten,
633 }),
634 'expect-result-count': new Definition('expect-result-count', {
635 default: null,
636 type: [null, Number],
637 hint: '<count>',
638 exclusive: ['expect-results'],
639 description: `
640 Tells to expect a specific number of results from the command.
641 `,
642 }),
643 'expect-results': new Definition('expect-results', {
644 default: null,
645 type: [null, Boolean],
646 exclusive: ['expect-result-count'],
647 description: `
648 Tells npm whether or not to expect results from the command.
649 Can be either true (expect some results) or false (expect no results).
650 `,
651 }),
652 expires: new Definition('expires', {
653 default: null,
654 type: [null, Number],
655 description: `
656 When creating a Granular Access Token with \`npm token create\`,
657 this sets the expiration in days. If not specified, the server
658 will determine the default expiration.
659 `,
660 flatten,
661 }),
662 'fetch-retries': new Definition('fetch-retries', {
663 default: 2,
664 type: Number,
665 description: `
666 The "retries" config for the \`retry\` module to use when fetching
667 packages from the registry.
668
669 npm will retry idempotent read requests to the registry in the case
670 of network failures or 5xx HTTP errors.
671 `,
672 flatten (key, obj, flatOptions) {
673 flatOptions.retry = flatOptions.retry || {}
674 flatOptions.retry.retries = obj[key]
675 },
676 }),
677 'fetch-retry-factor': new Definition('fetch-retry-factor', {
678 default: 10,
679 type: Number,
680 description: `
681 The "factor" config for the \`retry\` module to use when fetching
682 packages.
683 `,
684 flatten (key, obj, flatOptions) {
685 flatOptions.retry = flatOptions.retry || {}
686 flatOptions.retry.factor = obj[key]
687 },
688 }),
689 'fetch-retry-maxtimeout': new Definition('fetch-retry-maxtimeout', {
690 default: 60000,
691 defaultDescription: '60000 (1 minute)',
692 type: Number,
693 description: `
694 The "maxTimeout" config for the \`retry\` module to use when fetching
695 packages.
696 `,
697 flatten (key, obj, flatOptions) {
698 flatOptions.retry = flatOptions.retry || {}
699 flatOptions.retry.maxTimeout = obj[key]
700 },
701 }),
702 'fetch-retry-mintimeout': new Definition('fetch-retry-mintimeout', {
703 default: 10000,
704 defaultDescription: '10000 (10 seconds)',
705 type: Number,
706 description: `
707 The "minTimeout" config for the \`retry\` module to use when fetching
708 packages.
709 `,
710 flatten (key, obj, flatOptions) {
711 flatOptions.retry = flatOptions.retry || {}
712 flatOptions.retry.minTimeout = obj[key]
713 },
714 }),
715 'fetch-timeout': new Definition('fetch-timeout', {
716 default: 5 * 60 * 1000,
717 defaultDescription: `${5 * 60 * 1000} (5 minutes)`,
718 type: Number,
719 description: `
720 The maximum amount of time to wait for HTTP requests to complete.
721 `,
722 flatten (key, obj, flatOptions) {
723 flatOptions.timeout = obj[key]
724 },
725 }),
726 force: new Definition('force', {
727 default: false,
728 type: Boolean,
729 short: 'f',
730 description: `
731 Removes various protections against unfortunate side effects, common
732 mistakes, unnecessary performance degradation, and malicious input.
733
734 * Allow clobbering non-npm files in global installs.
735 * Allow the \`npm version\` command to work on an unclean git repository.
736 * Allow deleting the cache folder with \`npm cache clean\`.
737 * Allow installing packages that have an \`engines\` declaration
738 requiring a different version of npm.
739 * Allow installing packages that have an \`engines\` declaration
740 requiring a different version of \`node\`, even if \`--engine-strict\`
741 is enabled.
742 * Allow \`npm audit fix\` to install modules outside your stated
743 dependency range (including SemVer-major changes).
744 * Allow unpublishing all versions of a published package.
745 * Allow conflicting peerDependencies to be installed in the root project.
746 * Implicitly set \`--yes\` during \`npm init\`.
747 * Allow clobbering existing values in \`npm pkg\`
748 * Allow unpublishing of entire packages (not just a single version).
749
750 If you don't have a clear idea of what you want to do, it is strongly
751 recommended that you do not use this option!
752 `,
753 flatten,
754 }),
755 'foreground-scripts': new Definition('foreground-scripts', {
756 default: false,
757 defaultDescription: `\`false\` unless when using \`npm pack\` or \`npm publish\` where it
758 defaults to \`true\``,
759 type: Boolean,
760 description: `
761 Run all build scripts (ie, \`preinstall\`, \`install\`, and
762 \`postinstall\`) scripts for installed packages in the foreground
763 process, sharing standard input, output, and error with the main npm
764 process.
765
766 Note that this will generally make installs run slower, and be much
767 noisier, but can be useful for debugging.
768 `,
769 flatten,
770 }),
771 'format-package-lock': new Definition('format-package-lock', {
772 default: true,
773 type: Boolean,
774 description: `
775 Format \`package-lock.json\` or \`npm-shrinkwrap.json\` as a human
776 readable file.
777 `,
778 flatten,
779 }),
780 fund: new Definition('fund', {
781 default: true,
782 type: Boolean,
783 description: `
784 When "true" displays the message at the end of each \`npm install\`
785 acknowledging the number of dependencies looking for funding.
786 See [\`npm fund\`](/commands/npm-fund) for details.
787 `,
788 flatten,
789 }),
790 git: new Definition('git', {
791 default: 'git',
792 type: String,
793 description: `
794 The command to use for git commands. If git is installed on the
795 computer, but is not in the \`PATH\`, then set this to the full path to
796 the git binary.
797 `,
798 flatten,
799 }),
800 'git-tag-version': new Definition('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 global: new Definition('global', {
810 default: false,
811 type: Boolean,
812 short: 'g',
813 description: `
814 Operates in "global" mode, so that packages are installed into the
815 \`prefix\` folder instead of the current working directory. See
816 [folders](/configuring-npm/folders) for more on the differences in
817 behavior.
818
819 * packages are installed into the \`{prefix}/lib/node_modules\` folder,
820 instead of the current working directory.
821 * bin files are linked to \`{prefix}/bin\`
822 * man pages are linked to \`{prefix}/share/man\`
823 `,
824 flatten: (key, obj, flatOptions) => {
825 flatten(key, obj, flatOptions)
826 if (flatOptions.global) {
827 flatOptions.location = 'global'
828 }
829 },
830 }),
831 // the globalconfig has its default defined outside of this module
832 globalconfig: new Definition('globalconfig', {
833 type: path,
834 default: '',
835 defaultDescription: `
836 The global --prefix setting plus 'etc/npmrc'. For example,
837 '/usr/local/etc/npmrc'
838 `,
839 description: `
840 The config file to read for global config options.
841 `,
842 flatten,
843 }),
844 'global-style': new Definition('global-style', {
845 default: false,
846 type: Boolean,
847 description: `
848 Only install direct dependencies in the top level \`node_modules\`,
849 but hoist on deeper dependencies.
850 Sets \`--install-strategy=shallow\`.
851 `,
852 deprecated: `
853 This option has been deprecated in favor of \`--install-strategy=shallow\`
854 `,
855 flatten (key, obj, flatOptions) {
856 if (obj[key]) {
857 obj['install-strategy'] = 'shallow'
858 flatOptions.installStrategy = 'shallow'
859 }
860 },
861 }),
862 heading: new Definition('heading', {
863 default: 'npm',
864 type: String,
865 description: `
866 The string that starts all the debugging log output.
867 `,
868 flatten,
869 }),
870 'https-proxy': new Definition('https-proxy', {
871 default: null,
872 type: [null, url],
873 description: `
874 A proxy to use for outgoing https requests. If the \`HTTPS_PROXY\` or
875 \`https_proxy\` or \`HTTP_PROXY\` or \`http_proxy\` environment variables
876 are set, proxy settings will be honored by the underlying
877 \`make-fetch-happen\` library.
878 `,
879 flatten,
880 }),
881 'if-present': new Definition('if-present', {
882 default: false,
883 type: Boolean,
884 envExport: false,
885 description: `
886 If true, npm will not exit with an error code when \`run\` is
887 invoked for a script that isn't defined in the \`scripts\` section of
888 \`package.json\`. This option can be used when it's desirable to
889 optionally run a script when it's present and fail if the script fails.
890 This is useful, for example, when running scripts that may only apply for
891 some builds in an otherwise generic CI setup.
892 `,
893 flatten,
894 }),
895 'ignore-scripts': new Definition('ignore-scripts', {
896 default: false,
897 type: Boolean,
898 description: `
899 If true, npm does not run scripts specified in package.json files.
900
901 Note that commands explicitly intended to run a particular script, such
902 as \`npm start\`, \`npm stop\`, \`npm restart\`, \`npm test\`, and \`npm
903 run\` will still run their intended script if \`ignore-scripts\` is
904 set, but they will *not* run any pre- or post-scripts.
905 `,
906 flatten,
907 }),
908 include: new Definition('include', {
909 default: [],
910 type: [Array, 'prod', 'dev', 'optional', 'peer'],
911 description: `
912 Option that allows for defining which types of dependencies to install.
913
914 This is the inverse of \`--omit=<type>\`.
915
916 Dependency types specified in \`--include\` will not be omitted,
917 regardless of the order in which omit/include are specified on the
918 command-line.
919 `,
920 flatten (key, obj, flatOptions) {
921 // just call the omit flattener, it reads from obj.include
922 definitions.omit.flatten('omit', obj, flatOptions)
923 },
924 }),
925 'include-staged': new Definition('include-staged', {
926 default: false,
927 type: Boolean,
928 description: `
929 Allow installing "staged" published packages, as defined by [npm RFC PR
930 #92](https://github.com/npm/rfcs/pull/92).
931
932 This is experimental, and not implemented by the npm public registry.
933 `,
934 flatten,
935 }),
936 'include-workspace-root': new Definition('include-workspace-root', {
937 default: false,
938 type: Boolean,
939 envExport: false,
940 description: `
941 Include the workspace root when workspaces are enabled for a command.
942
943 When false, specifying individual workspaces via the \`workspace\` config,
944 or all workspaces via the \`workspaces\` flag, will cause npm to operate only
945 on the specified workspaces, and not on the root project.
946 `,
947 flatten,
948 }),
949 'include-attestations': new Definition('include-attestations', {
950 default: false,
951 type: Boolean,
952 description: `
953 When used with \`npm audit signatures --json\`, includes the full
954 sigstore attestation bundles in the JSON output for each verified
955 package. The bundles contain DSSE envelopes, verification material,
956 and transparency log entries.
957 `,
958 flatten,
959 }),
960 'init-author-email': new Definition('init-author-email', {
961 default: '',
962 hint: '<email>',
963 type: String,
964 description: `
965 The value \`npm init\` should use by default for the package author's
966 email.
967 `,
968 }),
969 'init-author-name': new Definition('init-author-name', {
970 default: '',
971 hint: '<name>',
972 type: String,
973 description: `
974 The value \`npm init\` should use by default for the package author's name.
975 `,
976 }),
977 'init-author-url': new Definition('init-author-url', {
978 default: '',
979 type: ['', url],
980 hint: '<url>',
981 description: `
982 The value \`npm init\` should use by default for the package author's homepage.
983 `,
984 }),
985 'init-license': new Definition('init-license', {
986 default: 'ISC',
987 hint: '<license>',
988 type: String,
989 description: `
990 The value \`npm init\` should use by default for the package license.
991 `,
992 }),
993 'init-module': new Definition('init-module', {
994 default: '~/.npm-init.js',
995 type: path,
996 hint: '<module>',
997 description: `
998 A module that will be loaded by the \`npm init\` command. See the
999 documentation for the
1000 [init-package-json](https://github.com/npm/init-package-json) module for
1001 more information, or [npm init](/commands/npm-init).
1002 `,
1003 }),
1004 'init-type': new Definition('init-type', {
1005 default: 'commonjs',
1006 type: String,
1007 hint: '<type>',
1008 description: `
1009 The value that \`npm init\` should use by default for the package.json type field.
1010 `,
1011 }),
1012 'init-version': new Definition('init-version', {
1013 default: '1.0.0',
1014 type: Semver,
1015 hint: '<version>',
1016 description: `
1017 The value that \`npm init\` should use by default for the package
1018 version number, if not already set in package.json.
1019 `,
1020 }),
1021 'init-private': new Definition('init-private', {
1022 default: false,
1023 type: Boolean,
1024 description: `
1025 The value \`npm init\` should use by default for the package's private flag.
1026 `,
1027 flatten,
1028 }),
1029 // these "aliases" are historically supported in .npmrc files, unfortunately
1030 // They should be removed in a future npm version.
1031 'init.author.email': new Definition('init.author.email', {
1032 default: '',
1033 type: String,
1034 deprecated: `
1035 Use \`--init-author-email\` instead.`,
1036 description: `
1037 Alias for \`--init-author-email\`
1038 `,
1039 }),
1040 'init.author.name': new Definition('init.author.name', {
1041 default: '',
1042 type: String,
1043 deprecated: `
1044 Use \`--init-author-name\` instead.
1045 `,
1046 description: `
1047 Alias for \`--init-author-name\`
1048 `,
1049 }),
1050 'init.author.url': new Definition('init.author.url', {
1051 default: '',
1052 type: ['', url],
1053 deprecated: `
1054 Use \`--init-author-url\` instead.
1055 `,
1056 description: `
1057 Alias for \`--init-author-url\`
1058 `,
1059 }),
1060 'init.license': new Definition('init.license', {
1061 default: 'ISC',
1062 type: String,
1063 deprecated: `
1064 Use \`--init-license\` instead.
1065 `,
1066 description: `
1067 Alias for \`--init-license\`
1068 `,
1069 }),
1070 'init.module': new Definition('init.module', {
1071 default: '~/.npm-init.js',
1072 type: path,
1073 deprecated: `
1074 Use \`--init-module\` instead.
1075 `,
1076 description: `
1077 Alias for \`--init-module\`
1078 `,
1079 }),
1080 'init.version': new Definition('init.version', {
1081 default: '1.0.0',
1082 type: Semver,
1083 deprecated: `
1084 Use \`--init-version\` instead.
1085 `,
1086 description: `
1087 Alias for \`--init-version\`
1088 `,
1089 }),
1090 'install-links': new Definition('install-links', {
1091 default: false,
1092 type: Boolean,
1093 description: `
1094 When set file: protocol dependencies will be packed and installed as
1095 regular dependencies instead of creating a symlink. This option has
1096 no effect on workspaces.
1097 `,
1098 flatten,
1099 }),
1100 'install-strategy': new Definition('install-strategy', {
1101 default: 'hoisted',
1102 type: ['hoisted', 'nested', 'shallow', 'linked'],
1103 description: `
1104 Sets the strategy for installing packages in node_modules.
1105 hoisted (default): Install non-duplicated in top-level, and duplicated as
1106 necessary within directory structure.
1107 nested: (formerly --legacy-bundling) install in place, no hoisting.
1108 shallow (formerly --global-style) only install direct deps at top-level.
1109 linked: (experimental) install in node_modules/.store, link in place,
1110 unhoisted.
1111 `,
1112 flatten,
1113 }),
1114 json: new Definition('json', {
1115 default: false,
1116 type: Boolean,
1117 description: `
1118 Whether or not to output JSON data, rather than the normal output.
1119
1120 * In \`npm pkg set\` it enables parsing set values with JSON.parse()
1121 before saving them to your \`package.json\`.
1122
1123 Not supported by all npm commands.
1124 `,
1125 flatten,
1126 }),
1127 key: new Definition('key', {
1128 default: null,
1129 type: [null, String],
1130 description: `
1131 A client key to pass when accessing the registry. Values should be in
1132 PEM format with newlines replaced by the string "\\n". For example:
1133
1134 \`\`\`ini
1135 key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----"
1136 \`\`\`
1137
1138 It is _not_ the path to a key file, though you can set a registry-scoped
1139 "keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem".
1140 `,
1141 deprecated: `
1142 \`key\` and \`cert\` are no longer used for most registry operations.
1143 Use registry scoped \`keyfile\` and \`certfile\` instead.
1144 Example:
1145 //other-registry.tld/:keyfile=/path/to/key.pem
1146 //other-registry.tld/:certfile=/path/to/cert.crt
1147 `,
1148 flatten,
1149 }),
1150 'legacy-bundling': new Definition('legacy-bundling', {
1151 default: false,
1152 type: Boolean,
1153 description: `
1154 Instead of hoisting package installs in \`node_modules\`, install packages
1155 in the same manner that they are depended on. This may cause very deep
1156 directory structures and duplicate package installs as there is no
1157 de-duplicating.
1158 Sets \`--install-strategy=nested\`.
1159 `,
1160 deprecated: `
1161 This option has been deprecated in favor of \`--install-strategy=nested\`
1162 `,
1163 flatten (key, obj, flatOptions) {
1164 if (obj[key]) {
1165 obj['install-strategy'] = 'nested'
1166 flatOptions.installStrategy = 'nested'
1167 }
1168 },
1169 }),
1170 'legacy-peer-deps': new Definition('legacy-peer-deps', {
1171 default: false,
1172 type: Boolean,
1173 description: `
1174 Causes npm to completely ignore \`peerDependencies\` when building a
1175 package tree, as in npm versions 3 through 6.
1176
1177 If a package cannot be installed because of overly strict
1178 \`peerDependencies\` that collide, it provides a way to move forward
1179 resolving the situation.
1180
1181 This differs from \`--omit=peer\`, in that \`--omit=peer\` will avoid
1182 unpacking \`peerDependencies\` on disk, but will still design a tree such
1183 that \`peerDependencies\` _could_ be unpacked in a correct place.
1184
1185 Use of \`legacy-peer-deps\` is not recommended, as it will not enforce
1186 the \`peerDependencies\` contract that meta-dependencies may rely on.
1187 `,
1188 flatten,
1189 }),
1190 libc: new Definition('libc', {
1191 default: null,
1192 type: [null, String],
1193 description: `
1194 Override libc of native modules to install.
1195 Acceptable values are same as \`libc\` field of package.json
1196 `,
1197 flatten,
1198 }),
1199 link: new Definition('link', {
1200 default: false,
