update
This commit is contained in:
20
package/node_modules/npm-registry-fetch/LICENSE.md
generated
vendored
Normal file
20
package/node_modules/npm-registry-fetch/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- This file is automatically added by @npmcli/template-oss. Do not edit. -->
|
||||
|
||||
ISC License
|
||||
|
||||
Copyright npm, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this
|
||||
software for any purpose with or without fee is hereby
|
||||
granted, provided that the above copyright notice and this
|
||||
permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
|
||||
USE OR PERFORMANCE OF THIS SOFTWARE.
|
181
package/node_modules/npm-registry-fetch/lib/auth.js
generated
vendored
Normal file
181
package/node_modules/npm-registry-fetch/lib/auth.js
generated
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
'use strict'
|
||||
const fs = require('fs')
|
||||
const npa = require('npm-package-arg')
|
||||
const { URL } = require('url')
|
||||
|
||||
// Find the longest registry key that is used for some kind of auth
|
||||
// in the options. Returns the registry key and the auth config.
|
||||
const regFromURI = (uri, opts) => {
|
||||
const parsed = new URL(uri)
|
||||
// try to find a config key indicating we have auth for this registry
|
||||
// can be one of :_authToken, :_auth, :_password and :username, or
|
||||
// :certfile and :keyfile
|
||||
// We walk up the "path" until we're left with just //<host>[:<port>],
|
||||
// stopping when we reach '//'.
|
||||
let regKey = `//${parsed.host}${parsed.pathname}`
|
||||
while (regKey.length > '//'.length) {
|
||||
const authKey = hasAuth(regKey, opts)
|
||||
// got some auth for this URI
|
||||
if (authKey) {
|
||||
return { regKey, authKey }
|
||||
}
|
||||
|
||||
// can be either //host/some/path/:_auth or //host/some/path:_auth
|
||||
// walk up by removing EITHER what's after the slash OR the slash itself
|
||||
regKey = regKey.replace(/([^/]+|\/)$/, '')
|
||||
}
|
||||
return { regKey: false, authKey: null }
|
||||
}
|
||||
|
||||
// Not only do we want to know if there is auth, but if we are calling `npm
|
||||
// logout` we want to know what config value specifically provided it. This is
|
||||
// so we can look up where the config came from to delete it (i.e. user vs
|
||||
// project)
|
||||
const hasAuth = (regKey, opts) => {
|
||||
if (opts[`${regKey}:_authToken`]) {
|
||||
return '_authToken'
|
||||
}
|
||||
if (opts[`${regKey}:_auth`]) {
|
||||
return '_auth'
|
||||
}
|
||||
if (opts[`${regKey}:username`] && opts[`${regKey}:_password`]) {
|
||||
// 'password' can be inferred to also be present
|
||||
return 'username'
|
||||
}
|
||||
if (opts[`${regKey}:certfile`] && opts[`${regKey}:keyfile`]) {
|
||||
// 'keyfile' can be inferred to also be present
|
||||
return 'certfile'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const sameHost = (a, b) => {
|
||||
const parsedA = new URL(a)
|
||||
const parsedB = new URL(b)
|
||||
return parsedA.host === parsedB.host
|
||||
}
|
||||
|
||||
const getRegistry = opts => {
|
||||
const { spec } = opts
|
||||
const { scope: specScope, subSpec } = spec ? npa(spec) : {}
|
||||
const subSpecScope = subSpec && subSpec.scope
|
||||
const scope = subSpec ? subSpecScope : specScope
|
||||
const scopeReg = scope && opts[`${scope}:registry`]
|
||||
return scopeReg || opts.registry
|
||||
}
|
||||
|
||||
const maybeReadFile = file => {
|
||||
try {
|
||||
return fs.readFileSync(file, 'utf8')
|
||||
} catch (er) {
|
||||
if (er.code !== 'ENOENT') {
|
||||
throw er
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const getAuth = (uri, opts = {}) => {
|
||||
const { forceAuth } = opts
|
||||
if (!uri) {
|
||||
throw new Error('URI is required')
|
||||
}
|
||||
const { regKey, authKey } = regFromURI(uri, forceAuth || opts)
|
||||
|
||||
// we are only allowed to use what's in forceAuth if specified
|
||||
if (forceAuth && !regKey) {
|
||||
return new Auth({
|
||||
// if we force auth we don't want to refer back to anything in config
|
||||
regKey: false,
|
||||
authKey: null,
|
||||
scopeAuthKey: null,
|
||||
token: forceAuth._authToken || forceAuth.token,
|
||||
username: forceAuth.username,
|
||||
password: forceAuth._password || forceAuth.password,
|
||||
auth: forceAuth._auth || forceAuth.auth,
|
||||
certfile: forceAuth.certfile,
|
||||
keyfile: forceAuth.keyfile,
|
||||
})
|
||||
}
|
||||
|
||||
// no auth for this URI, but might have it for the registry
|
||||
if (!regKey) {
|
||||
const registry = getRegistry(opts)
|
||||
if (registry && uri !== registry && sameHost(uri, registry)) {
|
||||
return getAuth(registry, opts)
|
||||
} else if (registry !== opts.registry) {
|
||||
// If making a tarball request to a different base URI than the
|
||||
// registry where we logged in, but the same auth SHOULD be sent
|
||||
// to that artifact host, then we track where it was coming in from,
|
||||
// and warn the user if we get a 4xx error on it.
|
||||
const { regKey: scopeAuthKey, authKey: _authKey } = regFromURI(registry, opts)
|
||||
return new Auth({ scopeAuthKey, regKey: scopeAuthKey, authKey: _authKey })
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
[`${regKey}:_authToken`]: token,
|
||||
[`${regKey}:username`]: username,
|
||||
[`${regKey}:_password`]: password,
|
||||
[`${regKey}:_auth`]: auth,
|
||||
[`${regKey}:certfile`]: certfile,
|
||||
[`${regKey}:keyfile`]: keyfile,
|
||||
} = opts
|
||||
|
||||
return new Auth({
|
||||
scopeAuthKey: null,
|
||||
regKey,
|
||||
authKey,
|
||||
token,
|
||||
auth,
|
||||
username,
|
||||
password,
|
||||
certfile,
|
||||
keyfile,
|
||||
})
|
||||
}
|
||||
|
||||
class Auth {
|
||||
constructor ({
|
||||
token,
|
||||
auth,
|
||||
username,
|
||||
password,
|
||||
scopeAuthKey,
|
||||
certfile,
|
||||
keyfile,
|
||||
regKey,
|
||||
authKey,
|
||||
}) {
|
||||
// same as regKey but only present for scoped auth. Should have been named scopeRegKey
|
||||
this.scopeAuthKey = scopeAuthKey
|
||||
// `${regKey}:${authKey}` will get you back to the auth config that gave us auth
|
||||
this.regKey = regKey
|
||||
this.authKey = authKey
|
||||
this.token = null
|
||||
this.auth = null
|
||||
this.isBasicAuth = false
|
||||
this.cert = null
|
||||
this.key = null
|
||||
if (token) {
|
||||
this.token = token
|
||||
} else if (auth) {
|
||||
this.auth = auth
|
||||
} else if (username && password) {
|
||||
const p = Buffer.from(password, 'base64').toString('utf8')
|
||||
this.auth = Buffer.from(`${username}:${p}`, 'utf8').toString('base64')
|
||||
this.isBasicAuth = true
|
||||
}
|
||||
// mTLS may be used in conjunction with another auth method above
|
||||
if (certfile && keyfile) {
|
||||
const cert = maybeReadFile(certfile, 'utf-8')
|
||||
const key = maybeReadFile(keyfile, 'utf-8')
|
||||
if (cert && key) {
|
||||
this.cert = cert
|
||||
this.key = key
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = getAuth
|
100
package/node_modules/npm-registry-fetch/lib/check-response.js
generated
vendored
Normal file
100
package/node_modules/npm-registry-fetch/lib/check-response.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
'use strict'
|
||||
|
||||
const errors = require('./errors.js')
|
||||
const { Response } = require('minipass-fetch')
|
||||
const defaultOpts = require('./default-opts.js')
|
||||
const { log } = require('proc-log')
|
||||
const { redact: cleanUrl } = require('@npmcli/redact')
|
||||
|
||||
/* eslint-disable-next-line max-len */
|
||||
const moreInfoUrl = 'https://github.com/npm/cli/wiki/No-auth-for-URI,-but-auth-present-for-scoped-registry'
|
||||
const checkResponse =
|
||||
async ({ method, uri, res, startTime, auth, opts }) => {
|
||||
opts = { ...defaultOpts, ...opts }
|
||||
if (res.headers.has('npm-notice') && !res.headers.has('x-local-cache')) {
|
||||
log.notice('', res.headers.get('npm-notice'))
|
||||
}
|
||||
|
||||
if (res.status >= 400) {
|
||||
logRequest(method, res, startTime)
|
||||
if (auth && auth.scopeAuthKey && !auth.token && !auth.auth) {
|
||||
// we didn't have auth for THIS request, but we do have auth for
|
||||
// requests to the registry indicated by the spec's scope value.
|
||||
// Warn the user.
|
||||
log.warn('registry', `No auth for URI, but auth present for scoped registry.
|
||||
|
||||
URI: ${uri}
|
||||
Scoped Registry Key: ${auth.scopeAuthKey}
|
||||
|
||||
More info here: ${moreInfoUrl}`)
|
||||
}
|
||||
return checkErrors(method, res, startTime, opts)
|
||||
} else {
|
||||
res.body.on('end', () => logRequest(method, res, startTime, opts))
|
||||
if (opts.ignoreBody) {
|
||||
res.body.resume()
|
||||
return new Response(null, res)
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
||||
module.exports = checkResponse
|
||||
|
||||
function logRequest (method, res, startTime) {
|
||||
const elapsedTime = Date.now() - startTime
|
||||
const attempt = res.headers.get('x-fetch-attempts')
|
||||
const attemptStr = attempt && attempt > 1 ? ` attempt #${attempt}` : ''
|
||||
const cacheStatus = res.headers.get('x-local-cache-status')
|
||||
const cacheStr = cacheStatus ? ` (cache ${cacheStatus})` : ''
|
||||
const urlStr = cleanUrl(res.url)
|
||||
|
||||
log.http(
|
||||
'fetch',
|
||||
`${method.toUpperCase()} ${res.status} ${urlStr} ${elapsedTime}ms${attemptStr}${cacheStr}`
|
||||
)
|
||||
}
|
||||
|
||||
function checkErrors (method, res, startTime, opts) {
|
||||
return res.buffer()
|
||||
.catch(() => null)
|
||||
.then(body => {
|
||||
let parsed = body
|
||||
try {
|
||||
parsed = JSON.parse(body.toString('utf8'))
|
||||
} catch {
|
||||
// ignore errors
|
||||
}
|
||||
if (res.status === 401 && res.headers.get('www-authenticate')) {
|
||||
const auth = res.headers.get('www-authenticate')
|
||||
.split(/,\s*/)
|
||||
.map(s => s.toLowerCase())
|
||||
if (auth.indexOf('ipaddress') !== -1) {
|
||||
throw new errors.HttpErrorAuthIPAddress(
|
||||
method, res, parsed, opts.spec
|
||||
)
|
||||
} else if (auth.indexOf('otp') !== -1) {
|
||||
throw new errors.HttpErrorAuthOTP(
|
||||
method, res, parsed, opts.spec
|
||||
)
|
||||
} else {
|
||||
throw new errors.HttpErrorAuthUnknown(
|
||||
method, res, parsed, opts.spec
|
||||
)
|
||||
}
|
||||
} else if (
|
||||
res.status === 401 &&
|
||||
body != null &&
|
||||
/one-time pass/.test(body.toString('utf8'))
|
||||
) {
|
||||
// Heuristic for malformed OTP responses that don't include the
|
||||
// www-authenticate header.
|
||||
throw new errors.HttpErrorAuthOTP(
|
||||
method, res, parsed, opts.spec
|
||||
)
|
||||
} else {
|
||||
throw new errors.HttpErrorGeneral(
|
||||
method, res, parsed, opts.spec
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
19
package/node_modules/npm-registry-fetch/lib/default-opts.js
generated
vendored
Normal file
19
package/node_modules/npm-registry-fetch/lib/default-opts.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
const pkg = require('../package.json')
|
||||
module.exports = {
|
||||
maxSockets: 12,
|
||||
method: 'GET',
|
||||
registry: 'https://registry.npmjs.org/',
|
||||
timeout: 5 * 60 * 1000, // 5 minutes
|
||||
strictSSL: true,
|
||||
noProxy: process.env.NOPROXY,
|
||||
userAgent: `${pkg.name
|
||||
}@${
|
||||
pkg.version
|
||||
}/node@${
|
||||
process.version
|
||||
}+${
|
||||
process.arch
|
||||
} (${
|
||||
process.platform
|
||||
})`,
|
||||
}
|
80
package/node_modules/npm-registry-fetch/lib/errors.js
generated
vendored
Normal file
80
package/node_modules/npm-registry-fetch/lib/errors.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
'use strict'
|
||||
|
||||
const { URL } = require('node:url')
|
||||
|
||||
function packageName (href) {
|
||||
try {
|
||||
let basePath = new URL(href).pathname.slice(1)
|
||||
if (!basePath.match(/^-/)) {
|
||||
basePath = basePath.split('/')
|
||||
var index = basePath.indexOf('_rewrite')
|
||||
if (index === -1) {
|
||||
index = basePath.length - 1
|
||||
} else {
|
||||
index++
|
||||
}
|
||||
return decodeURIComponent(basePath[index])
|
||||
}
|
||||
} catch {
|
||||
// this is ok
|
||||
}
|
||||
}
|
||||
|
||||
class HttpErrorBase extends Error {
|
||||
constructor (method, res, body, spec) {
|
||||
super()
|
||||
this.name = this.constructor.name
|
||||
this.headers = typeof res.headers?.raw === 'function' ? res.headers.raw() : res.headers
|
||||
this.statusCode = res.status
|
||||
this.code = `E${res.status}`
|
||||
this.method = method
|
||||
this.uri = res.url
|
||||
this.body = body
|
||||
this.pkgid = spec ? spec.toString() : packageName(res.url)
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
}
|
||||
}
|
||||
|
||||
class HttpErrorGeneral extends HttpErrorBase {
|
||||
constructor (method, res, body, spec) {
|
||||
super(method, res, body, spec)
|
||||
this.message = `${res.status} ${res.statusText} - ${
|
||||
this.method.toUpperCase()
|
||||
} ${
|
||||
this.spec || this.uri
|
||||
}${
|
||||
(body && body.error) ? ' - ' + body.error : ''
|
||||
}`
|
||||
}
|
||||
}
|
||||
|
||||
class HttpErrorAuthOTP extends HttpErrorBase {
|
||||
constructor (method, res, body, spec) {
|
||||
super(method, res, body, spec)
|
||||
this.message = 'OTP required for authentication'
|
||||
this.code = 'EOTP'
|
||||
}
|
||||
}
|
||||
|
||||
class HttpErrorAuthIPAddress extends HttpErrorBase {
|
||||
constructor (method, res, body, spec) {
|
||||
super(method, res, body, spec)
|
||||
this.message = 'Login is not allowed from your IP address'
|
||||
this.code = 'EAUTHIP'
|
||||
}
|
||||
}
|
||||
|
||||
class HttpErrorAuthUnknown extends HttpErrorBase {
|
||||
constructor (method, res, body, spec) {
|
||||
super(method, res, body, spec)
|
||||
this.message = 'Unable to authenticate, need: ' + res.headers.get('www-authenticate')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
HttpErrorBase,
|
||||
HttpErrorGeneral,
|
||||
HttpErrorAuthOTP,
|
||||
HttpErrorAuthIPAddress,
|
||||
HttpErrorAuthUnknown,
|
||||
}
|
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
|
||||
}
|
223
package/node_modules/npm-registry-fetch/lib/json-stream.js
generated
vendored
Normal file
223
package/node_modules/npm-registry-fetch/lib/json-stream.js
generated
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
const Parser = require('jsonparse')
|
||||
const { Minipass } = require('minipass')
|
||||
|
||||
class JSONStreamError extends Error {
|
||||
constructor (err, caller) {
|
||||
super(err.message)
|
||||
Error.captureStackTrace(this, caller || this.constructor)
|
||||
}
|
||||
|
||||
get name () {
|
||||
return 'JSONStreamError'
|
||||
}
|
||||
}
|
||||
|
||||
const check = (x, y) =>
|
||||
typeof x === 'string' ? String(y) === x
|
||||
: x && typeof x.test === 'function' ? x.test(y)
|
||||
: typeof x === 'boolean' || typeof x === 'object' ? x
|
||||
: typeof x === 'function' ? x(y)
|
||||
: false
|
||||
|
||||
class JSONStream extends Minipass {
|
||||
#count = 0
|
||||
#ending = false
|
||||
#footer = null
|
||||
#header = null
|
||||
#map = null
|
||||
#onTokenOriginal
|
||||
#parser
|
||||
#path = null
|
||||
#root = null
|
||||
|
||||
constructor (opts) {
|
||||
super({
|
||||
...opts,
|
||||
objectMode: true,
|
||||
})
|
||||
|
||||
const parser = this.#parser = new Parser()
|
||||
parser.onValue = value => this.#onValue(value)
|
||||
this.#onTokenOriginal = parser.onToken
|
||||
parser.onToken = (token, value) => this.#onToken(token, value)
|
||||
parser.onError = er => this.#onError(er)
|
||||
|
||||
this.#path = typeof opts.path === 'string'
|
||||
? opts.path.split('.').map(e =>
|
||||
e === '$*' ? { emitKey: true }
|
||||
: e === '*' ? true
|
||||
: e === '' ? { recurse: true }
|
||||
: e)
|
||||
: Array.isArray(opts.path) && opts.path.length ? opts.path
|
||||
: null
|
||||
|
||||
if (typeof opts.map === 'function') {
|
||||
this.#map = opts.map
|
||||
}
|
||||
}
|
||||
|
||||
#setHeaderFooter (key, value) {
|
||||
// header has not been emitted yet
|
||||
if (this.#header !== false) {
|
||||
this.#header = this.#header || {}
|
||||
this.#header[key] = value
|
||||
}
|
||||
|
||||
// footer has not been emitted yet but header has
|
||||
if (this.#footer !== false && this.#header === false) {
|
||||
this.#footer = this.#footer || {}
|
||||
this.#footer[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
#onError (er) {
|
||||
// error will always happen during a write() call.
|
||||
const caller = this.#ending ? this.end : this.write
|
||||
this.#ending = false
|
||||
return this.emit('error', new JSONStreamError(er, caller))
|
||||
}
|
||||
|
||||
#onToken (token, value) {
|
||||
const parser = this.#parser
|
||||
this.#onTokenOriginal.call(this.#parser, token, value)
|
||||
if (parser.stack.length === 0) {
|
||||
if (this.#root) {
|
||||
const root = this.#root
|
||||
if (!this.#path) {
|
||||
super.write(root)
|
||||
}
|
||||
this.#root = null
|
||||
this.#count = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#onValue (value) {
|
||||
const parser = this.#parser
|
||||
// the LAST onValue encountered is the root object.
|
||||
// just overwrite it each time.
|
||||
this.#root = value
|
||||
|
||||
if (!this.#path) {
|
||||
return
|
||||
}
|
||||
|
||||
let i = 0 // iterates on path
|
||||
let j = 0 // iterates on stack
|
||||
let emitKey = false
|
||||
while (i < this.#path.length) {
|
||||
const key = this.#path[i]
|
||||
j++
|
||||
|
||||
if (key && !key.recurse) {
|
||||
const c = (j === parser.stack.length) ? parser : parser.stack[j]
|
||||
if (!c) {
|
||||
return
|
||||
}
|
||||
if (!check(key, c.key)) {
|
||||
this.#setHeaderFooter(c.key, value)
|
||||
return
|
||||
}
|
||||
emitKey = !!key.emitKey
|
||||
i++
|
||||
} else {
|
||||
i++
|
||||
if (i >= this.#path.length) {
|
||||
return
|
||||
}
|
||||
const nextKey = this.#path[i]
|
||||
if (!nextKey) {
|
||||
return
|
||||
}
|
||||
while (true) {
|
||||
const c = (j === parser.stack.length) ? parser : parser.stack[j]
|
||||
if (!c) {
|
||||
return
|
||||
}
|
||||
if (check(nextKey, c.key)) {
|
||||
i++
|
||||
if (!Object.isFrozen(parser.stack[j])) {
|
||||
parser.stack[j].value = null
|
||||
}
|
||||
break
|
||||
} else {
|
||||
this.#setHeaderFooter(c.key, value)
|
||||
}
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit header
|
||||
if (this.#header) {
|
||||
const header = this.#header
|
||||
this.#header = false
|
||||
this.emit('header', header)
|
||||
}
|
||||
if (j !== parser.stack.length) {
|
||||
return
|
||||
}
|
||||
|
||||
this.#count++
|
||||
const actualPath = parser.stack.slice(1)
|
||||
.map(e => e.key).concat([parser.key])
|
||||
if (value !== null && value !== undefined) {
|
||||
const data = this.#map ? this.#map(value, actualPath) : value
|
||||
if (data !== null && data !== undefined) {
|
||||
const emit = emitKey ? { value: data } : data
|
||||
if (emitKey) {
|
||||
emit.key = parser.key
|
||||
}
|
||||
super.write(emit)
|
||||
}
|
||||
}
|
||||
|
||||
if (parser.value) {
|
||||
delete parser.value[parser.key]
|
||||
}
|
||||
|
||||
for (const k of parser.stack) {
|
||||
k.value = null
|
||||
}
|
||||
}
|
||||
|
||||
write (chunk, encoding) {
|
||||
if (typeof chunk === 'string') {
|
||||
chunk = Buffer.from(chunk, encoding)
|
||||
} else if (!Buffer.isBuffer(chunk)) {
|
||||
return this.emit('error', new TypeError(
|
||||
'Can only parse JSON from string or buffer input'))
|
||||
}
|
||||
this.#parser.write(chunk)
|
||||
return this.flowing
|
||||
}
|
||||
|
||||
end (chunk, encoding) {
|
||||
this.#ending = true
|
||||
if (chunk) {
|
||||
this.write(chunk, encoding)
|
||||
}
|
||||
|
||||
const h = this.#header
|
||||
this.#header = null
|
||||
const f = this.#footer
|
||||
this.#footer = null
|
||||
if (h) {
|
||||
this.emit('header', h)
|
||||
}
|
||||
if (f) {
|
||||
this.emit('footer', f)
|
||||
}
|
||||
return super.end()
|
||||
}
|
||||
|
||||
static get JSONStreamError () {
|
||||
return JSONStreamError
|
||||
}
|
||||
|
||||
static parse (path, map) {
|
||||
return new JSONStream({ path, map })
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JSONStream
|
68
package/node_modules/npm-registry-fetch/package.json
generated
vendored
Normal file
68
package/node_modules/npm-registry-fetch/package.json
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "npm-registry-fetch",
|
||||
"version": "17.1.0",
|
||||
"description": "Fetch-based http client for use with npm registry APIs",
|
||||
"main": "lib",
|
||||
"files": [
|
||||
"bin/",
|
||||
"lib/"
|
||||
],
|
||||
"scripts": {
|
||||
"eslint": "eslint",
|
||||
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
|
||||
"lintfix": "npm run lint -- --fix",
|
||||
"test": "tap",
|
||||
"posttest": "npm run lint",
|
||||
"npmclilint": "npmcli-lint",
|
||||
"postsnap": "npm run lintfix --",
|
||||
"postlint": "template-oss-check",
|
||||
"snap": "tap",
|
||||
"template-oss-apply": "template-oss-apply --force"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/npm/npm-registry-fetch.git"
|
||||
},
|
||||
"keywords": [
|
||||
"npm",
|
||||
"registry",
|
||||
"fetch"
|
||||
],
|
||||
"author": "GitHub Inc.",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@npmcli/redact": "^2.0.0",
|
||||
"jsonparse": "^1.3.1",
|
||||
"make-fetch-happen": "^13.0.0",
|
||||
"minipass": "^7.0.2",
|
||||
"minipass-fetch": "^3.0.0",
|
||||
"minizlib": "^2.1.2",
|
||||
"npm-package-arg": "^11.0.0",
|
||||
"proc-log": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@npmcli/eslint-config": "^4.0.0",
|
||||
"@npmcli/template-oss": "4.22.0",
|
||||
"cacache": "^18.0.0",
|
||||
"nock": "^13.2.4",
|
||||
"require-inject": "^1.4.4",
|
||||
"ssri": "^10.0.0",
|
||||
"tap": "^16.0.1"
|
||||
},
|
||||
"tap": {
|
||||
"check-coverage": true,
|
||||
"test-ignore": "test[\\\\/](util|cache)[\\\\/]",
|
||||
"nyc-arg": [
|
||||
"--exclude",
|
||||
"tap-snapshots/**"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.14.0 || >=18.0.0"
|
||||
},
|
||||
"templateOSS": {
|
||||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
||||
"version": "4.22.0",
|
||||
"publish": "true"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user