diff --git a/index.js b/index.js index 80a6ca9..994c1ba 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,7 @@ const zip = require('lodash.zip'); const validate = require('validate-npm-package-name'); const organizationRegex = require('org-regex')({exact: true}); const pMap = require('p-map'); +const {isTaken} = require('is-name-taken'); class InvalidNameError extends Error {} @@ -31,9 +32,10 @@ const request = async (name, options) => { throw error; } + let urlName = name; const isScopedPackage = isScoped(name); if (isScopedPackage) { - name = name.replace(/\//g, '%2f'); + urlName = name.replace(/\//g, '%2f'); } const authInfo = registryAuthToken(registryUrl, {recursive: true}); @@ -44,9 +46,9 @@ const request = async (name, options) => { try { if (isOrganization) { - await got.head(npmOrganizationUrl + name.toLowerCase(), {timeout: 10000}); + await got.head(npmOrganizationUrl + urlName.toLowerCase(), {timeout: 10000}); } else { - await got.head(registryUrl + name.toLowerCase(), {timeout: 10000, headers}); + await got.head(registryUrl + urlName.toLowerCase(), {timeout: 10000, headers}); } return false; @@ -54,6 +56,11 @@ const request = async (name, options) => { const {statusCode} = error.response; if (statusCode === 404) { + if (!isOrganization) { + const conflict = await isTaken(name.toLowerCase(), {maxAge: 60000}); + return !conflict; + } + return true; } diff --git a/package.json b/package.json index 11e4cd2..86d7974 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ ], "dependencies": { "got": "^10.6.0", + "is-name-taken": "^2.0.0", "is-scoped": "^2.1.0", "is-url-superb": "^4.0.0", "lodash.zip": "^4.2.0", diff --git a/test.js b/test.js index 9008907..9759038 100644 --- a/test.js +++ b/test.js @@ -27,6 +27,11 @@ test('returns false when package name is taken', async t => { t.false(await npmName('np', options)); }); +test('returns false when package name is taken, regardless of punctuation', async t => { + t.false(await npmName('ch-alk')); + t.false(await npmName('recursivereaddir')); +}); + test('returns false when organization name is taken', async t => { t.false(await npmName('@ava')); t.false(await npmName('@ava/'));