diff --git a/packages/@vue/cli/lib/util/ProjectPackageManager.js b/packages/@vue/cli/lib/util/ProjectPackageManager.js index 73cd6d5c6e..a5063f494a 100644 --- a/packages/@vue/cli/lib/util/ProjectPackageManager.js +++ b/packages/@vue/cli/lib/util/ProjectPackageManager.js @@ -1,6 +1,7 @@ const fs = require('fs-extra') const path = require('path') +const ini = require('ini') const minimist = require('minimist') const LRU = require('lru-cache') @@ -154,6 +155,38 @@ class PackageManager { return this._registry } + async getAuthToken () { + // get npmrc (https://docs.npmjs.com/configuring-npm/npmrc.html#files) + const possibleRcPaths = [ + path.resolve(this.context, '.npmrc'), + path.resolve(require('os').homedir(), '.npmrc') + ] + if (process.env.PREFIX) { + possibleRcPaths.push(path.resolve(process.env.PREFIX, '/etc/npmrc')) + } + // there's also a '/path/to/npm/npmrc', skipped for simplicity of implementation + + let npmConfig = {} + for (const loc of possibleRcPaths) { + if (fs.existsSync(loc)) { + try { + // the closer config file (the one with lower index) takes higher precedence + npmConfig = Object.assign({}, ini.parse(fs.readFileSync(loc, 'utf-8')), npmConfig) + } catch (e) { + // in case of file permission issues, etc. + } + } + } + + const registry = await this.getRegistry() + const registryWithoutProtocol = registry + .replace(/https?:/, '') // remove leading protocol + .replace(/([^/])$/, '$1/') // ensure ending with slash + const authTokenKey = `${registryWithoutProtocol}:_authToken` + + return npmConfig[authTokenKey] + } + async setRegistryEnvs () { const registry = await this.getRegistry() @@ -204,6 +237,7 @@ class PackageManager { // https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md async getMetadata (packageName, { full = false } = {}) { const registry = await this.getRegistry() + const authToken = await this.getAuthToken() const metadataKey = `${this.bin}-${registry}-${packageName}` let metadata = metadataCache.get(metadataKey) @@ -217,6 +251,10 @@ class PackageManager { headers.Accept = 'application/vnd.npm.install-v1+json' } + if (authToken) { + headers.Authorization = `Bearer ${authToken}` + } + const url = `${registry.replace(/\/$/g, '')}/${packageName}` try { metadata = (await request.get(url, { headers })).body diff --git a/packages/@vue/cli/package.json b/packages/@vue/cli/package.json index 8106d9eadd..d893a1bb52 100644 --- a/packages/@vue/cli/package.json +++ b/packages/@vue/cli/package.json @@ -39,6 +39,7 @@ "fs-extra": "^7.0.1", "globby": "^9.2.0", "import-global": "^0.1.0", + "ini": "^1.3.5", "inquirer": "^7.1.0", "isbinaryfile": "^4.0.6", "javascript-stringify": "^1.6.0",