@npmcli/config 10.6.0 → 10.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,6 +22,8 @@ const allowed = [
22
22
  'typeDescription',
23
23
  'usage',
24
24
  'envExport',
25
+ 'alias',
26
+ 'required',
25
27
  ]
26
28
 
27
29
  const {
@@ -246,6 +246,7 @@ const definitions = {
246
246
  default: null,
247
247
  hint: '<date>',
248
248
  type: [null, Date],
249
+ exclusive: ['min-release-age'],
249
250
  description: `
250
251
  If passed to \`npm install\`, will rebuild the npm tree such that only
251
252
  versions that were available **on or before** the given date are
@@ -1347,6 +1348,28 @@ const definitions = {
1347
1348
  `,
1348
1349
  flatten,
1349
1350
  }),
1351
+ 'min-release-age': new Definition('min-release-age', {
1352
+ default: null,
1353
+ hint: '<days>',
1354
+ type: [null, Number],
1355
+ exclusive: ['before'],
1356
+ description: `
1357
+ If set, npm will build the npm tree such that only versions that were
1358
+ available more than the given number of days ago will be installed. If
1359
+ there are no versions available for the current set of dependencies, the
1360
+ command will error.
1361
+
1362
+ This flag is a complement to \`before\`, which accepts an exact date
1363
+ instead of a relative number of days.
1364
+ `,
1365
+ flatten: (key, obj, flatOptions) => {
1366
+ if (obj['min-release-age'] !== null) {
1367
+ flatOptions.before = new Date(Date.now() - (86400000 * obj['min-release-age']))
1368
+ obj.before = flatOptions.before
1369
+ delete obj['min-release-age']
1370
+ }
1371
+ },
1372
+ }),
1350
1373
  'node-gyp': new Definition('node-gyp', {
1351
1374
  default: (() => {
1352
1375
  try {
package/lib/index.js CHANGED
@@ -59,6 +59,7 @@ class Config {
59
59
  #flatten
60
60
  // populated the first time we flatten the object
61
61
  #flatOptions = null
62
+ #warnings = []
62
63
 
63
64
  static get typeDefs () {
64
65
  return typeDefs
@@ -78,20 +79,13 @@ class Config {
78
79
  execPath = process.execPath,
79
80
  cwd = process.cwd(),
80
81
  excludeNpmCwd = false,
82
+ warn = true,
81
83
  }) {
82
84
  this.nerfDarts = nerfDarts
83
85
  this.definitions = definitions
84
86
  // turn the definitions into nopt's weirdo syntax
85
- const types = {}
86
- const defaults = {}
87
- this.deprecated = {}
88
- for (const [key, def] of Object.entries(definitions)) {
89
- defaults[key] = def.default
90
- types[key] = def.type
91
- if (def.deprecated) {
92
- this.deprecated[key] = def.deprecated.trim().replace(/\n +/, '\n')
93
- }
94
- }
87
+ const { types, defaults, deprecated } = getTypesFromDefinitions(definitions)
88
+ this.deprecated = deprecated
95
89
 
96
90
  this.#flatten = flatten
97
91
  this.types = types
@@ -137,6 +131,7 @@ class Config {
137
131
  }
138
132
 
139
133
  this.#loaded = false
134
+ this.warn = warn
140
135
  }
141
136
 
142
137
  get list () {
@@ -369,7 +364,7 @@ class Config {
369
364
  }
370
365
  nopt.invalidHandler = (k, val, type) =>
371
366
  this.invalidHandler(k, val, type, 'command line options', 'cli')
372
- nopt.unknownHandler = this.unknownHandler
367
+ nopt.unknownHandler = (k, next) => this.unknownHandler(k, next)
373
368
  nopt.abbrevHandler = this.abbrevHandler
374
369
  const conf = nopt(this.types, this.shorthands, this.argv)
375
370
  nopt.invalidHandler = null
@@ -545,7 +540,7 @@ class Config {
545
540
 
546
541
  unknownHandler (key, next) {
547
542
  if (next) {
548
- log.warn(`"${next}" is being parsed as a normal command line argument.`)
543
+ this.queueWarning(`unknown:${next}`, `"${next}" is being parsed as a normal command line argument.`)
549
544
  }
550
545
  }
551
546
 
@@ -613,13 +608,16 @@ class Config {
613
608
  if (internalEnv.includes(key)) {
614
609
  return
615
610
  }
611
+ const hint = where !== 'cli'
612
+ ? ' See `npm help npmrc` for supported config options.'
613
+ : ''
616
614
  if (!key.includes(':')) {
617
- log.warn(`Unknown ${where} config "${where === 'cli' ? '--' : ''}${key}". This will stop working in the next major version of npm.`)
615
+ this.queueWarning(key, `Unknown ${where} config "${where === 'cli' ? '--' : ''}${key}". This will stop working in the next major version of npm.${hint}`)
618
616
  return
619
617
  }
620
618
  const baseKey = key.split(':').pop()
621
619
  if (!this.definitions[baseKey] && !this.nerfDarts.includes(baseKey)) {
622
- log.warn(`Unknown ${where} config "${baseKey}" (${key}). This will stop working in the next major version of npm.`)
620
+ this.queueWarning(baseKey, `Unknown ${where} config "${baseKey}" (${key}). This will stop working in the next major version of npm.${hint}`)
623
621
  }
624
622
  }
625
623
  }
@@ -923,6 +921,35 @@ class Config {
923
921
  setEnvs () {
924
922
  setEnvs(this)
925
923
  }
924
+
925
+ removeWarning (key) {
926
+ this.#warnings = this.#warnings.filter(w => w.type !== key)
927
+ }
928
+
929
+ getUnknownPositionals () {
930
+ return this.#warnings
931
+ .filter(w => w.type.startsWith('unknown:'))
932
+ .map(w => w.type.slice('unknown:'.length))
933
+ }
934
+
935
+ removeUnknownPositional (value) {
936
+ this.removeWarning(`unknown:${value}`)
937
+ }
938
+
939
+ queueWarning (type, ...args) {
940
+ if (!this.warn) {
941
+ this.#warnings.push({ type, args })
942
+ } else {
943
+ log.warn(...args)
944
+ }
945
+ }
946
+
947
+ logWarnings () {
948
+ for (const warning of this.#warnings) {
949
+ log.warn(...warning.args)
950
+ }
951
+ this.#warnings = []
952
+ }
926
953
  }
927
954
 
928
955
  const _loadError = Symbol('loadError')
@@ -980,4 +1007,21 @@ class ConfigData {
980
1007
  }
981
1008
  }
982
1009
 
1010
+ const getTypesFromDefinitions = (definitions) => {
1011
+ const types = {}
1012
+ const defaults = {}
1013
+ const deprecated = {}
1014
+
1015
+ for (const [key, def] of Object.entries(definitions)) {
1016
+ defaults[key] = def.default
1017
+ types[key] = def.type
1018
+ if (def.deprecated) {
1019
+ deprecated[key] = def.deprecated.trim().replace(/\n +/, '\n')
1020
+ }
1021
+ }
1022
+
1023
+ return { types, defaults, deprecated }
1024
+ }
1025
+
983
1026
  module.exports = Config
1027
+ module.exports.getTypesFromDefinitions = getTypesFromDefinitions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/config",
3
- "version": "10.6.0",
3
+ "version": "10.7.1",
4
4
  "files": [
5
5
  "bin/",
6
6
  "lib/"
@@ -33,7 +33,7 @@
33
33
  "devDependencies": {
34
34
  "@npmcli/eslint-config": "^5.0.1",
35
35
  "@npmcli/mock-globals": "^1.0.0",
36
- "@npmcli/template-oss": "4.25.1",
36
+ "@npmcli/template-oss": "4.29.0",
37
37
  "tap": "^16.3.8"
38
38
  },
39
39
  "dependencies": {
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "templateOSS": {
53
53
  "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
54
- "version": "4.25.1",
54
+ "version": "4.29.0",
55
55
  "content": "../../scripts/template-oss/index.js"
56
56
  }
57
57
  }