update
This commit is contained in:
247
package/node_modules/npm-registry-fetch/lib/index.js
generated
vendored
Normal file
247
package/node_modules/npm-registry-fetch/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
'use strict'
|
||||
|
||||
const { HttpErrorAuthOTP } = require('./errors.js')
|
||||
const checkResponse = require('./check-response.js')
|
||||
const getAuth = require('./auth.js')
|
||||
const fetch = require('make-fetch-happen')
|
||||
const JSONStream = require('./json-stream')
|
||||
const npa = require('npm-package-arg')
|
||||
const qs = require('querystring')
|
||||
const url = require('url')
|
||||
const zlib = require('minizlib')
|
||||
const { Minipass } = require('minipass')
|
||||
|
||||
const defaultOpts = require('./default-opts.js')
|
||||
|
||||
// WhatWG URL throws if it's not fully resolved
|
||||
const urlIsValid = u => {
|
||||
try {
|
||||
return !!new url.URL(u)
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = regFetch
|
||||
function regFetch (uri, /* istanbul ignore next */ opts_ = {}) {
|
||||
const opts = {
|
||||
...defaultOpts,
|
||||
...opts_,
|
||||
}
|
||||
|
||||
// if we did not get a fully qualified URI, then we look at the registry
|
||||
// config or relevant scope to resolve it.
|
||||
const uriValid = urlIsValid(uri)
|
||||
let registry = opts.registry || defaultOpts.registry
|
||||
if (!uriValid) {
|
||||
registry = opts.registry = (
|
||||
(opts.spec && pickRegistry(opts.spec, opts)) ||
|
||||
opts.registry ||
|
||||
registry
|
||||
)
|
||||
uri = `${
|
||||
registry.trim().replace(/\/?$/g, '')
|
||||
}/${
|
||||
uri.trim().replace(/^\//, '')
|
||||
}`
|
||||
// asserts that this is now valid
|
||||
new url.URL(uri)
|
||||
}
|
||||
|
||||
const method = opts.method || 'GET'
|
||||
|
||||
// through that takes into account the scope, the prefix of `uri`, etc
|
||||
const startTime = Date.now()
|
||||
const auth = getAuth(uri, opts)
|
||||
const headers = getHeaders(uri, auth, opts)
|
||||
let body = opts.body
|
||||
const bodyIsStream = Minipass.isStream(body)
|
||||
const bodyIsPromise = body &&
|
||||
typeof body === 'object' &&
|
||||
typeof body.then === 'function'
|
||||
|
||||
if (
|
||||
body && !bodyIsStream && !bodyIsPromise && typeof body !== 'string' && !Buffer.isBuffer(body)
|
||||
) {
|
||||
headers['content-type'] = headers['content-type'] || 'application/json'
|
||||
body = JSON.stringify(body)
|
||||
} else if (body && !headers['content-type']) {
|
||||
headers['content-type'] = 'application/octet-stream'
|
||||
}
|
||||
|
||||
if (opts.gzip) {
|
||||
headers['content-encoding'] = 'gzip'
|
||||
if (bodyIsStream) {
|
||||
const gz = new zlib.Gzip()
|
||||
body.on('error', /* istanbul ignore next: unlikely and hard to test */
|
||||
err => gz.emit('error', err))
|
||||
body = body.pipe(gz)
|
||||
} else if (!bodyIsPromise) {
|
||||
body = new zlib.Gzip().end(body).concat()
|
||||
}
|
||||
}
|
||||
|
||||
const parsed = new url.URL(uri)
|
||||
|
||||
if (opts.query) {
|
||||
const q = typeof opts.query === 'string' ? qs.parse(opts.query)
|
||||
: opts.query
|
||||
|
||||
Object.keys(q).forEach(key => {
|
||||
if (q[key] !== undefined) {
|
||||
parsed.searchParams.set(key, q[key])
|
||||
}
|
||||
})
|
||||
uri = url.format(parsed)
|
||||
}
|
||||
|
||||
if (parsed.searchParams.get('write') === 'true' && method === 'GET') {
|
||||
// do not cache, because this GET is fetching a rev that will be
|
||||
// used for a subsequent PUT or DELETE, so we need to conditionally
|
||||
// update cache.
|
||||
opts.offline = false
|
||||
opts.preferOffline = false
|
||||
opts.preferOnline = true
|
||||
}
|
||||
|
||||
const doFetch = async fetchBody => {
|
||||
const p = fetch(uri, {
|
||||
agent: opts.agent,
|
||||
algorithms: opts.algorithms,
|
||||
body: fetchBody,
|
||||
cache: getCacheMode(opts),
|
||||
cachePath: opts.cache,
|
||||
ca: opts.ca,
|
||||
cert: auth.cert || opts.cert,
|
||||
headers,
|
||||
integrity: opts.integrity,
|
||||
key: auth.key || opts.key,
|
||||
localAddress: opts.localAddress,
|
||||
maxSockets: opts.maxSockets,
|
||||
memoize: opts.memoize,
|
||||
method: method,
|
||||
noProxy: opts.noProxy,
|
||||
proxy: opts.httpsProxy || opts.proxy,
|
||||
retry: opts.retry ? opts.retry : {
|
||||
retries: opts.fetchRetries,
|
||||
factor: opts.fetchRetryFactor,
|
||||
minTimeout: opts.fetchRetryMintimeout,
|
||||
maxTimeout: opts.fetchRetryMaxtimeout,
|
||||
},
|
||||
strictSSL: opts.strictSSL,
|
||||
timeout: opts.timeout || 30 * 1000,
|
||||
}).then(res => checkResponse({
|
||||
method,
|
||||
uri,
|
||||
res,
|
||||
registry,
|
||||
startTime,
|
||||
auth,
|
||||
opts,
|
||||
}))
|
||||
|
||||
if (typeof opts.otpPrompt === 'function') {
|
||||
return p.catch(async er => {
|
||||
if (er instanceof HttpErrorAuthOTP) {
|
||||
let otp
|
||||
// if otp fails to complete, we fail with that failure
|
||||
try {
|
||||
otp = await opts.otpPrompt()
|
||||
} catch (_) {
|
||||
// ignore this error
|
||||
}
|
||||
// if no otp provided, or otpPrompt errored, throw the original HTTP error
|
||||
if (!otp) {
|
||||
throw er
|
||||
}
|
||||
return regFetch(uri, { ...opts, otp })
|
||||
}
|
||||
throw er
|
||||
})
|
||||
} else {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve(body).then(doFetch)
|
||||
}
|
||||
|
||||
module.exports.getAuth = getAuth
|
||||
|
||||
module.exports.json = fetchJSON
|
||||
function fetchJSON (uri, opts) {
|
||||
return regFetch(uri, opts).then(res => res.json())
|
||||
}
|
||||
|
||||
module.exports.json.stream = fetchJSONStream
|
||||
function fetchJSONStream (uri, jsonPath,
|
||||
/* istanbul ignore next */ opts_ = {}) {
|
||||
const opts = { ...defaultOpts, ...opts_ }
|
||||
const parser = JSONStream.parse(jsonPath, opts.mapJSON)
|
||||
regFetch(uri, opts).then(res =>
|
||||
res.body.on('error',
|
||||
/* istanbul ignore next: unlikely and difficult to test */
|
||||
er => parser.emit('error', er)).pipe(parser)
|
||||
).catch(er => parser.emit('error', er))
|
||||
return parser
|
||||
}
|
||||
|
||||
module.exports.pickRegistry = pickRegistry
|
||||
function pickRegistry (spec, opts = {}) {
|
||||
spec = npa(spec)
|
||||
let registry = spec.scope &&
|
||||
opts[spec.scope.replace(/^@?/, '@') + ':registry']
|
||||
|
||||
if (!registry && opts.scope) {
|
||||
registry = opts[opts.scope.replace(/^@?/, '@') + ':registry']
|
||||
}
|
||||
|
||||
if (!registry) {
|
||||
registry = opts.registry || defaultOpts.registry
|
||||
}
|
||||
|
||||
return registry
|
||||
}
|
||||
|
||||
function getCacheMode (opts) {
|
||||
return opts.offline ? 'only-if-cached'
|
||||
: opts.preferOffline ? 'force-cache'
|
||||
: opts.preferOnline ? 'no-cache'
|
||||
: 'default'
|
||||
}
|
||||
|
||||
function getHeaders (uri, auth, opts) {
|
||||
const headers = Object.assign({
|
||||
'user-agent': opts.userAgent,
|
||||
}, opts.headers || {})
|
||||
|
||||
if (opts.authType) {
|
||||
headers['npm-auth-type'] = opts.authType
|
||||
}
|
||||
|
||||
if (opts.scope) {
|
||||
headers['npm-scope'] = opts.scope
|
||||
}
|
||||
|
||||
if (opts.npmSession) {
|
||||
headers['npm-session'] = opts.npmSession
|
||||
}
|
||||
|
||||
if (opts.npmCommand) {
|
||||
headers['npm-command'] = opts.npmCommand
|
||||
}
|
||||
|
||||
// If a tarball is hosted on a different place than the manifest, only send
|
||||
// credentials on `alwaysAuth`
|
||||
if (auth.token) {
|
||||
headers.authorization = `Bearer ${auth.token}`
|
||||
} else if (auth.auth) {
|
||||
headers.authorization = `Basic ${auth.auth}`
|
||||
}
|
||||
|
||||
if (opts.otp) {
|
||||
headers['npm-otp'] = opts.otp
|
||||
}
|
||||
|
||||
return headers
|
||||
}
|
Reference in New Issue
Block a user