Skip to content

Commit d2963c6

Browse files
nlffritzy
authored andcommitted
feat: explicitly validate config within the cli
BREAKING CHANGE: the presence of auth related settings that are not scoped to a specific registry found in a config file is no longer supported and will throw errors
1 parent cee3fd9 commit d2963c6

19 files changed

+68
-54
lines changed

lib/base-command.js

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ class BaseCommand {
1111
constructor (npm) {
1212
this.wrapWidth = 80
1313
this.npm = npm
14+
15+
if (!this.skipConfigValidation) {
16+
this.npm.config.validate()
17+
}
1418
}
1519

1620
get name () {
@@ -25,6 +29,10 @@ class BaseCommand {
2529
return this.constructor.ignoreImplicitWorkspace
2630
}
2731

32+
get skipConfigValidation () {
33+
return this.constructor.skipConfigValidation
34+
}
35+
2836
get usage () {
2937
const usage = [
3038
`${this.constructor.description}`,

lib/commands/config.js

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class Config extends BaseCommand {
6363

6464
static ignoreImplicitWorkspace = false
6565

66+
static skipConfigValidation = true
67+
6668
async completion (opts) {
6769
const argv = opts.conf.argv.remain
6870
if (argv[1] !== 'config') {

tap-snapshots/test/lib/utils/exit-handler.js.test.cjs

+28-28
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,34 @@
77
'use strict'
88
exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and debug file > debug file contents 1`] = `
99
0 timing npm:load:whichnode Completed in {TIME}ms
10-
15 timing config:load Completed in {TIME}ms
11-
16 timing npm:load:configload Completed in {TIME}ms
12-
17 timing npm:load:mkdirpcache Completed in {TIME}ms
13-
18 timing npm:load:mkdirplogs Completed in {TIME}ms
14-
19 verbose title npm
15-
20 verbose argv
16-
21 timing npm:load:setTitle Completed in {TIME}ms
17-
23 timing npm:load:display Completed in {TIME}ms
18-
24 verbose logfile logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-
19-
25 verbose logfile {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
20-
26 timing npm:load:logFile Completed in {TIME}ms
21-
27 timing npm:load:timers Completed in {TIME}ms
22-
28 timing npm:load:configScope Completed in {TIME}ms
23-
29 timing npm:load Completed in {TIME}ms
24-
30 silly logfile done cleaning log files
25-
31 verbose stack Error: Unknown error
26-
32 verbose cwd {CWD}
27-
33 verbose Foo 1.0.0
28-
34 verbose node v1.0.0
29-
35 verbose npm v1.0.0
30-
36 error code ECODE
31-
37 error ERR SUMMARY Unknown error
32-
38 error ERR DETAIL Unknown error
33-
39 verbose exit 1
34-
41 timing npm Completed in {TIME}ms
35-
42 verbose code 1
36-
43 error A complete log of this run can be found in:
37-
43 error {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
10+
13 timing config:load Completed in {TIME}ms
11+
14 timing npm:load:configload Completed in {TIME}ms
12+
15 timing npm:load:mkdirpcache Completed in {TIME}ms
13+
16 timing npm:load:mkdirplogs Completed in {TIME}ms
14+
17 verbose title npm
15+
18 verbose argv
16+
19 timing npm:load:setTitle Completed in {TIME}ms
17+
21 timing npm:load:display Completed in {TIME}ms
18+
22 verbose logfile logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-
19+
23 verbose logfile {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
20+
24 timing npm:load:logFile Completed in {TIME}ms
21+
25 timing npm:load:timers Completed in {TIME}ms
22+
26 timing npm:load:configScope Completed in {TIME}ms
23+
27 timing npm:load Completed in {TIME}ms
24+
28 silly logfile done cleaning log files
25+
29 verbose stack Error: Unknown error
26+
30 verbose cwd {CWD}
27+
31 verbose Foo 1.0.0
28+
32 verbose node v1.0.0
29+
33 verbose npm v1.0.0
30+
34 error code ECODE
31+
35 error ERR SUMMARY Unknown error
32+
36 error ERR DETAIL Unknown error
33+
37 verbose exit 1
34+
39 timing npm Completed in {TIME}ms
35+
40 verbose code 1
36+
41 error A complete log of this run can be found in:
37+
41 error {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
3838
`
3939

4040
exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and debug file > logs 1`] = `

test/fixtures/mock-npm.js

+1
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ class MockNpm {
216216
}
217217
},
218218
list: [{ ...realConfig.defaults, ...config }],
219+
validate: () => {},
219220
}
220221

221222
if (t && config.loglevel) {

test/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ t.test('loading as main module will load the cli', t => {
1111
const cwd = t.testdir()
1212
const { spawn } = require('child_process')
1313
const LS = require('../lib/commands/ls.js')
14-
const ls = new LS({})
14+
const ls = new LS({ config: { validate: () => {} } })
1515
const p = spawn(process.execPath, [index, 'ls', '-h', '--cache', cwd])
1616
const out = []
1717
p.stdout.on('data', c => out.push(c))

test/lib/arborist-cmd.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ t.test('arborist-cmd', async t => {
4444

4545
class TestCmd extends ArboristCmd {}
4646

47-
const cmd = new TestCmd()
48-
cmd.npm = { localPrefix: path }
47+
const cmd = new TestCmd({ localPrefix: path, config: { validate: () => {} } })
4948

5049
// check filtering for a single workspace name
5150
cmd.exec = async function (args) {
@@ -97,8 +96,7 @@ t.test('handle getWorkspaces raising an error', async t => {
9796
},
9897
})
9998
class TestCmd extends ArboristCmd {}
100-
const cmd = new TestCmd()
101-
cmd.npm = { localPrefix: t.testdir() }
99+
const cmd = new TestCmd({ localPrefix: t.testdir(), config: { validate: () => {} } })
102100

103101
await t.rejects(
104102
cmd.execWorkspaces(['foo'], ['a']),

test/lib/commands/adduser.js

-8
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,7 @@ t.test('legacy', async t => {
2727
const { npm, home } = await loadMockNpm(t, {
2828
config: { 'auth-type': 'legacy' },
2929
homeDir: {
30-
// These all get cleaned up by config.setCredentialsByURI
3130
'.npmrc': [
32-
'_token=user',
33-
'_password=user',
34-
'username=user',
35-
'_auth=user',
36-
'_authtoken=user',
37-
'-authtoken=user',
38-
'_authToken=user',
3931
'//registry.npmjs.org/:_authToken=user',
4032
'//registry.npmjs.org/:always-auth=user',
4133
'//registry.npmjs.org/:email=test-email-old@npmjs.org',

test/lib/commands/bugs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const Bugs = t.mock('../../../lib/commands/bugs.js', {
6262
'../../../lib/utils/open-url.js': openUrl,
6363
})
6464

65-
const bugs = new Bugs({ flatOptions: {} })
65+
const bugs = new Bugs({ flatOptions: {}, config: { validate: () => {} } })
6666

6767
t.test('usage', (t) => {
6868
t.match(bugs.usage, 'bugs', 'usage has command name in it')

test/lib/commands/explain.js

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ const npm = {
66
output: (...args) => {
77
OUTPUT.push(args)
88
},
9+
config: {
10+
validate: () => {},
11+
},
912
}
1013
const { resolve } = require('path')
1114

test/lib/commands/explore.js

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ const getExplore = (windows) => {
6767
output: out => {
6868
output.push(out)
6969
},
70+
config: {
71+
validate: () => {},
72+
},
7073
}
7174
return new Explore(npm)
7275
}

test/lib/commands/help.js

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const npm = {
1919
parsedArgv: {
2020
cooked: [],
2121
},
22+
validate: () => {},
2223
},
2324
exec: async (cmd, args) => {
2425
if (cmd === 'help-search') {

test/lib/commands/install-ci-test.js

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ const installCITest = new InstallCITest({
2323
testCalled = true
2424
}
2525
},
26+
config: {
27+
validate: () => {},
28+
},
2629
})
2730

2831
t.test('the install-ci-test command', t => {

test/lib/commands/install-test.js

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ const installTest = new InstallTest({
2323
testCalled = true
2424
}
2525
},
26+
config: {
27+
validate: () => {},
28+
},
2629
})
2730

2831
t.test('the install-test command', t => {

test/lib/commands/login.js

-8
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,7 @@ t.test('legacy', t => {
2626
const { npm, home } = await loadMockNpm(t, {
2727
config: { 'auth-type': 'legacy' },
2828
homeDir: {
29-
// These all get cleaned up by config.setCredentialsByURI
3029
'.npmrc': [
31-
'_token=user',
32-
'_password=user',
33-
'username=user',
34-
'_auth=user',
35-
'_authtoken=user',
36-
'-authtoken=user',
37-
'_authToken=user',
3830
'//registry.npmjs.org/:_authToken=user',
3931
'//registry.npmjs.org/:always-auth=user',
4032
'//registry.npmjs.org/:email=test-email-old@npmjs.org',

test/lib/commands/publish.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ t.test('dry-run', async t => {
190190
t.test('shows usage with wrong set of arguments', async t => {
191191
t.plan(1)
192192
const Publish = t.mock('../../../lib/commands/publish.js')
193-
const publish = new Publish({})
193+
const publish = new Publish({ config: { validate: () => {} } })
194194

195195
await t.rejects(publish.exec(['a', 'b', 'c']), publish.usage)
196196
})
@@ -637,7 +637,7 @@ t.test('ignore-scripts', async t => {
637637
t.test('_auth config default registry', async t => {
638638
const { npm, joinedOutput } = await loadMockNpm(t, {
639639
config: {
640-
_auth: basic,
640+
'//registry.npmjs.org/:_auth': basic,
641641
},
642642
prefixDir: {
643643
'package.json': JSON.stringify(pkgJson),
@@ -661,7 +661,7 @@ t.test('bare _auth and registry config', async t => {
661661
const { npm, joinedOutput } = await loadMockNpm(t, {
662662
config: {
663663
registry: alternateRegistry,
664-
_auth: basic,
664+
'//other.registry.npmjs.org/:_auth': basic,
665665
},
666666
prefixDir: {
667667
'package.json': JSON.stringify({

test/lib/commands/set.js

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ const npm = {
4040
configArgs = args
4141
}
4242
},
43+
config: {
44+
validate: () => {},
45+
},
4346
}
4447

4548
const Set = t.mock('../../../lib/commands/set.js')

test/lib/commands/stars.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ let result = ''
44

55
const noop = () => null
66
const npm = {
7-
config: { get () {} },
7+
config: { get () {}, validate: () => {} },
88
flatOptions: {},
99
output: (...msg) => {
1010
result = [result, ...msg].join('\n')

test/lib/commands/token.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const mocks = {
77
}
88
const npm = {
99
output: (...args) => mocks.output(...args),
10+
config: { validate: () => {} },
1011
}
1112

1213
const mockToken = (otherMocks) => t.mock('../../../lib/commands/token.js', {
@@ -21,6 +22,7 @@ const tokenWithMocks = (options = {}) => {
2122
for (const mod in mockRequests) {
2223
if (mod === 'npm') {
2324
mockRequests.npm = { ...npm, ...mockRequests.npm }
25+
mockRequests.npm.config.validate = () => {}
2426
} else {
2527
if (typeof mockRequests[mod] === 'function') {
2628
mocks[mod] = mockRequests[mod]

test/lib/lifecycle-cmd.js

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ const npm = {
88
return 'called the right thing'
99
}
1010
},
11+
config: {
12+
validate: () => {},
13+
},
1114
}
1215
t.test('create a lifecycle command', async t => {
1316
t.plan(5)

0 commit comments

Comments
 (0)