diff --git a/__tests__/registries/npm-registry.js b/__tests__/registries/npm-registry.js index 85dfdf9ebb..bf28d7321e 100644 --- a/__tests__/registries/npm-registry.js +++ b/__tests__/registries/npm-registry.js @@ -254,7 +254,7 @@ describe('isRequestToRegistry functional test', () => { const packageIdents = [ ['normal', ''], ['@scopedNoPkg', ''], - ['@scoped/notescaped', ''], + ['@scoped/notescaped', '@scoped'], ['not@scope/pkg', ''], ['@scope?query=true', ''], ['@scope%2fpkg', '@scope'], @@ -263,13 +263,15 @@ const packageIdents = [ ['@scope%2fpkg%2f1.2.3', '@scope'], ['http://foo.bar:80/normal', ''], ['http://foo.bar:80/@scopedNoPkg', ''], - ['http://foo.bar:80/@scoped/notescaped', ''], + ['http://foo.bar:80/@scoped/notescaped', '@scoped'], + ['http://foo.bar:80/@scoped/notescaped/download/@scoped/notescaped-1.0.0.tgz', '@scoped'], ['http://foo.bar:80/not@scope/pkg', ''], ['http://foo.bar:80/@scope?query=true', ''], ['http://foo.bar:80/@scope%2fpkg', '@scope'], ['http://foo.bar:80/@scope%2fpkg%2fext', '@scope'], ['http://foo.bar:80/@scope%2fpkg?query=true', '@scope'], ['http://foo.bar:80/@scope%2fpkg%2f1.2.3', '@scope'], + ['http://foo.bar:80/@scope%2fpkg/download/@scope%2fpkg-1.0.0.tgz', '@scope'], ]; describe('isScopedPackage functional test', () => { diff --git a/src/registries/npm-registry.js b/src/registries/npm-registry.js index 8e783ffef5..90879d9522 100644 --- a/src/registries/npm-registry.js +++ b/src/registries/npm-registry.js @@ -27,8 +27,11 @@ export const SCOPE_SEPARATOR = '%2f'; // All scoped package names are of the format `@scope%2fpkg` from the use of NpmRegistry.escapeName // `(?:^|\/)` Match either the start of the string or a `/` but don't capture // `[^\/?]+?` Match any character that is not '/' or '?' and capture, up until the first occurance of: -// `%2f` Match SCOPE_SEPARATOR, the escaped '/', and don't capture -const SCOPED_PKG_REGEXP = /(?:^|\/)(@[^\/?]+?)(?=%2f)/; +// `(?=%2f|\/)` Match SCOPE_SEPARATOR, the escaped '/', or a raw `/` and don't capture +// The reason for matching a plain `/` is NPM registry being inconsistent about escaping `/` in +// scoped package names: when you're fetching a tarball, it is not escaped, when you want info +// about the package, it is escaped. +const SCOPED_PKG_REGEXP = /(?:^|\/)(@[^\/?]+?)(?=%2f|\/)/; // TODO: Use the method from src/cli/commands/global.js for this instead function getGlobalPrefix(): string {