Skip to content

Commit e5544b1

Browse files
committed
refactor(verify-auth): apply memoization directly to npm-whoami calls
1 parent ac7ffc8 commit e5544b1

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ async function verifyConditions(pluginConfig, context) {
3232
const pkg = await getPkg(pluginConfig, context);
3333

3434
// Verify the npm authentication only if `npmPublish` is not false and `pkg.private` is not `true`
35-
if (!verified && pluginConfig.npmPublish !== false && pkg.private !== true) {
35+
if (pluginConfig.npmPublish !== false && pkg.private !== true) {
3636
await verifyNpmAuth(npmrc, pkg, context);
3737
}
3838
} catch (error) {

lib/verify-auth.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const getError = require('./get-error');
55
const getRegistry = require('./get-registry');
66
const setNpmrcAuth = require('./set-npmrc-auth');
77

8+
const memo = {};
9+
810
module.exports = async (npmrc, pkg, context) => {
911
const {
1012
cwd,
@@ -17,12 +19,20 @@ module.exports = async (npmrc, pkg, context) => {
1719
await setNpmrcAuth(npmrc, registry, context);
1820

1921
if (normalizeUrl(registry) === normalizeUrl(DEFAULT_NPM_REGISTRY)) {
22+
const key = npmrc + registry;
23+
if (memo[key]) {
24+
return memo[key];
25+
}
26+
2027
try {
2128
const whoamiResult = execa('npm', ['whoami', '--userconfig', npmrc, '--registry', registry], {cwd, env});
2229
whoamiResult.stdout.pipe(stdout, {end: false});
2330
whoamiResult.stderr.pipe(stderr, {end: false});
31+
32+
memo[key] = whoamiResult;
2433
await whoamiResult;
2534
} catch {
35+
memo[key] = undefined;
2636
throw new AggregateError([getError('EINVALIDNPMTOKEN', {registry})]);
2737
}
2838
}

test/verify-auth.test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const test = require('ava');
2+
const {stub} = require('sinon');
3+
const tempy = require('tempy');
4+
5+
const getRegistryPath = require.resolve('../lib/get-registry');
6+
const verifyAuthPath = require.resolve('../lib/verify-auth');
7+
const setNmprcAuthPath = require.resolve('../lib/set-npmrc-auth');
8+
const execaPath = require.resolve('execa');
9+
10+
const resetModuleCache = () => {
11+
require.cache[getRegistryPath] = undefined;
12+
require.cache[verifyAuthPath] = undefined;
13+
require.cache[setNmprcAuthPath] = undefined;
14+
require.cache[execaPath] = undefined;
15+
};
16+
17+
test.before(resetModuleCache);
18+
test.after(resetModuleCache);
19+
20+
test('Verify `npm-whoami` calls memoization', async (t) => {
21+
const pkg = {};
22+
const context = {cwd: tempy.directory(), env: {}};
23+
const fakeExeca = stub().returns({stdout: {pipe() {}}, stderr: {pipe() {}}});
24+
25+
require.cache[getRegistryPath] = {id: getRegistryPath, exports: () => 'https://registry.npmjs.org/'};
26+
require.cache[setNmprcAuthPath] = {id: setNmprcAuthPath, exports: () => {}};
27+
require.cache[execaPath] = {id: execaPath, exports: fakeExeca};
28+
29+
const verifyAuth = require('../lib/verify-auth');
30+
31+
await verifyAuth('foo', pkg, context);
32+
await verifyAuth('foo', pkg, context);
33+
await verifyAuth('foo', pkg, context);
34+
35+
t.assert(fakeExeca.calledOnce);
36+
37+
fakeExeca.resetHistory();
38+
39+
await verifyAuth('foo', pkg, context);
40+
await verifyAuth('bar', pkg, context);
41+
42+
t.assert(fakeExeca.calledTwice);
43+
});

0 commit comments

Comments
 (0)