From edbc25a5980c34e0d28aac7503475cd33e07f7d2 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 11 Aug 2023 16:41:41 -0700 Subject: [PATCH] deps: pacote@16.0.0 --- mock-registry/package.json | 2 +- node_modules/.gitignore | 6 +- .../npm-registry-fetch/LICENSE.md | 0 .../npm-registry-fetch/lib/auth.js | 0 .../npm-registry-fetch/lib/check-response.js | 0 .../npm-registry-fetch/lib/clean-url.js | 0 .../npm-registry-fetch/lib/default-opts.js | 0 .../npm-registry-fetch/lib/errors.js | 0 .../npm-registry-fetch/lib/index.js | 0 .../npm-registry-fetch/package.json | 0 .../node_modules/pacote/LICENSE | 15 + .../node_modules/pacote/lib/bin.js | 158 +++ .../node_modules/pacote/lib/dir.js | 108 ++ .../node_modules/pacote/lib/fetcher.js | 505 ++++++++ .../node_modules/pacote/lib/file.js | 96 ++ .../node_modules/pacote/lib/git.js | 327 ++++++ .../node_modules/pacote/lib/index.js | 23 + .../node_modules/pacote/lib/registry.js | 344 ++++++ .../node_modules/pacote/lib/remote.js | 91 ++ .../pacote/lib/util/add-git-sha.js | 15 + .../node_modules/pacote/lib/util/cache-dir.js | 15 + .../pacote/lib/util/is-package-bin.js | 25 + .../node_modules/pacote/lib/util/npm.js | 14 + .../pacote/lib/util/tar-create-options.js | 31 + .../pacote/lib/util/trailing-slashes.js | 10 + .../node_modules/pacote/package.json | 79 ++ .../pacote/node_modules/minipass/LICENSE | 15 + .../node_modules/minipass/dist/cjs/index.js | 1028 +++++++++++++++++ .../minipass/dist/cjs/package.json | 3 + .../node_modules/minipass/dist/mjs/index.js | 1018 ++++++++++++++++ .../minipass/dist/mjs/package.json | 3 + .../pacote/node_modules/minipass/package.json | 82 ++ node_modules/pacote/package.json | 18 +- package-lock.json | 105 +- package.json | 2 +- workspaces/arborist/package.json | 2 +- workspaces/libnpmdiff/package.json | 2 +- workspaces/libnpmexec/package.json | 2 +- workspaces/libnpmpack/package.json | 2 +- 39 files changed, 4100 insertions(+), 46 deletions(-) rename node_modules/{pacote => @npmcli/metavuln-calculator}/node_modules/npm-registry-fetch/LICENSE.md (100%) rename node_modules/{pacote => @npmcli/metavuln-calculator}/node_modules/npm-registry-fetch/lib/auth.js (100%) rename node_modules/{pacote => @npmcli/metavuln-calculator}/node_modules/npm-registry-fetch/lib/check-response.js (100%) rename node_modules/{pacote => @npmcli/metavuln-calculator}/node_modules/npm-registry-fetch/lib/clean-url.js (100%) rename node_modules/{pacote => @npmcli/metavuln-calculator}/node_modules/npm-registry-fetch/lib/default-opts.js (100%) rename node_modules/{pacote => @npmcli/metavuln-calculator}/node_modules/npm-registry-fetch/lib/errors.js (100%) rename node_modules/{pacote => @npmcli/metavuln-calculator}/node_modules/npm-registry-fetch/lib/index.js (100%) rename node_modules/{pacote => @npmcli/metavuln-calculator}/node_modules/npm-registry-fetch/package.json (100%) create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/LICENSE create mode 100755 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/bin.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/dir.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/fetcher.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/file.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/git.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/index.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/registry.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/remote.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/add-git-sha.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/cache-dir.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/is-package-bin.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/npm.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/tar-create-options.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/trailing-slashes.js create mode 100644 node_modules/@npmcli/metavuln-calculator/node_modules/pacote/package.json create mode 100644 node_modules/pacote/node_modules/minipass/LICENSE create mode 100644 node_modules/pacote/node_modules/minipass/dist/cjs/index.js create mode 100644 node_modules/pacote/node_modules/minipass/dist/cjs/package.json create mode 100644 node_modules/pacote/node_modules/minipass/dist/mjs/index.js create mode 100644 node_modules/pacote/node_modules/minipass/dist/mjs/package.json create mode 100644 node_modules/pacote/node_modules/minipass/package.json diff --git a/mock-registry/package.json b/mock-registry/package.json index 530be56427040..8187bbe52b722 100644 --- a/mock-registry/package.json +++ b/mock-registry/package.json @@ -50,7 +50,7 @@ "json-stringify-safe": "^5.0.1", "nock": "^13.3.0", "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8", + "pacote": "^16.0.0", "tap": "^16.3.4" } } diff --git a/node_modules/.gitignore b/node_modules/.gitignore index 851e54092990b..069ee05e38167 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -25,6 +25,10 @@ !/@npmcli/installed-package-contents !/@npmcli/map-workspaces !/@npmcli/metavuln-calculator +!/@npmcli/metavuln-calculator/node_modules/ +/@npmcli/metavuln-calculator/node_modules/* +!/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch +!/@npmcli/metavuln-calculator/node_modules/pacote !/@npmcli/name-from-folder !/@npmcli/node-gyp !/@npmcli/package-json @@ -209,7 +213,7 @@ !/pacote !/pacote/node_modules/ /pacote/node_modules/* -!/pacote/node_modules/npm-registry-fetch +!/pacote/node_modules/minipass !/parse-conflict-json !/path-is-absolute !/path-key diff --git a/node_modules/pacote/node_modules/npm-registry-fetch/LICENSE.md b/node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/LICENSE.md similarity index 100% rename from node_modules/pacote/node_modules/npm-registry-fetch/LICENSE.md rename to node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/LICENSE.md diff --git a/node_modules/pacote/node_modules/npm-registry-fetch/lib/auth.js b/node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/auth.js similarity index 100% rename from node_modules/pacote/node_modules/npm-registry-fetch/lib/auth.js rename to node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/auth.js diff --git a/node_modules/pacote/node_modules/npm-registry-fetch/lib/check-response.js b/node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/check-response.js similarity index 100% rename from node_modules/pacote/node_modules/npm-registry-fetch/lib/check-response.js rename to node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/check-response.js diff --git a/node_modules/pacote/node_modules/npm-registry-fetch/lib/clean-url.js b/node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/clean-url.js similarity index 100% rename from node_modules/pacote/node_modules/npm-registry-fetch/lib/clean-url.js rename to node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/clean-url.js diff --git a/node_modules/pacote/node_modules/npm-registry-fetch/lib/default-opts.js b/node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/default-opts.js similarity index 100% rename from node_modules/pacote/node_modules/npm-registry-fetch/lib/default-opts.js rename to node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/default-opts.js diff --git a/node_modules/pacote/node_modules/npm-registry-fetch/lib/errors.js b/node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/errors.js similarity index 100% rename from node_modules/pacote/node_modules/npm-registry-fetch/lib/errors.js rename to node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/errors.js diff --git a/node_modules/pacote/node_modules/npm-registry-fetch/lib/index.js b/node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/index.js similarity index 100% rename from node_modules/pacote/node_modules/npm-registry-fetch/lib/index.js rename to node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/lib/index.js diff --git a/node_modules/pacote/node_modules/npm-registry-fetch/package.json b/node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/package.json similarity index 100% rename from node_modules/pacote/node_modules/npm-registry-fetch/package.json rename to node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch/package.json diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/LICENSE b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/LICENSE new file mode 100644 index 0000000000000..a03cd0ed0b338 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter, Kat Marchán, npm, Inc., and Contributors + +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 THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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. diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/bin.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/bin.js new file mode 100755 index 0000000000000..f35b62ca71a53 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/bin.js @@ -0,0 +1,158 @@ +#!/usr/bin/env node + +const run = conf => { + const pacote = require('../') + switch (conf._[0]) { + case 'resolve': + case 'manifest': + case 'packument': + if (conf._[0] === 'resolve' && conf.long) { + return pacote.manifest(conf._[1], conf).then(mani => ({ + resolved: mani._resolved, + integrity: mani._integrity, + from: mani._from, + })) + } + return pacote[conf._[0]](conf._[1], conf) + + case 'tarball': + if (!conf._[2] || conf._[2] === '-') { + return pacote.tarball.stream(conf._[1], stream => { + stream.pipe( + conf.testStdout || + /* istanbul ignore next */ + process.stdout + ) + // make sure it resolves something falsey + return stream.promise().then(() => { + return false + }) + }, conf) + } else { + return pacote.tarball.file(conf._[1], conf._[2], conf) + } + + case 'extract': + return pacote.extract(conf._[1], conf._[2], conf) + + default: /* istanbul ignore next */ { + throw new Error(`bad command: ${conf._[0]}`) + } + } +} + +const version = require('../package.json').version +const usage = () => +`Pacote - The JavaScript Package Handler, v${version} + +Usage: + + pacote resolve + Resolve a specifier and output the fully resolved target + Returns integrity and from if '--long' flag is set. + + pacote manifest + Fetch a manifest and print to stdout + + pacote packument + Fetch a full packument and print to stdout + + pacote tarball [] + Fetch a package tarball and save to + If is missing or '-', the tarball will be streamed to stdout. + + pacote extract + Extract a package to the destination folder. + +Configuration values all match the names of configs passed to npm, or +options passed to Pacote. Additional flags for this executable: + + --long Print an object from 'resolve', including integrity and spec. + --json Print result objects as JSON rather than node's default. + (This is the default if stdout is not a TTY.) + --help -h Print this helpful text. + +For example '--cache=/path/to/folder' will use that folder as the cache. +` + +const shouldJSON = (conf, result) => + conf.json || + !process.stdout.isTTY && + conf.json === undefined && + result && + typeof result === 'object' + +const pretty = (conf, result) => + shouldJSON(conf, result) ? JSON.stringify(result, 0, 2) : result + +let addedLogListener = false +const main = args => { + const conf = parse(args) + if (conf.help || conf.h) { + return console.log(usage()) + } + + if (!addedLogListener) { + process.on('log', console.error) + addedLogListener = true + } + + try { + return run(conf) + .then(result => result && console.log(pretty(conf, result))) + .catch(er => { + console.error(er) + process.exit(1) + }) + } catch (er) { + console.error(er.message) + console.error(usage()) + } +} + +const parseArg = arg => { + const split = arg.slice(2).split('=') + const k = split.shift() + const v = split.join('=') + const no = /^no-/.test(k) && !v + const key = (no ? k.slice(3) : k) + .replace(/^tag$/, 'defaultTag') + .replace(/-([a-z])/g, (_, c) => c.toUpperCase()) + const value = v ? v.replace(/^~/, process.env.HOME) : !no + return { key, value } +} + +const parse = args => { + const conf = { + _: [], + cache: process.env.HOME + '/.npm/_cacache', + } + let dashdash = false + args.forEach(arg => { + if (dashdash) { + conf._.push(arg) + } else if (arg === '--') { + dashdash = true + } else if (arg === '-h') { + conf.help = true + } else if (/^--/.test(arg)) { + const { key, value } = parseArg(arg) + conf[key] = value + } else { + conf._.push(arg) + } + }) + return conf +} + +if (module === require.main) { + main(process.argv.slice(2)) +} else { + module.exports = { + main, + run, + usage, + parseArg, + parse, + } +} diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/dir.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/dir.js new file mode 100644 index 0000000000000..420afc5802cb2 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/dir.js @@ -0,0 +1,108 @@ +const Fetcher = require('./fetcher.js') +const FileFetcher = require('./file.js') +const { Minipass } = require('minipass') +const tarCreateOptions = require('./util/tar-create-options.js') +const packlist = require('npm-packlist') +const tar = require('tar') +const _prepareDir = Symbol('_prepareDir') +const { resolve } = require('path') +const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') + +const runScript = require('@npmcli/run-script') + +const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') +class DirFetcher extends Fetcher { + constructor (spec, opts) { + super(spec, opts) + // just the fully resolved filename + this.resolved = this.spec.fetchSpec + + this.tree = opts.tree || null + this.Arborist = opts.Arborist || null + } + + // exposes tarCreateOptions as public API + static tarCreateOptions (manifest) { + return tarCreateOptions(manifest) + } + + get types () { + return ['directory'] + } + + [_prepareDir] () { + return this.manifest().then(mani => { + if (!mani.scripts || !mani.scripts.prepare) { + return + } + + // we *only* run prepare. + // pre/post-pack is run by the npm CLI for publish and pack, + // but this function is *also* run when installing git deps + const stdio = this.opts.foregroundScripts ? 'inherit' : 'pipe' + + // hide the banner if silent opt is passed in, or if prepare running + // in the background. + const banner = this.opts.silent ? false : stdio === 'inherit' + + return runScript({ + pkg: mani, + event: 'prepare', + path: this.resolved, + stdio, + banner, + env: { + npm_package_resolved: this.resolved, + npm_package_integrity: this.integrity, + npm_package_json: resolve(this.resolved, 'package.json'), + }, + }) + }) + } + + [_tarballFromResolved] () { + if (!this.tree && !this.Arborist) { + throw new Error('DirFetcher requires either a tree or an Arborist constructor to pack') + } + + const stream = new Minipass() + stream.resolved = this.resolved + stream.integrity = this.integrity + + const { prefix, workspaces } = this.opts + + // run the prepare script, get the list of files, and tar it up + // pipe to the stream, and proxy errors the chain. + this[_prepareDir]() + .then(async () => { + if (!this.tree) { + const arb = new this.Arborist({ path: this.resolved }) + this.tree = await arb.loadActual() + } + return packlist(this.tree, { path: this.resolved, prefix, workspaces }) + }) + .then(files => tar.c(tarCreateOptions(this.package), files) + .on('error', er => stream.emit('error', er)).pipe(stream)) + .catch(er => stream.emit('error', er)) + return stream + } + + manifest () { + if (this.package) { + return Promise.resolve(this.package) + } + + return this[_readPackageJson](this.resolved + '/package.json') + .then(mani => this.package = { + ...mani, + _integrity: this.integrity && String(this.integrity), + _resolved: this.resolved, + _from: this.from, + }) + } + + packument () { + return FileFetcher.prototype.packument.apply(this) + } +} +module.exports = DirFetcher diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/fetcher.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/fetcher.js new file mode 100644 index 0000000000000..f961a45c7d346 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/fetcher.js @@ -0,0 +1,505 @@ +// This is the base class that the other fetcher types in lib +// all descend from. +// It handles the unpacking and retry logic that is shared among +// all of the other Fetcher types. + +const npa = require('npm-package-arg') +const ssri = require('ssri') +const { promisify } = require('util') +const { basename, dirname } = require('path') +const tar = require('tar') +const log = require('proc-log') +const retry = require('promise-retry') +const fs = require('fs/promises') +const fsm = require('fs-minipass') +const cacache = require('cacache') +const isPackageBin = require('./util/is-package-bin.js') +const removeTrailingSlashes = require('./util/trailing-slashes.js') +const getContents = require('@npmcli/installed-package-contents') +const readPackageJsonFast = require('read-package-json-fast') +const readPackageJson = promisify(require('read-package-json')) +const { Minipass } = require('minipass') + +const cacheDir = require('./util/cache-dir.js') + +// Private methods. +// Child classes should not have to override these. +// Users should never call them. +const _extract = Symbol('_extract') +const _mkdir = Symbol('_mkdir') +const _empty = Symbol('_empty') +const _toFile = Symbol('_toFile') +const _tarxOptions = Symbol('_tarxOptions') +const _entryMode = Symbol('_entryMode') +const _istream = Symbol('_istream') +const _assertType = Symbol('_assertType') +const _tarballFromCache = Symbol('_tarballFromCache') +const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') +const _cacheFetches = Symbol.for('pacote.Fetcher._cacheFetches') +const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') + +class FetcherBase { + constructor (spec, opts) { + if (!opts || typeof opts !== 'object') { + throw new TypeError('options object is required') + } + this.spec = npa(spec, opts.where) + + this.allowGitIgnore = !!opts.allowGitIgnore + + // a bit redundant because presumably the caller already knows this, + // but it makes it easier to not have to keep track of the requested + // spec when we're dispatching thousands of these at once, and normalizing + // is nice. saveSpec is preferred if set, because it turns stuff like + // x/y#committish into github:x/y#committish. use name@rawSpec for + // registry deps so that we turn xyz and xyz@ -> xyz@ + this.from = this.spec.registry + ? `${this.spec.name}@${this.spec.rawSpec}` : this.spec.saveSpec + + this[_assertType]() + // clone the opts object so that others aren't upset when we mutate it + // by adding/modifying the integrity value. + this.opts = { ...opts } + + this.cache = opts.cache || cacheDir().cacache + this.tufCache = opts.tufCache || cacheDir().tufcache + this.resolved = opts.resolved || null + + // default to caching/verifying with sha512, that's what we usually have + // need to change this default, or start overriding it, when sha512 + // is no longer strong enough. + this.defaultIntegrityAlgorithm = opts.defaultIntegrityAlgorithm || 'sha512' + + if (typeof opts.integrity === 'string') { + this.opts.integrity = ssri.parse(opts.integrity) + } + + this.package = null + this.type = this.constructor.name + this.fmode = opts.fmode || 0o666 + this.dmode = opts.dmode || 0o777 + // we don't need a default umask, because we don't chmod files coming + // out of package tarballs. they're forced to have a mode that is + // valid, regardless of what's in the tarball entry, and then we let + // the process's umask setting do its job. but if configured, we do + // respect it. + this.umask = opts.umask || 0 + + this.preferOnline = !!opts.preferOnline + this.preferOffline = !!opts.preferOffline + this.offline = !!opts.offline + + this.before = opts.before + this.fullMetadata = this.before ? true : !!opts.fullMetadata + this.fullReadJson = !!opts.fullReadJson + if (this.fullReadJson) { + this[_readPackageJson] = readPackageJson + } else { + this[_readPackageJson] = readPackageJsonFast + } + + // rrh is a registry hostname or 'never' or 'always' + // defaults to registry.npmjs.org + this.replaceRegistryHost = (!opts.replaceRegistryHost || opts.replaceRegistryHost === 'npmjs') ? + 'registry.npmjs.org' : opts.replaceRegistryHost + + this.defaultTag = opts.defaultTag || 'latest' + this.registry = removeTrailingSlashes(opts.registry || 'https://registry.npmjs.org') + + // command to run 'prepare' scripts on directories and git dirs + // To use pacote with yarn, for example, set npmBin to 'yarn' + // and npmCliConfig with yarn's equivalents. + this.npmBin = opts.npmBin || 'npm' + + // command to install deps for preparing + this.npmInstallCmd = opts.npmInstallCmd || ['install', '--force'] + + // XXX fill more of this in based on what we know from this.opts + // we explicitly DO NOT fill in --tag, though, since we are often + // going to be packing in the context of a publish, which may set + // a dist-tag, but certainly wants to keep defaulting to latest. + this.npmCliConfig = opts.npmCliConfig || [ + `--cache=${dirname(this.cache)}`, + `--prefer-offline=${!!this.preferOffline}`, + `--prefer-online=${!!this.preferOnline}`, + `--offline=${!!this.offline}`, + ...(this.before ? [`--before=${this.before.toISOString()}`] : []), + '--no-progress', + '--no-save', + '--no-audit', + // override any omit settings from the environment + '--include=dev', + '--include=peer', + '--include=optional', + // we need the actual things, not just the lockfile + '--no-package-lock-only', + '--no-dry-run', + ] + } + + get integrity () { + return this.opts.integrity || null + } + + set integrity (i) { + if (!i) { + return + } + + i = ssri.parse(i) + const current = this.opts.integrity + + // do not ever update an existing hash value, but do + // merge in NEW algos and hashes that we don't already have. + if (current) { + current.merge(i) + } else { + this.opts.integrity = i + } + } + + get notImplementedError () { + return new Error('not implemented in this fetcher type: ' + this.type) + } + + // override in child classes + // Returns a Promise that resolves to this.resolved string value + resolve () { + return this.resolved ? Promise.resolve(this.resolved) + : Promise.reject(this.notImplementedError) + } + + packument () { + return Promise.reject(this.notImplementedError) + } + + // override in child class + // returns a manifest containing: + // - name + // - version + // - _resolved + // - _integrity + // - plus whatever else was in there (corgi, full metadata, or pj file) + manifest () { + return Promise.reject(this.notImplementedError) + } + + // private, should be overridden. + // Note that they should *not* calculate or check integrity or cache, + // but *just* return the raw tarball data stream. + [_tarballFromResolved] () { + throw this.notImplementedError + } + + // public, should not be overridden + tarball () { + return this.tarballStream(stream => stream.concat().then(data => { + data.integrity = this.integrity && String(this.integrity) + data.resolved = this.resolved + data.from = this.from + return data + })) + } + + // private + // Note: cacache will raise a EINTEGRITY error if the integrity doesn't match + [_tarballFromCache] () { + return cacache.get.stream.byDigest(this.cache, this.integrity, this.opts) + } + + get [_cacheFetches] () { + return true + } + + [_istream] (stream) { + // if not caching this, just return it + if (!this.opts.cache || !this[_cacheFetches]) { + // instead of creating a new integrity stream, we only piggyback on the + // provided stream's events + if (stream.hasIntegrityEmitter) { + stream.on('integrity', i => this.integrity = i) + return stream + } + + const istream = ssri.integrityStream(this.opts) + istream.on('integrity', i => this.integrity = i) + stream.on('error', err => istream.emit('error', err)) + return stream.pipe(istream) + } + + // we have to return a stream that gets ALL the data, and proxies errors, + // but then pipe from the original tarball stream into the cache as well. + // To do this without losing any data, and since the cacache put stream + // is not a passthrough, we have to pipe from the original stream into + // the cache AFTER we pipe into the middleStream. Since the cache stream + // has an asynchronous flush to write its contents to disk, we need to + // defer the middleStream end until the cache stream ends. + const middleStream = new Minipass() + stream.on('error', err => middleStream.emit('error', err)) + stream.pipe(middleStream, { end: false }) + const cstream = cacache.put.stream( + this.opts.cache, + `pacote:tarball:${this.from}`, + this.opts + ) + cstream.on('integrity', i => this.integrity = i) + cstream.on('error', err => stream.emit('error', err)) + stream.pipe(cstream) + + // eslint-disable-next-line promise/catch-or-return + cstream.promise().catch(() => {}).then(() => middleStream.end()) + return middleStream + } + + pickIntegrityAlgorithm () { + return this.integrity ? this.integrity.pickAlgorithm(this.opts) + : this.defaultIntegrityAlgorithm + } + + // TODO: check error class, once those are rolled out to our deps + isDataCorruptionError (er) { + return er.code === 'EINTEGRITY' || er.code === 'Z_DATA_ERROR' + } + + // override the types getter + get types () { + return false + } + + [_assertType] () { + if (this.types && !this.types.includes(this.spec.type)) { + throw new TypeError(`Wrong spec type (${ + this.spec.type + }) for ${ + this.constructor.name + }. Supported types: ${this.types.join(', ')}`) + } + } + + // We allow ENOENTs from cacache, but not anywhere else. + // An ENOENT trying to read a tgz file, for example, is Right Out. + isRetriableError (er) { + // TODO: check error class, once those are rolled out to our deps + return this.isDataCorruptionError(er) || + er.code === 'ENOENT' || + er.code === 'EISDIR' + } + + // Mostly internal, but has some uses + // Pass in a function which returns a promise + // Function will be called 1 or more times with streams that may fail. + // Retries: + // Function MUST handle errors on the stream by rejecting the promise, + // so that retry logic can pick it up and either retry or fail whatever + // promise it was making (ie, failing extraction, etc.) + // + // The return value of this method is a Promise that resolves the same + // as whatever the streamHandler resolves to. + // + // This should never be overridden by child classes, but it is public. + tarballStream (streamHandler) { + // Only short-circuit via cache if we have everything else we'll need, + // and the user has not expressed a preference for checking online. + + const fromCache = ( + !this.preferOnline && + this.integrity && + this.resolved + ) ? streamHandler(this[_tarballFromCache]()).catch(er => { + if (this.isDataCorruptionError(er)) { + log.warn('tarball', `cached data for ${ + this.spec + } (${this.integrity}) seems to be corrupted. Refreshing cache.`) + return this.cleanupCached().then(() => { + throw er + }) + } else { + throw er + } + }) : null + + const fromResolved = er => { + if (er) { + if (!this.isRetriableError(er)) { + throw er + } + log.silly('tarball', `no local data for ${ + this.spec + }. Extracting by manifest.`) + } + return this.resolve().then(() => retry(tryAgain => + streamHandler(this[_istream](this[_tarballFromResolved]())) + .catch(streamErr => { + // Most likely data integrity. A cache ENOENT error is unlikely + // here, since we're definitely not reading from the cache, but it + // IS possible that the fetch subsystem accessed the cache, and the + // entry got blown away or something. Try one more time to be sure. + if (this.isRetriableError(streamErr)) { + log.warn('tarball', `tarball data for ${ + this.spec + } (${this.integrity}) seems to be corrupted. Trying again.`) + return this.cleanupCached().then(() => tryAgain(streamErr)) + } + throw streamErr + }), { retries: 1, minTimeout: 0, maxTimeout: 0 })) + } + + return fromCache ? fromCache.catch(fromResolved) : fromResolved() + } + + cleanupCached () { + return cacache.rm.content(this.cache, this.integrity, this.opts) + } + + [_empty] (path) { + return getContents({ path, depth: 1 }).then(contents => Promise.all( + contents.map(entry => fs.rm(entry, { recursive: true, force: true })))) + } + + async [_mkdir] (dest) { + await this[_empty](dest) + return await fs.mkdir(dest, { recursive: true }) + } + + // extraction is always the same. the only difference is where + // the tarball comes from. + async extract (dest) { + await this[_mkdir](dest) + return this.tarballStream((tarball) => this[_extract](dest, tarball)) + } + + [_toFile] (dest) { + return this.tarballStream(str => new Promise((res, rej) => { + const writer = new fsm.WriteStream(dest) + str.on('error', er => writer.emit('error', er)) + writer.on('error', er => rej(er)) + writer.on('close', () => res({ + integrity: this.integrity && String(this.integrity), + resolved: this.resolved, + from: this.from, + })) + str.pipe(writer) + })) + } + + // don't use this[_mkdir] because we don't want to rimraf anything + async tarballFile (dest) { + const dir = dirname(dest) + await fs.mkdir(dir, { recursive: true }) + return this[_toFile](dest) + } + + [_extract] (dest, tarball) { + const extractor = tar.x(this[_tarxOptions]({ cwd: dest })) + const p = new Promise((resolve, reject) => { + extractor.on('end', () => { + resolve({ + resolved: this.resolved, + integrity: this.integrity && String(this.integrity), + from: this.from, + }) + }) + + extractor.on('error', er => { + log.warn('tar', er.message) + log.silly('tar', er) + reject(er) + }) + + tarball.on('error', er => reject(er)) + }) + + tarball.pipe(extractor) + return p + } + + // always ensure that entries are at least as permissive as our configured + // dmode/fmode, but never more permissive than the umask allows. + [_entryMode] (path, mode, type) { + const m = /Directory|GNUDumpDir/.test(type) ? this.dmode + : /File$/.test(type) ? this.fmode + : /* istanbul ignore next - should never happen in a pkg */ 0 + + // make sure package bins are executable + const exe = isPackageBin(this.package, path) ? 0o111 : 0 + // always ensure that files are read/writable by the owner + return ((mode | m) & ~this.umask) | exe | 0o600 + } + + [_tarxOptions] ({ cwd }) { + const sawIgnores = new Set() + return { + cwd, + noChmod: true, + noMtime: true, + filter: (name, entry) => { + if (/Link$/.test(entry.type)) { + return false + } + entry.mode = this[_entryMode](entry.path, entry.mode, entry.type) + // this replicates the npm pack behavior where .gitignore files + // are treated like .npmignore files, but only if a .npmignore + // file is not present. + if (/File$/.test(entry.type)) { + const base = basename(entry.path) + if (base === '.npmignore') { + sawIgnores.add(entry.path) + } else if (base === '.gitignore' && !this.allowGitIgnore) { + // rename, but only if there's not already a .npmignore + const ni = entry.path.replace(/\.gitignore$/, '.npmignore') + if (sawIgnores.has(ni)) { + return false + } + entry.path = ni + } + return true + } + }, + strip: 1, + onwarn: /* istanbul ignore next - we can trust that tar logs */ + (code, msg, data) => { + log.warn('tar', code, msg) + log.silly('tar', code, msg, data) + }, + umask: this.umask, + // always ignore ownership info from tarball metadata + preserveOwner: false, + } + } +} + +module.exports = FetcherBase + +// Child classes +const GitFetcher = require('./git.js') +const RegistryFetcher = require('./registry.js') +const FileFetcher = require('./file.js') +const DirFetcher = require('./dir.js') +const RemoteFetcher = require('./remote.js') + +// Get an appropriate fetcher object from a spec and options +FetcherBase.get = (rawSpec, opts = {}) => { + const spec = npa(rawSpec, opts.where) + switch (spec.type) { + case 'git': + return new GitFetcher(spec, opts) + + case 'remote': + return new RemoteFetcher(spec, opts) + + case 'version': + case 'range': + case 'tag': + case 'alias': + return new RegistryFetcher(spec.subSpec || spec, opts) + + case 'file': + return new FileFetcher(spec, opts) + + case 'directory': + return new DirFetcher(spec, opts) + + default: + throw new TypeError('Unknown spec type: ' + spec.type) + } +} diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/file.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/file.js new file mode 100644 index 0000000000000..bf99bb86e359e --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/file.js @@ -0,0 +1,96 @@ +const Fetcher = require('./fetcher.js') +const fsm = require('fs-minipass') +const cacache = require('cacache') +const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') +const _exeBins = Symbol('_exeBins') +const { resolve } = require('path') +const fs = require('fs') +const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') + +class FileFetcher extends Fetcher { + constructor (spec, opts) { + super(spec, opts) + // just the fully resolved filename + this.resolved = this.spec.fetchSpec + } + + get types () { + return ['file'] + } + + manifest () { + if (this.package) { + return Promise.resolve(this.package) + } + + // have to unpack the tarball for this. + return cacache.tmp.withTmp(this.cache, this.opts, dir => + this.extract(dir) + .then(() => this[_readPackageJson](dir + '/package.json')) + .then(mani => this.package = { + ...mani, + _integrity: this.integrity && String(this.integrity), + _resolved: this.resolved, + _from: this.from, + })) + } + + [_exeBins] (pkg, dest) { + if (!pkg.bin) { + return Promise.resolve() + } + + return Promise.all(Object.keys(pkg.bin).map(k => new Promise(res => { + const script = resolve(dest, pkg.bin[k]) + // Best effort. Ignore errors here, the only result is that + // a bin script is not executable. But if it's missing or + // something, we just leave it for a later stage to trip over + // when we can provide a more useful contextual error. + fs.stat(script, (er, st) => { + if (er) { + return res() + } + const mode = st.mode | 0o111 + if (mode === st.mode) { + return res() + } + fs.chmod(script, mode, res) + }) + }))) + } + + extract (dest) { + // if we've already loaded the manifest, then the super got it. + // but if not, read the unpacked manifest and chmod properly. + return super.extract(dest) + .then(result => this.package ? result + : this[_readPackageJson](dest + '/package.json').then(pkg => + this[_exeBins](pkg, dest)).then(() => result)) + } + + [_tarballFromResolved] () { + // create a read stream and return it + return new fsm.ReadStream(this.resolved) + } + + packument () { + // simulate based on manifest + return this.manifest().then(mani => ({ + name: mani.name, + 'dist-tags': { + [this.defaultTag]: mani.version, + }, + versions: { + [mani.version]: { + ...mani, + dist: { + tarball: `file:${this.resolved}`, + integrity: this.integrity && String(this.integrity), + }, + }, + }, + })) + } +} + +module.exports = FileFetcher diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/git.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/git.js new file mode 100644 index 0000000000000..5d24f72497ec9 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/git.js @@ -0,0 +1,327 @@ +const Fetcher = require('./fetcher.js') +const FileFetcher = require('./file.js') +const RemoteFetcher = require('./remote.js') +const DirFetcher = require('./dir.js') +const hashre = /^[a-f0-9]{40}$/ +const git = require('@npmcli/git') +const pickManifest = require('npm-pick-manifest') +const npa = require('npm-package-arg') +const { Minipass } = require('minipass') +const cacache = require('cacache') +const log = require('proc-log') +const npm = require('./util/npm.js') + +const _resolvedFromRepo = Symbol('_resolvedFromRepo') +const _resolvedFromHosted = Symbol('_resolvedFromHosted') +const _resolvedFromClone = Symbol('_resolvedFromClone') +const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') +const _addGitSha = Symbol('_addGitSha') +const addGitSha = require('./util/add-git-sha.js') +const _clone = Symbol('_clone') +const _cloneHosted = Symbol('_cloneHosted') +const _cloneRepo = Symbol('_cloneRepo') +const _setResolvedWithSha = Symbol('_setResolvedWithSha') +const _prepareDir = Symbol('_prepareDir') +const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') + +// get the repository url. +// prefer https if there's auth, since ssh will drop that. +// otherwise, prefer ssh if available (more secure). +// We have to add the git+ back because npa suppresses it. +const repoUrl = (h, opts) => + h.sshurl && !(h.https && h.auth) && addGitPlus(h.sshurl(opts)) || + h.https && addGitPlus(h.https(opts)) + +// add git+ to the url, but only one time. +const addGitPlus = url => url && `git+${url}`.replace(/^(git\+)+/, 'git+') + +class GitFetcher extends Fetcher { + constructor (spec, opts) { + super(spec, opts) + + // we never want to compare integrity for git dependencies: npm/rfcs#525 + if (this.opts.integrity) { + delete this.opts.integrity + log.warn(`skipping integrity check for git dependency ${this.spec.fetchSpec}`) + } + + this.resolvedRef = null + if (this.spec.hosted) { + this.from = this.spec.hosted.shortcut({ noCommittish: false }) + } + + // shortcut: avoid full clone when we can go straight to the tgz + // if we have the full sha and it's a hosted git platform + if (this.spec.gitCommittish && hashre.test(this.spec.gitCommittish)) { + this.resolvedSha = this.spec.gitCommittish + // use hosted.tarball() when we shell to RemoteFetcher later + this.resolved = this.spec.hosted + ? repoUrl(this.spec.hosted, { noCommittish: false }) + : this.spec.rawSpec + } else { + this.resolvedSha = '' + } + + this.Arborist = opts.Arborist || null + } + + // just exposed to make it easier to test all the combinations + static repoUrl (hosted, opts) { + return repoUrl(hosted, opts) + } + + get types () { + return ['git'] + } + + resolve () { + // likely a hosted git repo with a sha, so get the tarball url + // but in general, no reason to resolve() more than necessary! + if (this.resolved) { + return super.resolve() + } + + // fetch the git repo and then look at the current hash + const h = this.spec.hosted + // try to use ssh, fall back to git. + return h ? this[_resolvedFromHosted](h) + : this[_resolvedFromRepo](this.spec.fetchSpec) + } + + // first try https, since that's faster and passphrase-less for + // public repos, and supports private repos when auth is provided. + // Fall back to SSH to support private repos + // NB: we always store the https url in resolved field if auth + // is present, otherwise ssh if the hosted type provides it + [_resolvedFromHosted] (hosted) { + return this[_resolvedFromRepo](hosted.https && hosted.https()) + .catch(er => { + // Throw early since we know pathspec errors will fail again if retried + if (er instanceof git.errors.GitPathspecError) { + throw er + } + const ssh = hosted.sshurl && hosted.sshurl() + // no fallthrough if we can't fall through or have https auth + if (!ssh || hosted.auth) { + throw er + } + return this[_resolvedFromRepo](ssh) + }) + } + + [_resolvedFromRepo] (gitRemote) { + // XXX make this a custom error class + if (!gitRemote) { + return Promise.reject(new Error(`No git url for ${this.spec}`)) + } + const gitRange = this.spec.gitRange + const name = this.spec.name + return git.revs(gitRemote, this.opts).then(remoteRefs => { + return gitRange ? pickManifest({ + versions: remoteRefs.versions, + 'dist-tags': remoteRefs['dist-tags'], + name, + }, gitRange, this.opts) + : this.spec.gitCommittish ? + remoteRefs.refs[this.spec.gitCommittish] || + remoteRefs.refs[remoteRefs.shas[this.spec.gitCommittish]] + : remoteRefs.refs.HEAD // no git committish, get default head + }).then(revDoc => { + // the committish provided isn't in the rev list + // things like HEAD~3 or @yesterday can land here. + if (!revDoc || !revDoc.sha) { + return this[_resolvedFromClone]() + } + + this.resolvedRef = revDoc + this.resolvedSha = revDoc.sha + this[_addGitSha](revDoc.sha) + return this.resolved + }) + } + + [_setResolvedWithSha] (withSha) { + // we haven't cloned, so a tgz download is still faster + // of course, if it's not a known host, we can't do that. + this.resolved = !this.spec.hosted ? withSha + : repoUrl(npa(withSha).hosted, { noCommittish: false }) + } + + // when we get the git sha, we affix it to our spec to build up + // either a git url with a hash, or a tarball download URL + [_addGitSha] (sha) { + this[_setResolvedWithSha](addGitSha(this.spec, sha)) + } + + [_resolvedFromClone] () { + // do a full or shallow clone, then look at the HEAD + // kind of wasteful, but no other option, really + return this[_clone](dir => this.resolved) + } + + [_prepareDir] (dir) { + return this[_readPackageJson](dir + '/package.json').then(mani => { + // no need if we aren't going to do any preparation. + const scripts = mani.scripts + if (!mani.workspaces && (!scripts || !( + scripts.postinstall || + scripts.build || + scripts.preinstall || + scripts.install || + scripts.prepack || + scripts.prepare))) { + return + } + + // to avoid cases where we have an cycle of git deps that depend + // on one another, we only ever do preparation for one instance + // of a given git dep along the chain of installations. + // Note that this does mean that a dependency MAY in theory end up + // trying to run its prepare script using a dependency that has not + // been properly prepared itself, but that edge case is smaller + // and less hazardous than a fork bomb of npm and git commands. + const noPrepare = !process.env._PACOTE_NO_PREPARE_ ? [] + : process.env._PACOTE_NO_PREPARE_.split('\n') + if (noPrepare.includes(this.resolved)) { + log.info('prepare', 'skip prepare, already seen', this.resolved) + return + } + noPrepare.push(this.resolved) + + // the DirFetcher will do its own preparation to run the prepare scripts + // All we have to do is put the deps in place so that it can succeed. + return npm( + this.npmBin, + [].concat(this.npmInstallCmd).concat(this.npmCliConfig), + dir, + { ...process.env, _PACOTE_NO_PREPARE_: noPrepare.join('\n') }, + { message: 'git dep preparation failed' } + ) + }) + } + + [_tarballFromResolved] () { + const stream = new Minipass() + stream.resolved = this.resolved + stream.from = this.from + + // check it out and then shell out to the DirFetcher tarball packer + this[_clone](dir => this[_prepareDir](dir) + .then(() => new Promise((res, rej) => { + if (!this.Arborist) { + throw new Error('GitFetcher requires an Arborist constructor to pack a tarball') + } + const df = new DirFetcher(`file:${dir}`, { + ...this.opts, + Arborist: this.Arborist, + resolved: null, + integrity: null, + }) + const dirStream = df[_tarballFromResolved]() + dirStream.on('error', rej) + dirStream.on('end', res) + dirStream.pipe(stream) + }))).catch( + /* istanbul ignore next: very unlikely and hard to test */ + er => stream.emit('error', er) + ) + return stream + } + + // clone a git repo into a temp folder (or fetch and unpack if possible) + // handler accepts a directory, and returns a promise that resolves + // when we're done with it, at which point, cacache deletes it + // + // TODO: after cloning, create a tarball of the folder, and add to the cache + // with cacache.put.stream(), using a key that's deterministic based on the + // spec and repo, so that we don't ever clone the same thing multiple times. + [_clone] (handler, tarballOk = true) { + const o = { tmpPrefix: 'git-clone' } + const ref = this.resolvedSha || this.spec.gitCommittish + const h = this.spec.hosted + const resolved = this.resolved + + // can be set manually to false to fall back to actual git clone + tarballOk = tarballOk && + h && resolved === repoUrl(h, { noCommittish: false }) && h.tarball + + return cacache.tmp.withTmp(this.cache, o, async tmp => { + // if we're resolved, and have a tarball url, shell out to RemoteFetcher + if (tarballOk) { + const nameat = this.spec.name ? `${this.spec.name}@` : '' + return new RemoteFetcher(h.tarball({ noCommittish: false }), { + ...this.opts, + allowGitIgnore: true, + pkgid: `git:${nameat}${this.resolved}`, + resolved: this.resolved, + integrity: null, // it'll always be different, if we have one + }).extract(tmp).then(() => handler(tmp), er => { + // fall back to ssh download if tarball fails + if (er.constructor.name.match(/^Http/)) { + return this[_clone](handler, false) + } else { + throw er + } + }) + } + + const sha = await ( + h ? this[_cloneHosted](ref, tmp) + : this[_cloneRepo](this.spec.fetchSpec, ref, tmp) + ) + this.resolvedSha = sha + if (!this.resolved) { + await this[_addGitSha](sha) + } + return handler(tmp) + }) + } + + // first try https, since that's faster and passphrase-less for + // public repos, and supports private repos when auth is provided. + // Fall back to SSH to support private repos + // NB: we always store the https url in resolved field if auth + // is present, otherwise ssh if the hosted type provides it + [_cloneHosted] (ref, tmp) { + const hosted = this.spec.hosted + return this[_cloneRepo](hosted.https({ noCommittish: true }), ref, tmp) + .catch(er => { + // Throw early since we know pathspec errors will fail again if retried + if (er instanceof git.errors.GitPathspecError) { + throw er + } + const ssh = hosted.sshurl && hosted.sshurl({ noCommittish: true }) + // no fallthrough if we can't fall through or have https auth + if (!ssh || hosted.auth) { + throw er + } + return this[_cloneRepo](ssh, ref, tmp) + }) + } + + [_cloneRepo] (repo, ref, tmp) { + const { opts, spec } = this + return git.clone(repo, ref, tmp, { ...opts, spec }) + } + + manifest () { + if (this.package) { + return Promise.resolve(this.package) + } + + return this.spec.hosted && this.resolved + ? FileFetcher.prototype.manifest.apply(this) + : this[_clone](dir => + this[_readPackageJson](dir + '/package.json') + .then(mani => this.package = { + ...mani, + _resolved: this.resolved, + _from: this.from, + })) + } + + packument () { + return FileFetcher.prototype.packument.apply(this) + } +} +module.exports = GitFetcher diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/index.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/index.js new file mode 100644 index 0000000000000..cbcbd7c92d15f --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/index.js @@ -0,0 +1,23 @@ +const { get } = require('./fetcher.js') +const GitFetcher = require('./git.js') +const RegistryFetcher = require('./registry.js') +const FileFetcher = require('./file.js') +const DirFetcher = require('./dir.js') +const RemoteFetcher = require('./remote.js') + +module.exports = { + GitFetcher, + RegistryFetcher, + FileFetcher, + DirFetcher, + RemoteFetcher, + resolve: (spec, opts) => get(spec, opts).resolve(), + extract: (spec, dest, opts) => get(spec, opts).extract(dest), + manifest: (spec, opts) => get(spec, opts).manifest(), + tarball: (spec, opts) => get(spec, opts).tarball(), + packument: (spec, opts) => get(spec, opts).packument(), +} +module.exports.tarball.stream = (spec, handler, opts) => + get(spec, opts).tarballStream(handler) +module.exports.tarball.file = (spec, dest, opts) => + get(spec, opts).tarballFile(dest) diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/registry.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/registry.js new file mode 100644 index 0000000000000..34d9b2b87f3f3 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/registry.js @@ -0,0 +1,344 @@ +const Fetcher = require('./fetcher.js') +const RemoteFetcher = require('./remote.js') +const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') +const pacoteVersion = require('../package.json').version +const removeTrailingSlashes = require('./util/trailing-slashes.js') +const rpj = require('read-package-json-fast') +const pickManifest = require('npm-pick-manifest') +const ssri = require('ssri') +const crypto = require('crypto') +const npa = require('npm-package-arg') +const { sigstore } = require('sigstore') + +// Corgis are cute. 🐕🐶 +const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' +const fullDoc = 'application/json' + +const fetch = require('npm-registry-fetch') + +const _headers = Symbol('_headers') +class RegistryFetcher extends Fetcher { + constructor (spec, opts) { + super(spec, opts) + + // you usually don't want to fetch the same packument multiple times in + // the span of a given script or command, no matter how many pacote calls + // are made, so this lets us avoid doing that. It's only relevant for + // registry fetchers, because other types simulate their packument from + // the manifest, which they memoize on this.package, so it's very cheap + // already. + this.packumentCache = this.opts.packumentCache || null + + this.registry = fetch.pickRegistry(spec, opts) + this.packumentUrl = removeTrailingSlashes(this.registry) + '/' + + this.spec.escapedName + + const parsed = new URL(this.registry) + const regKey = `//${parsed.host}${parsed.pathname}` + // unlike the nerf-darted auth keys, this one does *not* allow a mismatch + // of trailing slashes. It must match exactly. + if (this.opts[`${regKey}:_keys`]) { + this.registryKeys = this.opts[`${regKey}:_keys`] + } + + // XXX pacote <=9 has some logic to ignore opts.resolved if + // the resolved URL doesn't go to the same registry. + // Consider reproducing that here, to throw away this.resolved + // in that case. + } + + async resolve () { + // fetching the manifest sets resolved and (if present) integrity + await this.manifest() + if (!this.resolved) { + throw Object.assign( + new Error('Invalid package manifest: no `dist.tarball` field'), + { package: this.spec.toString() } + ) + } + return this.resolved + } + + [_headers] () { + return { + // npm will override UA, but ensure that we always send *something* + 'user-agent': this.opts.userAgent || + `pacote/${pacoteVersion} node/${process.version}`, + ...(this.opts.headers || {}), + 'pacote-version': pacoteVersion, + 'pacote-req-type': 'packument', + 'pacote-pkg-id': `registry:${this.spec.name}`, + accept: this.fullMetadata ? fullDoc : corgiDoc, + } + } + + async packument () { + // note this might be either an in-flight promise for a request, + // or the actual packument, but we never want to make more than + // one request at a time for the same thing regardless. + if (this.packumentCache && this.packumentCache.has(this.packumentUrl)) { + return this.packumentCache.get(this.packumentUrl) + } + + // npm-registry-fetch the packument + // set the appropriate header for corgis if fullMetadata isn't set + // return the res.json() promise + try { + const res = await fetch(this.packumentUrl, { + ...this.opts, + headers: this[_headers](), + spec: this.spec, + // never check integrity for packuments themselves + integrity: null, + }) + const packument = await res.json() + packument._contentLength = +res.headers.get('content-length') + if (this.packumentCache) { + this.packumentCache.set(this.packumentUrl, packument) + } + return packument + } catch (err) { + if (this.packumentCache) { + this.packumentCache.delete(this.packumentUrl) + } + if (err.code !== 'E404' || this.fullMetadata) { + throw err + } + // possible that corgis are not supported by this registry + this.fullMetadata = true + return this.packument() + } + } + + async manifest () { + if (this.package) { + return this.package + } + + const packument = await this.packument() + let mani = await pickManifest(packument, this.spec.fetchSpec, { + ...this.opts, + defaultTag: this.defaultTag, + before: this.before, + }) + mani = rpj.normalize(mani) + /* XXX add ETARGET and E403 revalidation of cached packuments here */ + + // add _resolved and _integrity from dist object + const { dist } = mani + if (dist) { + this.resolved = mani._resolved = dist.tarball + mani._from = this.from + const distIntegrity = dist.integrity ? ssri.parse(dist.integrity) + : dist.shasum ? ssri.fromHex(dist.shasum, 'sha1', { ...this.opts }) + : null + if (distIntegrity) { + if (this.integrity && !this.integrity.match(distIntegrity)) { + // only bork if they have algos in common. + // otherwise we end up breaking if we have saved a sha512 + // previously for the tarball, but the manifest only + // provides a sha1, which is possible for older publishes. + // Otherwise, this is almost certainly a case of holding it + // wrong, and will result in weird or insecure behavior + // later on when building package tree. + for (const algo of Object.keys(this.integrity)) { + if (distIntegrity[algo]) { + throw Object.assign(new Error( + `Integrity checksum failed when using ${algo}: ` + + `wanted ${this.integrity} but got ${distIntegrity}.` + ), { code: 'EINTEGRITY' }) + } + } + } + // made it this far, the integrity is worthwhile. accept it. + // the setter here will take care of merging it into what we already + // had. + this.integrity = distIntegrity + } + } + if (this.integrity) { + mani._integrity = String(this.integrity) + if (dist.signatures) { + if (this.opts.verifySignatures) { + // validate and throw on error, then set _signatures + const message = `${mani._id}:${mani._integrity}` + for (const signature of dist.signatures) { + const publicKey = this.registryKeys && + this.registryKeys.filter(key => (key.keyid === signature.keyid))[0] + if (!publicKey) { + throw Object.assign(new Error( + `${mani._id} has a registry signature with keyid: ${signature.keyid} ` + + 'but no corresponding public key can be found' + ), { code: 'EMISSINGSIGNATUREKEY' }) + } + const validPublicKey = + !publicKey.expires || (Date.parse(publicKey.expires) > Date.now()) + if (!validPublicKey) { + throw Object.assign(new Error( + `${mani._id} has a registry signature with keyid: ${signature.keyid} ` + + `but the corresponding public key has expired ${publicKey.expires}` + ), { code: 'EEXPIREDSIGNATUREKEY' }) + } + const verifier = crypto.createVerify('SHA256') + verifier.write(message) + verifier.end() + const valid = verifier.verify( + publicKey.pemkey, + signature.sig, + 'base64' + ) + if (!valid) { + throw Object.assign(new Error( + `${mani._id} has an invalid registry signature with ` + + `keyid: ${publicKey.keyid} and signature: ${signature.sig}` + ), { + code: 'EINTEGRITYSIGNATURE', + keyid: publicKey.keyid, + signature: signature.sig, + resolved: mani._resolved, + integrity: mani._integrity, + }) + } + } + mani._signatures = dist.signatures + } else { + mani._signatures = dist.signatures + } + } + + if (dist.attestations) { + if (this.opts.verifyAttestations) { + // Always fetch attestations from the current registry host + const attestationsPath = new URL(dist.attestations.url).pathname + const attestationsUrl = removeTrailingSlashes(this.registry) + attestationsPath + const res = await fetch(attestationsUrl, { + ...this.opts, + // disable integrity check for attestations json payload, we check the + // integrity in the verification steps below + integrity: null, + }) + const { attestations } = await res.json() + const bundles = attestations.map(({ predicateType, bundle }) => { + const statement = JSON.parse( + Buffer.from(bundle.dsseEnvelope.payload, 'base64').toString('utf8') + ) + const keyid = bundle.dsseEnvelope.signatures[0].keyid + const signature = bundle.dsseEnvelope.signatures[0].sig + + return { + predicateType, + bundle, + statement, + keyid, + signature, + } + }) + + const attestationKeyIds = bundles.map((b) => b.keyid).filter((k) => !!k) + const attestationRegistryKeys = (this.registryKeys || []) + .filter(key => attestationKeyIds.includes(key.keyid)) + if (!attestationRegistryKeys.length) { + throw Object.assign(new Error( + `${mani._id} has attestations but no corresponding public key(s) can be found` + ), { code: 'EMISSINGSIGNATUREKEY' }) + } + + for (const { predicateType, bundle, keyid, signature, statement } of bundles) { + const publicKey = attestationRegistryKeys.find(key => key.keyid === keyid) + // Publish attestations have a keyid set and a valid public key must be found + if (keyid) { + if (!publicKey) { + throw Object.assign(new Error( + `${mani._id} has attestations with keyid: ${keyid} ` + + 'but no corresponding public key can be found' + ), { code: 'EMISSINGSIGNATUREKEY' }) + } + + const validPublicKey = + !publicKey.expires || (Date.parse(publicKey.expires) > Date.now()) + if (!validPublicKey) { + throw Object.assign(new Error( + `${mani._id} has attestations with keyid: ${keyid} ` + + `but the corresponding public key has expired ${publicKey.expires}` + ), { code: 'EEXPIREDSIGNATUREKEY' }) + } + } + + const subject = { + name: statement.subject[0].name, + sha512: statement.subject[0].digest.sha512, + } + + // Only type 'version' can be turned into a PURL + const purl = this.spec.type === 'version' ? npa.toPurl(this.spec) : this.spec + // Verify the statement subject matches the package, version + if (subject.name !== purl) { + throw Object.assign(new Error( + `${mani._id} package name and version (PURL): ${purl} ` + + `doesn't match what was signed: ${subject.name}` + ), { code: 'EATTESTATIONSUBJECT' }) + } + + // Verify the statement subject matches the tarball integrity + const integrityHexDigest = ssri.parse(this.integrity).hexDigest() + if (subject.sha512 !== integrityHexDigest) { + throw Object.assign(new Error( + `${mani._id} package integrity (hex digest): ` + + `${integrityHexDigest} ` + + `doesn't match what was signed: ${subject.sha512}` + ), { code: 'EATTESTATIONSUBJECT' }) + } + + try { + // Provenance attestations are signed with a signing certificate + // (including the key) so we don't need to return a public key. + // + // Publish attestations are signed with a keyid so we need to + // specify a public key from the keys endpoint: `registry-host.tld/-/npm/v1/keys` + const options = { + tufCachePath: this.tufCache, + keySelector: publicKey ? () => publicKey.pemkey : undefined, + } + await sigstore.verify(bundle, null, options) + } catch (e) { + throw Object.assign(new Error( + `${mani._id} failed to verify attestation: ${e.message}` + ), { + code: 'EATTESTATIONVERIFY', + predicateType, + keyid, + signature, + resolved: mani._resolved, + integrity: mani._integrity, + }) + } + } + mani._attestations = dist.attestations + } else { + mani._attestations = dist.attestations + } + } + } + + this.package = mani + return this.package + } + + [_tarballFromResolved] () { + // we use a RemoteFetcher to get the actual tarball stream + return new RemoteFetcher(this.resolved, { + ...this.opts, + resolved: this.resolved, + pkgid: `registry:${this.spec.name}@${this.resolved}`, + })[_tarballFromResolved]() + } + + get types () { + return [ + 'tag', + 'version', + 'range', + ] + } +} +module.exports = RegistryFetcher diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/remote.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/remote.js new file mode 100644 index 0000000000000..fd617459fb031 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/remote.js @@ -0,0 +1,91 @@ +const Fetcher = require('./fetcher.js') +const FileFetcher = require('./file.js') +const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') +const pacoteVersion = require('../package.json').version +const fetch = require('npm-registry-fetch') +const { Minipass } = require('minipass') + +const _cacheFetches = Symbol.for('pacote.Fetcher._cacheFetches') +const _headers = Symbol('_headers') +class RemoteFetcher extends Fetcher { + constructor (spec, opts) { + super(spec, opts) + this.resolved = this.spec.fetchSpec + const resolvedURL = new URL(this.resolved) + if (this.replaceRegistryHost !== 'never' + && (this.replaceRegistryHost === 'always' + || this.replaceRegistryHost === resolvedURL.host)) { + this.resolved = new URL(resolvedURL.pathname, this.registry).href + } + + // nam is a fermented pork sausage that is good to eat + const nameat = this.spec.name ? `${this.spec.name}@` : '' + this.pkgid = opts.pkgid ? opts.pkgid : `remote:${nameat}${this.resolved}` + } + + // Don't need to cache tarball fetches in pacote, because make-fetch-happen + // will write into cacache anyway. + get [_cacheFetches] () { + return false + } + + [_tarballFromResolved] () { + const stream = new Minipass() + stream.hasIntegrityEmitter = true + + const fetchOpts = { + ...this.opts, + headers: this[_headers](), + spec: this.spec, + integrity: this.integrity, + algorithms: [this.pickIntegrityAlgorithm()], + } + + // eslint-disable-next-line promise/always-return + fetch(this.resolved, fetchOpts).then(res => { + res.body.on('error', + /* istanbul ignore next - exceedingly rare and hard to simulate */ + er => stream.emit('error', er) + ) + + res.body.on('integrity', i => { + this.integrity = i + stream.emit('integrity', i) + }) + + res.body.pipe(stream) + }).catch(er => stream.emit('error', er)) + + return stream + } + + [_headers] () { + return { + // npm will override this, but ensure that we always send *something* + 'user-agent': this.opts.userAgent || + `pacote/${pacoteVersion} node/${process.version}`, + ...(this.opts.headers || {}), + 'pacote-version': pacoteVersion, + 'pacote-req-type': 'tarball', + 'pacote-pkg-id': this.pkgid, + ...(this.integrity ? { 'pacote-integrity': String(this.integrity) } + : {}), + ...(this.opts.headers || {}), + } + } + + get types () { + return ['remote'] + } + + // getting a packument and/or manifest is the same as with a file: spec. + // unpack the tarball stream, and then read from the package.json file. + packument () { + return FileFetcher.prototype.packument.apply(this) + } + + manifest () { + return FileFetcher.prototype.manifest.apply(this) + } +} +module.exports = RemoteFetcher diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/add-git-sha.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/add-git-sha.js new file mode 100644 index 0000000000000..843fe5b600caf --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/add-git-sha.js @@ -0,0 +1,15 @@ +// add a sha to a git remote url spec +const addGitSha = (spec, sha) => { + if (spec.hosted) { + const h = spec.hosted + const opt = { noCommittish: true } + const base = h.https && h.auth ? h.https(opt) : h.shortcut(opt) + + return `${base}#${sha}` + } else { + // don't use new URL for this, because it doesn't handle scp urls + return spec.rawSpec.replace(/#.*$/, '') + `#${sha}` + } +} + +module.exports = addGitSha diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/cache-dir.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/cache-dir.js new file mode 100644 index 0000000000000..ac83b1793f199 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/cache-dir.js @@ -0,0 +1,15 @@ +const os = require('os') +const { resolve } = require('path') + +module.exports = (fakePlatform = false) => { + const temp = os.tmpdir() + const uidOrPid = process.getuid ? process.getuid() : process.pid + const home = os.homedir() || resolve(temp, 'npm-' + uidOrPid) + const platform = fakePlatform || process.platform + const cacheExtra = platform === 'win32' ? 'npm-cache' : '.npm' + const cacheRoot = (platform === 'win32' && process.env.LOCALAPPDATA) || home + return { + cacache: resolve(cacheRoot, cacheExtra, '_cacache'), + tufcache: resolve(cacheRoot, cacheExtra, '_tuf'), + } +} diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/is-package-bin.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/is-package-bin.js new file mode 100644 index 0000000000000..49a3f73f537ce --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/is-package-bin.js @@ -0,0 +1,25 @@ +// Function to determine whether a path is in the package.bin set. +// Used to prevent issues when people publish a package from a +// windows machine, and then install with --no-bin-links. +// +// Note: this is not possible in remote or file fetchers, since +// we don't have the manifest until AFTER we've unpacked. But the +// main use case is registry fetching with git a distant second, +// so that's an acceptable edge case to not handle. + +const binObj = (name, bin) => + typeof bin === 'string' ? { [name]: bin } : bin + +const hasBin = (pkg, path) => { + const bin = binObj(pkg.name, pkg.bin) + const p = path.replace(/^[^\\/]*\//, '') + for (const kv of Object.entries(bin)) { + if (kv[1] === p) { + return true + } + } + return false +} + +module.exports = (pkg, path) => + pkg && pkg.bin ? hasBin(pkg, path) : false diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/npm.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/npm.js new file mode 100644 index 0000000000000..a3005c255565f --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/npm.js @@ -0,0 +1,14 @@ +// run an npm command +const spawn = require('@npmcli/promise-spawn') + +module.exports = (npmBin, npmCommand, cwd, env, extra) => { + const isJS = npmBin.endsWith('.js') + const cmd = isJS ? process.execPath : npmBin + const args = (isJS ? [npmBin] : []).concat(npmCommand) + // when installing to run the `prepare` script for a git dep, we need + // to ensure that we don't run into a cycle of checking out packages + // in temp directories. this lets us link previously-seen repos that + // are also being prepared. + + return spawn(cmd, args, { cwd, env }, extra) +} diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/tar-create-options.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/tar-create-options.js new file mode 100644 index 0000000000000..d070f0f7ba2d4 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/tar-create-options.js @@ -0,0 +1,31 @@ +const isPackageBin = require('./is-package-bin.js') + +const tarCreateOptions = manifest => ({ + cwd: manifest._resolved, + prefix: 'package/', + portable: true, + gzip: { + // forcing the level to 9 seems to avoid some + // platform specific optimizations that cause + // integrity mismatch errors due to differing + // end results after compression + level: 9, + }, + + // ensure that package bins are always executable + // Note that npm-packlist is already filtering out + // anything that is not a regular file, ignored by + // .npmignore or package.json "files", etc. + filter: (path, stat) => { + if (isPackageBin(manifest, path)) { + stat.mode |= 0o111 + } + return true + }, + + // Provide a specific date in the 1980s for the benefit of zip, + // which is confounded by files dated at the Unix epoch 0. + mtime: new Date('1985-10-26T08:15:00.000Z'), +}) + +module.exports = tarCreateOptions diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/trailing-slashes.js b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/trailing-slashes.js new file mode 100644 index 0000000000000..c50cb6173b92e --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/lib/util/trailing-slashes.js @@ -0,0 +1,10 @@ +const removeTrailingSlashes = (input) => { + // in order to avoid regexp redos detection + let output = input + while (output.endsWith('/')) { + output = output.slice(0, -1) + } + return output +} + +module.exports = removeTrailingSlashes diff --git a/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/package.json b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/package.json new file mode 100644 index 0000000000000..bc8d984704af5 --- /dev/null +++ b/node_modules/@npmcli/metavuln-calculator/node_modules/pacote/package.json @@ -0,0 +1,79 @@ +{ + "name": "pacote", + "version": "15.2.0", + "description": "JavaScript package downloader", + "author": "GitHub Inc.", + "bin": { + "pacote": "lib/bin.js" + }, + "license": "ISC", + "main": "lib/index.js", + "scripts": { + "test": "tap", + "snap": "tap", + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", + "lintfix": "npm run lint -- --fix", + "posttest": "npm run lint", + "template-oss-apply": "template-oss-apply --force" + }, + "tap": { + "timeout": 300, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "devDependencies": { + "@npmcli/arborist": "^6.0.0 || ^6.0.0-pre.0", + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.14.1", + "hosted-git-info": "^6.0.0", + "mutate-fs": "^2.1.1", + "nock": "^13.2.4", + "npm-registry-mock": "^1.3.2", + "tap": "^16.0.1" + }, + "files": [ + "bin/", + "lib/" + ], + "keywords": [ + "packages", + "npm", + "git" + ], + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/pacote.git" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.14.1", + "windowsCI": false, + "publish": "true" + } +} diff --git a/node_modules/pacote/node_modules/minipass/LICENSE b/node_modules/pacote/node_modules/minipass/LICENSE new file mode 100644 index 0000000000000..97f8e32ed82e4 --- /dev/null +++ b/node_modules/pacote/node_modules/minipass/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors + +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 THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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. diff --git a/node_modules/pacote/node_modules/minipass/dist/cjs/index.js b/node_modules/pacote/node_modules/minipass/dist/cjs/index.js new file mode 100644 index 0000000000000..068c095b69793 --- /dev/null +++ b/node_modules/pacote/node_modules/minipass/dist/cjs/index.js @@ -0,0 +1,1028 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Minipass = exports.isWritable = exports.isReadable = exports.isStream = void 0; +const proc = typeof process === 'object' && process + ? process + : { + stdout: null, + stderr: null, + }; +const node_events_1 = require("node:events"); +const node_stream_1 = __importDefault(require("node:stream")); +const node_string_decoder_1 = require("node:string_decoder"); +/** + * Return true if the argument is a Minipass stream, Node stream, or something + * else that Minipass can interact with. + */ +const isStream = (s) => !!s && + typeof s === 'object' && + (s instanceof Minipass || + s instanceof node_stream_1.default || + (0, exports.isReadable)(s) || + (0, exports.isWritable)(s)); +exports.isStream = isStream; +/** + * Return true if the argument is a valid {@link Minipass.Readable} + */ +const isReadable = (s) => !!s && + typeof s === 'object' && + s instanceof node_events_1.EventEmitter && + typeof s.pipe === 'function' && + // node core Writable streams have a pipe() method, but it throws + s.pipe !== node_stream_1.default.Writable.prototype.pipe; +exports.isReadable = isReadable; +/** + * Return true if the argument is a valid {@link Minipass.Writable} + */ +const isWritable = (s) => !!s && + typeof s === 'object' && + s instanceof node_events_1.EventEmitter && + typeof s.write === 'function' && + typeof s.end === 'function'; +exports.isWritable = isWritable; +const EOF = Symbol('EOF'); +const MAYBE_EMIT_END = Symbol('maybeEmitEnd'); +const EMITTED_END = Symbol('emittedEnd'); +const EMITTING_END = Symbol('emittingEnd'); +const EMITTED_ERROR = Symbol('emittedError'); +const CLOSED = Symbol('closed'); +const READ = Symbol('read'); +const FLUSH = Symbol('flush'); +const FLUSHCHUNK = Symbol('flushChunk'); +const ENCODING = Symbol('encoding'); +const DECODER = Symbol('decoder'); +const FLOWING = Symbol('flowing'); +const PAUSED = Symbol('paused'); +const RESUME = Symbol('resume'); +const BUFFER = Symbol('buffer'); +const PIPES = Symbol('pipes'); +const BUFFERLENGTH = Symbol('bufferLength'); +const BUFFERPUSH = Symbol('bufferPush'); +const BUFFERSHIFT = Symbol('bufferShift'); +const OBJECTMODE = Symbol('objectMode'); +// internal event when stream is destroyed +const DESTROYED = Symbol('destroyed'); +// internal event when stream has an error +const ERROR = Symbol('error'); +const EMITDATA = Symbol('emitData'); +const EMITEND = Symbol('emitEnd'); +const EMITEND2 = Symbol('emitEnd2'); +const ASYNC = Symbol('async'); +const ABORT = Symbol('abort'); +const ABORTED = Symbol('aborted'); +const SIGNAL = Symbol('signal'); +const DATALISTENERS = Symbol('dataListeners'); +const DISCARDED = Symbol('discarded'); +const defer = (fn) => Promise.resolve().then(fn); +const nodefer = (fn) => fn(); +const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish'; +const isArrayBufferLike = (b) => b instanceof ArrayBuffer || + (!!b && + typeof b === 'object' && + b.constructor && + b.constructor.name === 'ArrayBuffer' && + b.byteLength >= 0); +const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b); +/** + * Internal class representing a pipe to a destination stream. + * + * @internal + */ +class Pipe { + src; + dest; + opts; + ondrain; + constructor(src, dest, opts) { + this.src = src; + this.dest = dest; + this.opts = opts; + this.ondrain = () => src[RESUME](); + this.dest.on('drain', this.ondrain); + } + unpipe() { + this.dest.removeListener('drain', this.ondrain); + } + // only here for the prototype + /* c8 ignore start */ + proxyErrors(_er) { } + /* c8 ignore stop */ + end() { + this.unpipe(); + if (this.opts.end) + this.dest.end(); + } +} +/** + * Internal class representing a pipe to a destination stream where + * errors are proxied. + * + * @internal + */ +class PipeProxyErrors extends Pipe { + unpipe() { + this.src.removeListener('error', this.proxyErrors); + super.unpipe(); + } + constructor(src, dest, opts) { + super(src, dest, opts); + this.proxyErrors = er => dest.emit('error', er); + src.on('error', this.proxyErrors); + } +} +const isObjectModeOptions = (o) => !!o.objectMode; +const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer'; +/** + * Main export, the Minipass class + * + * `RType` is the type of data emitted, defaults to Buffer + * + * `WType` is the type of data to be written, if RType is buffer or string, + * then any {@link Minipass.ContiguousData} is allowed. + * + * `Events` is the set of event handler signatures that this object + * will emit, see {@link Minipass.Events} + */ +class Minipass extends node_events_1.EventEmitter { + [FLOWING] = false; + [PAUSED] = false; + [PIPES] = []; + [BUFFER] = []; + [OBJECTMODE]; + [ENCODING]; + [ASYNC]; + [DECODER]; + [EOF] = false; + [EMITTED_END] = false; + [EMITTING_END] = false; + [CLOSED] = false; + [EMITTED_ERROR] = null; + [BUFFERLENGTH] = 0; + [DESTROYED] = false; + [SIGNAL]; + [ABORTED] = false; + [DATALISTENERS] = 0; + [DISCARDED] = false; + /** + * true if the stream can be written + */ + writable = true; + /** + * true if the stream can be read + */ + readable = true; + /** + * If `RType` is Buffer, then options do not need to be provided. + * Otherwise, an options object must be provided to specify either + * {@link Minipass.SharedOptions.objectMode} or + * {@link Minipass.SharedOptions.encoding}, as appropriate. + */ + constructor(...args) { + const options = (args[0] || + {}); + super(); + if (options.objectMode && typeof options.encoding === 'string') { + throw new TypeError('Encoding and objectMode may not be used together'); + } + if (isObjectModeOptions(options)) { + this[OBJECTMODE] = true; + this[ENCODING] = null; + } + else if (isEncodingOptions(options)) { + this[ENCODING] = options.encoding; + this[OBJECTMODE] = false; + } + else { + this[OBJECTMODE] = false; + this[ENCODING] = null; + } + this[ASYNC] = !!options.async; + this[DECODER] = this[ENCODING] + ? new node_string_decoder_1.StringDecoder(this[ENCODING]) + : null; + //@ts-ignore - private option for debugging and testing + if (options && options.debugExposeBuffer === true) { + Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] }); + } + //@ts-ignore - private option for debugging and testing + if (options && options.debugExposePipes === true) { + Object.defineProperty(this, 'pipes', { get: () => this[PIPES] }); + } + const { signal } = options; + if (signal) { + this[SIGNAL] = signal; + if (signal.aborted) { + this[ABORT](); + } + else { + signal.addEventListener('abort', () => this[ABORT]()); + } + } + } + /** + * The amount of data stored in the buffer waiting to be read. + * + * For Buffer strings, this will be the total byte length. + * For string encoding streams, this will be the string character length, + * according to JavaScript's `string.length` logic. + * For objectMode streams, this is a count of the items waiting to be + * emitted. + */ + get bufferLength() { + return this[BUFFERLENGTH]; + } + /** + * The `BufferEncoding` currently in use, or `null` + */ + get encoding() { + return this[ENCODING]; + } + /** + * @deprecated - This is a read only property + */ + set encoding(_enc) { + throw new Error('Encoding must be set at instantiation time'); + } + /** + * @deprecated - Encoding may only be set at instantiation time + */ + setEncoding(_enc) { + throw new Error('Encoding must be set at instantiation time'); + } + /** + * True if this is an objectMode stream + */ + get objectMode() { + return this[OBJECTMODE]; + } + /** + * @deprecated - This is a read-only property + */ + set objectMode(_om) { + throw new Error('objectMode must be set at instantiation time'); + } + /** + * true if this is an async stream + */ + get ['async']() { + return this[ASYNC]; + } + /** + * Set to true to make this stream async. + * + * Once set, it cannot be unset, as this would potentially cause incorrect + * behavior. Ie, a sync stream can be made async, but an async stream + * cannot be safely made sync. + */ + set ['async'](a) { + this[ASYNC] = this[ASYNC] || !!a; + } + // drop everything and get out of the flow completely + [ABORT]() { + this[ABORTED] = true; + this.emit('abort', this[SIGNAL]?.reason); + this.destroy(this[SIGNAL]?.reason); + } + /** + * True if the stream has been aborted. + */ + get aborted() { + return this[ABORTED]; + } + /** + * No-op setter. Stream aborted status is set via the AbortSignal provided + * in the constructor options. + */ + set aborted(_) { } + write(chunk, encoding, cb) { + if (this[ABORTED]) + return false; + if (this[EOF]) + throw new Error('write after end'); + if (this[DESTROYED]) { + this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' })); + return true; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = 'utf8'; + } + if (!encoding) + encoding = 'utf8'; + const fn = this[ASYNC] ? defer : nodefer; + // convert array buffers and typed array views into buffers + // at some point in the future, we may want to do the opposite! + // leave strings and buffers as-is + // anything is only allowed if in object mode, so throw + if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { + if (isArrayBufferView(chunk)) { + //@ts-ignore - sinful unsafe type changing + chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); + } + else if (isArrayBufferLike(chunk)) { + //@ts-ignore - sinful unsafe type changing + chunk = Buffer.from(chunk); + } + else if (typeof chunk !== 'string') { + throw new Error('Non-contiguous data written to non-objectMode stream'); + } + } + // handle object mode up front, since it's simpler + // this yields better performance, fewer checks later. + if (this[OBJECTMODE]) { + // maybe impossible? + /* c8 ignore start */ + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + /* c8 ignore stop */ + if (this[FLOWING]) + this.emit('data', chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + // at this point the chunk is a buffer or string + // don't buffer it up or send it to the decoder + if (!chunk.length) { + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + // fast-path writing strings of same encoding to a stream with + // an empty buffer, skipping the buffer/decoder dance + if (typeof chunk === 'string' && + // unless it is a string already ready for us to use + !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) { + //@ts-ignore - sinful unsafe type change + chunk = Buffer.from(chunk, encoding); + } + if (Buffer.isBuffer(chunk) && this[ENCODING]) { + //@ts-ignore - sinful unsafe type change + chunk = this[DECODER].write(chunk); + } + // Note: flushing CAN potentially switch us into not-flowing mode + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + if (this[FLOWING]) + this.emit('data', chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + /** + * Low-level explicit read method. + * + * In objectMode, the argument is ignored, and one item is returned if + * available. + * + * `n` is the number of bytes (or in the case of encoding streams, + * characters) to consume. If `n` is not provided, then the entire buffer + * is returned, or `null` is returned if no data is available. + * + * If `n` is greater that the amount of data in the internal buffer, + * then `null` is returned. + */ + read(n) { + if (this[DESTROYED]) + return null; + this[DISCARDED] = false; + if (this[BUFFERLENGTH] === 0 || + n === 0 || + (n && n > this[BUFFERLENGTH])) { + this[MAYBE_EMIT_END](); + return null; + } + if (this[OBJECTMODE]) + n = null; + if (this[BUFFER].length > 1 && !this[OBJECTMODE]) { + // not object mode, so if we have an encoding, then RType is string + // otherwise, must be Buffer + this[BUFFER] = [ + (this[ENCODING] + ? this[BUFFER].join('') + : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])), + ]; + } + const ret = this[READ](n || null, this[BUFFER][0]); + this[MAYBE_EMIT_END](); + return ret; + } + [READ](n, chunk) { + if (this[OBJECTMODE]) + this[BUFFERSHIFT](); + else { + const c = chunk; + if (n === c.length || n === null) + this[BUFFERSHIFT](); + else if (typeof c === 'string') { + this[BUFFER][0] = c.slice(n); + chunk = c.slice(0, n); + this[BUFFERLENGTH] -= n; + } + else { + this[BUFFER][0] = c.subarray(n); + chunk = c.subarray(0, n); + this[BUFFERLENGTH] -= n; + } + } + this.emit('data', chunk); + if (!this[BUFFER].length && !this[EOF]) + this.emit('drain'); + return chunk; + } + end(chunk, encoding, cb) { + if (typeof chunk === 'function') { + cb = chunk; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = 'utf8'; + } + if (chunk !== undefined) + this.write(chunk, encoding); + if (cb) + this.once('end', cb); + this[EOF] = true; + this.writable = false; + // if we haven't written anything, then go ahead and emit, + // even if we're not reading. + // we'll re-emit if a new 'end' listener is added anyway. + // This makes MP more suitable to write-only use cases. + if (this[FLOWING] || !this[PAUSED]) + this[MAYBE_EMIT_END](); + return this; + } + // don't let the internal resume be overwritten + [RESUME]() { + if (this[DESTROYED]) + return; + if (!this[DATALISTENERS] && !this[PIPES].length) { + this[DISCARDED] = true; + } + this[PAUSED] = false; + this[FLOWING] = true; + this.emit('resume'); + if (this[BUFFER].length) + this[FLUSH](); + else if (this[EOF]) + this[MAYBE_EMIT_END](); + else + this.emit('drain'); + } + /** + * Resume the stream if it is currently in a paused state + * + * If called when there are no pipe destinations or `data` event listeners, + * this will place the stream in a "discarded" state, where all data will + * be thrown away. The discarded state is removed if a pipe destination or + * data handler is added, if pause() is called, or if any synchronous or + * asynchronous iteration is started. + */ + resume() { + return this[RESUME](); + } + /** + * Pause the stream + */ + pause() { + this[FLOWING] = false; + this[PAUSED] = true; + this[DISCARDED] = false; + } + /** + * true if the stream has been forcibly destroyed + */ + get destroyed() { + return this[DESTROYED]; + } + /** + * true if the stream is currently in a flowing state, meaning that + * any writes will be immediately emitted. + */ + get flowing() { + return this[FLOWING]; + } + /** + * true if the stream is currently in a paused state + */ + get paused() { + return this[PAUSED]; + } + [BUFFERPUSH](chunk) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] += 1; + else + this[BUFFERLENGTH] += chunk.length; + this[BUFFER].push(chunk); + } + [BUFFERSHIFT]() { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] -= 1; + else + this[BUFFERLENGTH] -= this[BUFFER][0].length; + return this[BUFFER].shift(); + } + [FLUSH](noDrain = false) { + do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && + this[BUFFER].length); + if (!noDrain && !this[BUFFER].length && !this[EOF]) + this.emit('drain'); + } + [FLUSHCHUNK](chunk) { + this.emit('data', chunk); + return this[FLOWING]; + } + /** + * Pipe all data emitted by this stream into the destination provided. + * + * Triggers the flow of data. + */ + pipe(dest, opts) { + if (this[DESTROYED]) + return dest; + this[DISCARDED] = false; + const ended = this[EMITTED_END]; + opts = opts || {}; + if (dest === proc.stdout || dest === proc.stderr) + opts.end = false; + else + opts.end = opts.end !== false; + opts.proxyErrors = !!opts.proxyErrors; + // piping an ended stream ends immediately + if (ended) { + if (opts.end) + dest.end(); + } + else { + // "as" here just ignores the WType, which pipes don't care about, + // since they're only consuming from us, and writing to the dest + this[PIPES].push(!opts.proxyErrors + ? new Pipe(this, dest, opts) + : new PipeProxyErrors(this, dest, opts)); + if (this[ASYNC]) + defer(() => this[RESUME]()); + else + this[RESUME](); + } + return dest; + } + /** + * Fully unhook a piped destination stream. + * + * If the destination stream was the only consumer of this stream (ie, + * there are no other piped destinations or `'data'` event listeners) + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + unpipe(dest) { + const p = this[PIPES].find(p => p.dest === dest); + if (p) { + if (this[PIPES].length === 1) { + if (this[FLOWING] && this[DATALISTENERS] === 0) { + this[FLOWING] = false; + } + this[PIPES] = []; + } + else + this[PIPES].splice(this[PIPES].indexOf(p), 1); + p.unpipe(); + } + } + /** + * Alias for {@link Minipass#on} + */ + addListener(ev, handler) { + return this.on(ev, handler); + } + /** + * Mostly identical to `EventEmitter.on`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * - Adding a 'data' event handler will trigger the flow of data + * + * - Adding a 'readable' event handler when there is data waiting to be read + * will cause 'readable' to be emitted immediately. + * + * - Adding an 'endish' event handler ('end', 'finish', etc.) which has + * already passed will cause the event to be emitted immediately and all + * handlers removed. + * + * - Adding an 'error' event handler after an error has been emitted will + * cause the event to be re-emitted immediately with the error previously + * raised. + */ + on(ev, handler) { + const ret = super.on(ev, handler); + if (ev === 'data') { + this[DISCARDED] = false; + this[DATALISTENERS]++; + if (!this[PIPES].length && !this[FLOWING]) { + this[RESUME](); + } + } + else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) { + super.emit('readable'); + } + else if (isEndish(ev) && this[EMITTED_END]) { + super.emit(ev); + this.removeAllListeners(ev); + } + else if (ev === 'error' && this[EMITTED_ERROR]) { + const h = handler; + if (this[ASYNC]) + defer(() => h.call(this, this[EMITTED_ERROR])); + else + h.call(this, this[EMITTED_ERROR]); + } + return ret; + } + /** + * Alias for {@link Minipass#off} + */ + removeListener(ev, handler) { + return this.off(ev, handler); + } + /** + * Mostly identical to `EventEmitter.off` + * + * If a 'data' event handler is removed, and it was the last consumer + * (ie, there are no pipe destinations or other 'data' event listeners), + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + off(ev, handler) { + const ret = super.off(ev, handler); + // if we previously had listeners, and now we don't, and we don't + // have any pipes, then stop the flow, unless it's been explicitly + // put in a discarded flowing state via stream.resume(). + if (ev === 'data') { + this[DATALISTENERS] = this.listeners('data').length; + if (this[DATALISTENERS] === 0 && + !this[DISCARDED] && + !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * Mostly identical to `EventEmitter.removeAllListeners` + * + * If all 'data' event handlers are removed, and they were the last consumer + * (ie, there are no pipe destinations), then the flow of data will stop + * until there is another consumer or {@link Minipass#resume} is explicitly + * called. + */ + removeAllListeners(ev) { + const ret = super.removeAllListeners(ev); + if (ev === 'data' || ev === undefined) { + this[DATALISTENERS] = 0; + if (!this[DISCARDED] && !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * true if the 'end' event has been emitted + */ + get emittedEnd() { + return this[EMITTED_END]; + } + [MAYBE_EMIT_END]() { + if (!this[EMITTING_END] && + !this[EMITTED_END] && + !this[DESTROYED] && + this[BUFFER].length === 0 && + this[EOF]) { + this[EMITTING_END] = true; + this.emit('end'); + this.emit('prefinish'); + this.emit('finish'); + if (this[CLOSED]) + this.emit('close'); + this[EMITTING_END] = false; + } + } + /** + * Mostly identical to `EventEmitter.emit`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * If the stream has been destroyed, and the event is something other + * than 'close' or 'error', then `false` is returned and no handlers + * are called. + * + * If the event is 'end', and has already been emitted, then the event + * is ignored. If the stream is in a paused or non-flowing state, then + * the event will be deferred until data flow resumes. If the stream is + * async, then handlers will be called on the next tick rather than + * immediately. + * + * If the event is 'close', and 'end' has not yet been emitted, then + * the event will be deferred until after 'end' is emitted. + * + * If the event is 'error', and an AbortSignal was provided for the stream, + * and there are no listeners, then the event is ignored, matching the + * behavior of node core streams in the presense of an AbortSignal. + * + * If the event is 'finish' or 'prefinish', then all listeners will be + * removed after emitting the event, to prevent double-firing. + */ + emit(ev, ...args) { + const data = args[0]; + // error and close are only events allowed after calling destroy() + if (ev !== 'error' && + ev !== 'close' && + ev !== DESTROYED && + this[DESTROYED]) { + return false; + } + else if (ev === 'data') { + return !this[OBJECTMODE] && !data + ? false + : this[ASYNC] + ? (defer(() => this[EMITDATA](data)), true) + : this[EMITDATA](data); + } + else if (ev === 'end') { + return this[EMITEND](); + } + else if (ev === 'close') { + this[CLOSED] = true; + // don't emit close before 'end' and 'finish' + if (!this[EMITTED_END] && !this[DESTROYED]) + return false; + const ret = super.emit('close'); + this.removeAllListeners('close'); + return ret; + } + else if (ev === 'error') { + this[EMITTED_ERROR] = data; + super.emit(ERROR, data); + const ret = !this[SIGNAL] || this.listeners('error').length + ? super.emit('error', data) + : false; + this[MAYBE_EMIT_END](); + return ret; + } + else if (ev === 'resume') { + const ret = super.emit('resume'); + this[MAYBE_EMIT_END](); + return ret; + } + else if (ev === 'finish' || ev === 'prefinish') { + const ret = super.emit(ev); + this.removeAllListeners(ev); + return ret; + } + // Some other unknown event + const ret = super.emit(ev, ...args); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITDATA](data) { + for (const p of this[PIPES]) { + if (p.dest.write(data) === false) + this.pause(); + } + const ret = this[DISCARDED] ? false : super.emit('data', data); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITEND]() { + if (this[EMITTED_END]) + return false; + this[EMITTED_END] = true; + this.readable = false; + return this[ASYNC] + ? (defer(() => this[EMITEND2]()), true) + : this[EMITEND2](); + } + [EMITEND2]() { + if (this[DECODER]) { + const data = this[DECODER].end(); + if (data) { + for (const p of this[PIPES]) { + p.dest.write(data); + } + if (!this[DISCARDED]) + super.emit('data', data); + } + } + for (const p of this[PIPES]) { + p.end(); + } + const ret = super.emit('end'); + this.removeAllListeners('end'); + return ret; + } + /** + * Return a Promise that resolves to an array of all emitted data once + * the stream ends. + */ + async collect() { + const buf = Object.assign([], { + dataLength: 0, + }); + if (!this[OBJECTMODE]) + buf.dataLength = 0; + // set the promise first, in case an error is raised + // by triggering the flow here. + const p = this.promise(); + this.on('data', c => { + buf.push(c); + if (!this[OBJECTMODE]) + buf.dataLength += c.length; + }); + await p; + return buf; + } + /** + * Return a Promise that resolves to the concatenation of all emitted data + * once the stream ends. + * + * Not allowed on objectMode streams. + */ + async concat() { + if (this[OBJECTMODE]) { + throw new Error('cannot concat in objectMode'); + } + const buf = await this.collect(); + return (this[ENCODING] + ? buf.join('') + : Buffer.concat(buf, buf.dataLength)); + } + /** + * Return a void Promise that resolves once the stream ends. + */ + async promise() { + return new Promise((resolve, reject) => { + this.on(DESTROYED, () => reject(new Error('stream destroyed'))); + this.on('error', er => reject(er)); + this.on('end', () => resolve()); + }); + } + /** + * Asynchronous `for await of` iteration. + * + * This will continue emitting all chunks until the stream terminates. + */ + [Symbol.asyncIterator]() { + // set this up front, in case the consumer doesn't call next() + // right away. + this[DISCARDED] = false; + let stopped = false; + const stop = async () => { + this.pause(); + stopped = true; + return { value: undefined, done: true }; + }; + const next = () => { + if (stopped) + return stop(); + const res = this.read(); + if (res !== null) + return Promise.resolve({ done: false, value: res }); + if (this[EOF]) + return stop(); + let resolve; + let reject; + const onerr = (er) => { + this.off('data', ondata); + this.off('end', onend); + this.off(DESTROYED, ondestroy); + stop(); + reject(er); + }; + const ondata = (value) => { + this.off('error', onerr); + this.off('end', onend); + this.off(DESTROYED, ondestroy); + this.pause(); + resolve({ value, done: !!this[EOF] }); + }; + const onend = () => { + this.off('error', onerr); + this.off('data', ondata); + this.off(DESTROYED, ondestroy); + stop(); + resolve({ done: true, value: undefined }); + }; + const ondestroy = () => onerr(new Error('stream destroyed')); + return new Promise((res, rej) => { + reject = rej; + resolve = res; + this.once(DESTROYED, ondestroy); + this.once('error', onerr); + this.once('end', onend); + this.once('data', ondata); + }); + }; + return { + next, + throw: stop, + return: stop, + [Symbol.asyncIterator]() { + return this; + }, + }; + } + /** + * Synchronous `for of` iteration. + * + * The iteration will terminate when the internal buffer runs out, even + * if the stream has not yet terminated. + */ + [Symbol.iterator]() { + // set this up front, in case the consumer doesn't call next() + // right away. + this[DISCARDED] = false; + let stopped = false; + const stop = () => { + this.pause(); + this.off(ERROR, stop); + this.off(DESTROYED, stop); + this.off('end', stop); + stopped = true; + return { done: true, value: undefined }; + }; + const next = () => { + if (stopped) + return stop(); + const value = this.read(); + return value === null ? stop() : { done: false, value }; + }; + this.once('end', stop); + this.once(ERROR, stop); + this.once(DESTROYED, stop); + return { + next, + throw: stop, + return: stop, + [Symbol.iterator]() { + return this; + }, + }; + } + /** + * Destroy a stream, preventing it from being used for any further purpose. + * + * If the stream has a `close()` method, then it will be called on + * destruction. + * + * After destruction, any attempt to write data, read data, or emit most + * events will be ignored. + * + * If an error argument is provided, then it will be emitted in an + * 'error' event. + */ + destroy(er) { + if (this[DESTROYED]) { + if (er) + this.emit('error', er); + else + this.emit(DESTROYED); + return this; + } + this[DESTROYED] = true; + this[DISCARDED] = true; + // throw away all buffered data, it's never coming out + this[BUFFER].length = 0; + this[BUFFERLENGTH] = 0; + const wc = this; + if (typeof wc.close === 'function' && !this[CLOSED]) + wc.close(); + if (er) + this.emit('error', er); + // if no error to emit, still reject pending promises + else + this.emit(DESTROYED); + return this; + } + /** + * Alias for {@link isStream} + * + * Former export location, maintained for backwards compatibility. + * + * @deprecated + */ + static get isStream() { + return exports.isStream; + } +} +exports.Minipass = Minipass; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/pacote/node_modules/minipass/dist/cjs/package.json b/node_modules/pacote/node_modules/minipass/dist/cjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/pacote/node_modules/minipass/dist/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/pacote/node_modules/minipass/dist/mjs/index.js b/node_modules/pacote/node_modules/minipass/dist/mjs/index.js new file mode 100644 index 0000000000000..b5fa4513c9083 --- /dev/null +++ b/node_modules/pacote/node_modules/minipass/dist/mjs/index.js @@ -0,0 +1,1018 @@ +const proc = typeof process === 'object' && process + ? process + : { + stdout: null, + stderr: null, + }; +import { EventEmitter } from 'node:events'; +import Stream from 'node:stream'; +import { StringDecoder } from 'node:string_decoder'; +/** + * Return true if the argument is a Minipass stream, Node stream, or something + * else that Minipass can interact with. + */ +export const isStream = (s) => !!s && + typeof s === 'object' && + (s instanceof Minipass || + s instanceof Stream || + isReadable(s) || + isWritable(s)); +/** + * Return true if the argument is a valid {@link Minipass.Readable} + */ +export const isReadable = (s) => !!s && + typeof s === 'object' && + s instanceof EventEmitter && + typeof s.pipe === 'function' && + // node core Writable streams have a pipe() method, but it throws + s.pipe !== Stream.Writable.prototype.pipe; +/** + * Return true if the argument is a valid {@link Minipass.Writable} + */ +export const isWritable = (s) => !!s && + typeof s === 'object' && + s instanceof EventEmitter && + typeof s.write === 'function' && + typeof s.end === 'function'; +const EOF = Symbol('EOF'); +const MAYBE_EMIT_END = Symbol('maybeEmitEnd'); +const EMITTED_END = Symbol('emittedEnd'); +const EMITTING_END = Symbol('emittingEnd'); +const EMITTED_ERROR = Symbol('emittedError'); +const CLOSED = Symbol('closed'); +const READ = Symbol('read'); +const FLUSH = Symbol('flush'); +const FLUSHCHUNK = Symbol('flushChunk'); +const ENCODING = Symbol('encoding'); +const DECODER = Symbol('decoder'); +const FLOWING = Symbol('flowing'); +const PAUSED = Symbol('paused'); +const RESUME = Symbol('resume'); +const BUFFER = Symbol('buffer'); +const PIPES = Symbol('pipes'); +const BUFFERLENGTH = Symbol('bufferLength'); +const BUFFERPUSH = Symbol('bufferPush'); +const BUFFERSHIFT = Symbol('bufferShift'); +const OBJECTMODE = Symbol('objectMode'); +// internal event when stream is destroyed +const DESTROYED = Symbol('destroyed'); +// internal event when stream has an error +const ERROR = Symbol('error'); +const EMITDATA = Symbol('emitData'); +const EMITEND = Symbol('emitEnd'); +const EMITEND2 = Symbol('emitEnd2'); +const ASYNC = Symbol('async'); +const ABORT = Symbol('abort'); +const ABORTED = Symbol('aborted'); +const SIGNAL = Symbol('signal'); +const DATALISTENERS = Symbol('dataListeners'); +const DISCARDED = Symbol('discarded'); +const defer = (fn) => Promise.resolve().then(fn); +const nodefer = (fn) => fn(); +const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish'; +const isArrayBufferLike = (b) => b instanceof ArrayBuffer || + (!!b && + typeof b === 'object' && + b.constructor && + b.constructor.name === 'ArrayBuffer' && + b.byteLength >= 0); +const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b); +/** + * Internal class representing a pipe to a destination stream. + * + * @internal + */ +class Pipe { + src; + dest; + opts; + ondrain; + constructor(src, dest, opts) { + this.src = src; + this.dest = dest; + this.opts = opts; + this.ondrain = () => src[RESUME](); + this.dest.on('drain', this.ondrain); + } + unpipe() { + this.dest.removeListener('drain', this.ondrain); + } + // only here for the prototype + /* c8 ignore start */ + proxyErrors(_er) { } + /* c8 ignore stop */ + end() { + this.unpipe(); + if (this.opts.end) + this.dest.end(); + } +} +/** + * Internal class representing a pipe to a destination stream where + * errors are proxied. + * + * @internal + */ +class PipeProxyErrors extends Pipe { + unpipe() { + this.src.removeListener('error', this.proxyErrors); + super.unpipe(); + } + constructor(src, dest, opts) { + super(src, dest, opts); + this.proxyErrors = er => dest.emit('error', er); + src.on('error', this.proxyErrors); + } +} +const isObjectModeOptions = (o) => !!o.objectMode; +const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer'; +/** + * Main export, the Minipass class + * + * `RType` is the type of data emitted, defaults to Buffer + * + * `WType` is the type of data to be written, if RType is buffer or string, + * then any {@link Minipass.ContiguousData} is allowed. + * + * `Events` is the set of event handler signatures that this object + * will emit, see {@link Minipass.Events} + */ +export class Minipass extends EventEmitter { + [FLOWING] = false; + [PAUSED] = false; + [PIPES] = []; + [BUFFER] = []; + [OBJECTMODE]; + [ENCODING]; + [ASYNC]; + [DECODER]; + [EOF] = false; + [EMITTED_END] = false; + [EMITTING_END] = false; + [CLOSED] = false; + [EMITTED_ERROR] = null; + [BUFFERLENGTH] = 0; + [DESTROYED] = false; + [SIGNAL]; + [ABORTED] = false; + [DATALISTENERS] = 0; + [DISCARDED] = false; + /** + * true if the stream can be written + */ + writable = true; + /** + * true if the stream can be read + */ + readable = true; + /** + * If `RType` is Buffer, then options do not need to be provided. + * Otherwise, an options object must be provided to specify either + * {@link Minipass.SharedOptions.objectMode} or + * {@link Minipass.SharedOptions.encoding}, as appropriate. + */ + constructor(...args) { + const options = (args[0] || + {}); + super(); + if (options.objectMode && typeof options.encoding === 'string') { + throw new TypeError('Encoding and objectMode may not be used together'); + } + if (isObjectModeOptions(options)) { + this[OBJECTMODE] = true; + this[ENCODING] = null; + } + else if (isEncodingOptions(options)) { + this[ENCODING] = options.encoding; + this[OBJECTMODE] = false; + } + else { + this[OBJECTMODE] = false; + this[ENCODING] = null; + } + this[ASYNC] = !!options.async; + this[DECODER] = this[ENCODING] + ? new StringDecoder(this[ENCODING]) + : null; + //@ts-ignore - private option for debugging and testing + if (options && options.debugExposeBuffer === true) { + Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] }); + } + //@ts-ignore - private option for debugging and testing + if (options && options.debugExposePipes === true) { + Object.defineProperty(this, 'pipes', { get: () => this[PIPES] }); + } + const { signal } = options; + if (signal) { + this[SIGNAL] = signal; + if (signal.aborted) { + this[ABORT](); + } + else { + signal.addEventListener('abort', () => this[ABORT]()); + } + } + } + /** + * The amount of data stored in the buffer waiting to be read. + * + * For Buffer strings, this will be the total byte length. + * For string encoding streams, this will be the string character length, + * according to JavaScript's `string.length` logic. + * For objectMode streams, this is a count of the items waiting to be + * emitted. + */ + get bufferLength() { + return this[BUFFERLENGTH]; + } + /** + * The `BufferEncoding` currently in use, or `null` + */ + get encoding() { + return this[ENCODING]; + } + /** + * @deprecated - This is a read only property + */ + set encoding(_enc) { + throw new Error('Encoding must be set at instantiation time'); + } + /** + * @deprecated - Encoding may only be set at instantiation time + */ + setEncoding(_enc) { + throw new Error('Encoding must be set at instantiation time'); + } + /** + * True if this is an objectMode stream + */ + get objectMode() { + return this[OBJECTMODE]; + } + /** + * @deprecated - This is a read-only property + */ + set objectMode(_om) { + throw new Error('objectMode must be set at instantiation time'); + } + /** + * true if this is an async stream + */ + get ['async']() { + return this[ASYNC]; + } + /** + * Set to true to make this stream async. + * + * Once set, it cannot be unset, as this would potentially cause incorrect + * behavior. Ie, a sync stream can be made async, but an async stream + * cannot be safely made sync. + */ + set ['async'](a) { + this[ASYNC] = this[ASYNC] || !!a; + } + // drop everything and get out of the flow completely + [ABORT]() { + this[ABORTED] = true; + this.emit('abort', this[SIGNAL]?.reason); + this.destroy(this[SIGNAL]?.reason); + } + /** + * True if the stream has been aborted. + */ + get aborted() { + return this[ABORTED]; + } + /** + * No-op setter. Stream aborted status is set via the AbortSignal provided + * in the constructor options. + */ + set aborted(_) { } + write(chunk, encoding, cb) { + if (this[ABORTED]) + return false; + if (this[EOF]) + throw new Error('write after end'); + if (this[DESTROYED]) { + this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' })); + return true; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = 'utf8'; + } + if (!encoding) + encoding = 'utf8'; + const fn = this[ASYNC] ? defer : nodefer; + // convert array buffers and typed array views into buffers + // at some point in the future, we may want to do the opposite! + // leave strings and buffers as-is + // anything is only allowed if in object mode, so throw + if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { + if (isArrayBufferView(chunk)) { + //@ts-ignore - sinful unsafe type changing + chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); + } + else if (isArrayBufferLike(chunk)) { + //@ts-ignore - sinful unsafe type changing + chunk = Buffer.from(chunk); + } + else if (typeof chunk !== 'string') { + throw new Error('Non-contiguous data written to non-objectMode stream'); + } + } + // handle object mode up front, since it's simpler + // this yields better performance, fewer checks later. + if (this[OBJECTMODE]) { + // maybe impossible? + /* c8 ignore start */ + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + /* c8 ignore stop */ + if (this[FLOWING]) + this.emit('data', chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + // at this point the chunk is a buffer or string + // don't buffer it up or send it to the decoder + if (!chunk.length) { + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + // fast-path writing strings of same encoding to a stream with + // an empty buffer, skipping the buffer/decoder dance + if (typeof chunk === 'string' && + // unless it is a string already ready for us to use + !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) { + //@ts-ignore - sinful unsafe type change + chunk = Buffer.from(chunk, encoding); + } + if (Buffer.isBuffer(chunk) && this[ENCODING]) { + //@ts-ignore - sinful unsafe type change + chunk = this[DECODER].write(chunk); + } + // Note: flushing CAN potentially switch us into not-flowing mode + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + if (this[FLOWING]) + this.emit('data', chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + /** + * Low-level explicit read method. + * + * In objectMode, the argument is ignored, and one item is returned if + * available. + * + * `n` is the number of bytes (or in the case of encoding streams, + * characters) to consume. If `n` is not provided, then the entire buffer + * is returned, or `null` is returned if no data is available. + * + * If `n` is greater that the amount of data in the internal buffer, + * then `null` is returned. + */ + read(n) { + if (this[DESTROYED]) + return null; + this[DISCARDED] = false; + if (this[BUFFERLENGTH] === 0 || + n === 0 || + (n && n > this[BUFFERLENGTH])) { + this[MAYBE_EMIT_END](); + return null; + } + if (this[OBJECTMODE]) + n = null; + if (this[BUFFER].length > 1 && !this[OBJECTMODE]) { + // not object mode, so if we have an encoding, then RType is string + // otherwise, must be Buffer + this[BUFFER] = [ + (this[ENCODING] + ? this[BUFFER].join('') + : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])), + ]; + } + const ret = this[READ](n || null, this[BUFFER][0]); + this[MAYBE_EMIT_END](); + return ret; + } + [READ](n, chunk) { + if (this[OBJECTMODE]) + this[BUFFERSHIFT](); + else { + const c = chunk; + if (n === c.length || n === null) + this[BUFFERSHIFT](); + else if (typeof c === 'string') { + this[BUFFER][0] = c.slice(n); + chunk = c.slice(0, n); + this[BUFFERLENGTH] -= n; + } + else { + this[BUFFER][0] = c.subarray(n); + chunk = c.subarray(0, n); + this[BUFFERLENGTH] -= n; + } + } + this.emit('data', chunk); + if (!this[BUFFER].length && !this[EOF]) + this.emit('drain'); + return chunk; + } + end(chunk, encoding, cb) { + if (typeof chunk === 'function') { + cb = chunk; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = 'utf8'; + } + if (chunk !== undefined) + this.write(chunk, encoding); + if (cb) + this.once('end', cb); + this[EOF] = true; + this.writable = false; + // if we haven't written anything, then go ahead and emit, + // even if we're not reading. + // we'll re-emit if a new 'end' listener is added anyway. + // This makes MP more suitable to write-only use cases. + if (this[FLOWING] || !this[PAUSED]) + this[MAYBE_EMIT_END](); + return this; + } + // don't let the internal resume be overwritten + [RESUME]() { + if (this[DESTROYED]) + return; + if (!this[DATALISTENERS] && !this[PIPES].length) { + this[DISCARDED] = true; + } + this[PAUSED] = false; + this[FLOWING] = true; + this.emit('resume'); + if (this[BUFFER].length) + this[FLUSH](); + else if (this[EOF]) + this[MAYBE_EMIT_END](); + else + this.emit('drain'); + } + /** + * Resume the stream if it is currently in a paused state + * + * If called when there are no pipe destinations or `data` event listeners, + * this will place the stream in a "discarded" state, where all data will + * be thrown away. The discarded state is removed if a pipe destination or + * data handler is added, if pause() is called, or if any synchronous or + * asynchronous iteration is started. + */ + resume() { + return this[RESUME](); + } + /** + * Pause the stream + */ + pause() { + this[FLOWING] = false; + this[PAUSED] = true; + this[DISCARDED] = false; + } + /** + * true if the stream has been forcibly destroyed + */ + get destroyed() { + return this[DESTROYED]; + } + /** + * true if the stream is currently in a flowing state, meaning that + * any writes will be immediately emitted. + */ + get flowing() { + return this[FLOWING]; + } + /** + * true if the stream is currently in a paused state + */ + get paused() { + return this[PAUSED]; + } + [BUFFERPUSH](chunk) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] += 1; + else + this[BUFFERLENGTH] += chunk.length; + this[BUFFER].push(chunk); + } + [BUFFERSHIFT]() { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] -= 1; + else + this[BUFFERLENGTH] -= this[BUFFER][0].length; + return this[BUFFER].shift(); + } + [FLUSH](noDrain = false) { + do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && + this[BUFFER].length); + if (!noDrain && !this[BUFFER].length && !this[EOF]) + this.emit('drain'); + } + [FLUSHCHUNK](chunk) { + this.emit('data', chunk); + return this[FLOWING]; + } + /** + * Pipe all data emitted by this stream into the destination provided. + * + * Triggers the flow of data. + */ + pipe(dest, opts) { + if (this[DESTROYED]) + return dest; + this[DISCARDED] = false; + const ended = this[EMITTED_END]; + opts = opts || {}; + if (dest === proc.stdout || dest === proc.stderr) + opts.end = false; + else + opts.end = opts.end !== false; + opts.proxyErrors = !!opts.proxyErrors; + // piping an ended stream ends immediately + if (ended) { + if (opts.end) + dest.end(); + } + else { + // "as" here just ignores the WType, which pipes don't care about, + // since they're only consuming from us, and writing to the dest + this[PIPES].push(!opts.proxyErrors + ? new Pipe(this, dest, opts) + : new PipeProxyErrors(this, dest, opts)); + if (this[ASYNC]) + defer(() => this[RESUME]()); + else + this[RESUME](); + } + return dest; + } + /** + * Fully unhook a piped destination stream. + * + * If the destination stream was the only consumer of this stream (ie, + * there are no other piped destinations or `'data'` event listeners) + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + unpipe(dest) { + const p = this[PIPES].find(p => p.dest === dest); + if (p) { + if (this[PIPES].length === 1) { + if (this[FLOWING] && this[DATALISTENERS] === 0) { + this[FLOWING] = false; + } + this[PIPES] = []; + } + else + this[PIPES].splice(this[PIPES].indexOf(p), 1); + p.unpipe(); + } + } + /** + * Alias for {@link Minipass#on} + */ + addListener(ev, handler) { + return this.on(ev, handler); + } + /** + * Mostly identical to `EventEmitter.on`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * - Adding a 'data' event handler will trigger the flow of data + * + * - Adding a 'readable' event handler when there is data waiting to be read + * will cause 'readable' to be emitted immediately. + * + * - Adding an 'endish' event handler ('end', 'finish', etc.) which has + * already passed will cause the event to be emitted immediately and all + * handlers removed. + * + * - Adding an 'error' event handler after an error has been emitted will + * cause the event to be re-emitted immediately with the error previously + * raised. + */ + on(ev, handler) { + const ret = super.on(ev, handler); + if (ev === 'data') { + this[DISCARDED] = false; + this[DATALISTENERS]++; + if (!this[PIPES].length && !this[FLOWING]) { + this[RESUME](); + } + } + else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) { + super.emit('readable'); + } + else if (isEndish(ev) && this[EMITTED_END]) { + super.emit(ev); + this.removeAllListeners(ev); + } + else if (ev === 'error' && this[EMITTED_ERROR]) { + const h = handler; + if (this[ASYNC]) + defer(() => h.call(this, this[EMITTED_ERROR])); + else + h.call(this, this[EMITTED_ERROR]); + } + return ret; + } + /** + * Alias for {@link Minipass#off} + */ + removeListener(ev, handler) { + return this.off(ev, handler); + } + /** + * Mostly identical to `EventEmitter.off` + * + * If a 'data' event handler is removed, and it was the last consumer + * (ie, there are no pipe destinations or other 'data' event listeners), + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + off(ev, handler) { + const ret = super.off(ev, handler); + // if we previously had listeners, and now we don't, and we don't + // have any pipes, then stop the flow, unless it's been explicitly + // put in a discarded flowing state via stream.resume(). + if (ev === 'data') { + this[DATALISTENERS] = this.listeners('data').length; + if (this[DATALISTENERS] === 0 && + !this[DISCARDED] && + !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * Mostly identical to `EventEmitter.removeAllListeners` + * + * If all 'data' event handlers are removed, and they were the last consumer + * (ie, there are no pipe destinations), then the flow of data will stop + * until there is another consumer or {@link Minipass#resume} is explicitly + * called. + */ + removeAllListeners(ev) { + const ret = super.removeAllListeners(ev); + if (ev === 'data' || ev === undefined) { + this[DATALISTENERS] = 0; + if (!this[DISCARDED] && !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * true if the 'end' event has been emitted + */ + get emittedEnd() { + return this[EMITTED_END]; + } + [MAYBE_EMIT_END]() { + if (!this[EMITTING_END] && + !this[EMITTED_END] && + !this[DESTROYED] && + this[BUFFER].length === 0 && + this[EOF]) { + this[EMITTING_END] = true; + this.emit('end'); + this.emit('prefinish'); + this.emit('finish'); + if (this[CLOSED]) + this.emit('close'); + this[EMITTING_END] = false; + } + } + /** + * Mostly identical to `EventEmitter.emit`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * If the stream has been destroyed, and the event is something other + * than 'close' or 'error', then `false` is returned and no handlers + * are called. + * + * If the event is 'end', and has already been emitted, then the event + * is ignored. If the stream is in a paused or non-flowing state, then + * the event will be deferred until data flow resumes. If the stream is + * async, then handlers will be called on the next tick rather than + * immediately. + * + * If the event is 'close', and 'end' has not yet been emitted, then + * the event will be deferred until after 'end' is emitted. + * + * If the event is 'error', and an AbortSignal was provided for the stream, + * and there are no listeners, then the event is ignored, matching the + * behavior of node core streams in the presense of an AbortSignal. + * + * If the event is 'finish' or 'prefinish', then all listeners will be + * removed after emitting the event, to prevent double-firing. + */ + emit(ev, ...args) { + const data = args[0]; + // error and close are only events allowed after calling destroy() + if (ev !== 'error' && + ev !== 'close' && + ev !== DESTROYED && + this[DESTROYED]) { + return false; + } + else if (ev === 'data') { + return !this[OBJECTMODE] && !data + ? false + : this[ASYNC] + ? (defer(() => this[EMITDATA](data)), true) + : this[EMITDATA](data); + } + else if (ev === 'end') { + return this[EMITEND](); + } + else if (ev === 'close') { + this[CLOSED] = true; + // don't emit close before 'end' and 'finish' + if (!this[EMITTED_END] && !this[DESTROYED]) + return false; + const ret = super.emit('close'); + this.removeAllListeners('close'); + return ret; + } + else if (ev === 'error') { + this[EMITTED_ERROR] = data; + super.emit(ERROR, data); + const ret = !this[SIGNAL] || this.listeners('error').length + ? super.emit('error', data) + : false; + this[MAYBE_EMIT_END](); + return ret; + } + else if (ev === 'resume') { + const ret = super.emit('resume'); + this[MAYBE_EMIT_END](); + return ret; + } + else if (ev === 'finish' || ev === 'prefinish') { + const ret = super.emit(ev); + this.removeAllListeners(ev); + return ret; + } + // Some other unknown event + const ret = super.emit(ev, ...args); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITDATA](data) { + for (const p of this[PIPES]) { + if (p.dest.write(data) === false) + this.pause(); + } + const ret = this[DISCARDED] ? false : super.emit('data', data); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITEND]() { + if (this[EMITTED_END]) + return false; + this[EMITTED_END] = true; + this.readable = false; + return this[ASYNC] + ? (defer(() => this[EMITEND2]()), true) + : this[EMITEND2](); + } + [EMITEND2]() { + if (this[DECODER]) { + const data = this[DECODER].end(); + if (data) { + for (const p of this[PIPES]) { + p.dest.write(data); + } + if (!this[DISCARDED]) + super.emit('data', data); + } + } + for (const p of this[PIPES]) { + p.end(); + } + const ret = super.emit('end'); + this.removeAllListeners('end'); + return ret; + } + /** + * Return a Promise that resolves to an array of all emitted data once + * the stream ends. + */ + async collect() { + const buf = Object.assign([], { + dataLength: 0, + }); + if (!this[OBJECTMODE]) + buf.dataLength = 0; + // set the promise first, in case an error is raised + // by triggering the flow here. + const p = this.promise(); + this.on('data', c => { + buf.push(c); + if (!this[OBJECTMODE]) + buf.dataLength += c.length; + }); + await p; + return buf; + } + /** + * Return a Promise that resolves to the concatenation of all emitted data + * once the stream ends. + * + * Not allowed on objectMode streams. + */ + async concat() { + if (this[OBJECTMODE]) { + throw new Error('cannot concat in objectMode'); + } + const buf = await this.collect(); + return (this[ENCODING] + ? buf.join('') + : Buffer.concat(buf, buf.dataLength)); + } + /** + * Return a void Promise that resolves once the stream ends. + */ + async promise() { + return new Promise((resolve, reject) => { + this.on(DESTROYED, () => reject(new Error('stream destroyed'))); + this.on('error', er => reject(er)); + this.on('end', () => resolve()); + }); + } + /** + * Asynchronous `for await of` iteration. + * + * This will continue emitting all chunks until the stream terminates. + */ + [Symbol.asyncIterator]() { + // set this up front, in case the consumer doesn't call next() + // right away. + this[DISCARDED] = false; + let stopped = false; + const stop = async () => { + this.pause(); + stopped = true; + return { value: undefined, done: true }; + }; + const next = () => { + if (stopped) + return stop(); + const res = this.read(); + if (res !== null) + return Promise.resolve({ done: false, value: res }); + if (this[EOF]) + return stop(); + let resolve; + let reject; + const onerr = (er) => { + this.off('data', ondata); + this.off('end', onend); + this.off(DESTROYED, ondestroy); + stop(); + reject(er); + }; + const ondata = (value) => { + this.off('error', onerr); + this.off('end', onend); + this.off(DESTROYED, ondestroy); + this.pause(); + resolve({ value, done: !!this[EOF] }); + }; + const onend = () => { + this.off('error', onerr); + this.off('data', ondata); + this.off(DESTROYED, ondestroy); + stop(); + resolve({ done: true, value: undefined }); + }; + const ondestroy = () => onerr(new Error('stream destroyed')); + return new Promise((res, rej) => { + reject = rej; + resolve = res; + this.once(DESTROYED, ondestroy); + this.once('error', onerr); + this.once('end', onend); + this.once('data', ondata); + }); + }; + return { + next, + throw: stop, + return: stop, + [Symbol.asyncIterator]() { + return this; + }, + }; + } + /** + * Synchronous `for of` iteration. + * + * The iteration will terminate when the internal buffer runs out, even + * if the stream has not yet terminated. + */ + [Symbol.iterator]() { + // set this up front, in case the consumer doesn't call next() + // right away. + this[DISCARDED] = false; + let stopped = false; + const stop = () => { + this.pause(); + this.off(ERROR, stop); + this.off(DESTROYED, stop); + this.off('end', stop); + stopped = true; + return { done: true, value: undefined }; + }; + const next = () => { + if (stopped) + return stop(); + const value = this.read(); + return value === null ? stop() : { done: false, value }; + }; + this.once('end', stop); + this.once(ERROR, stop); + this.once(DESTROYED, stop); + return { + next, + throw: stop, + return: stop, + [Symbol.iterator]() { + return this; + }, + }; + } + /** + * Destroy a stream, preventing it from being used for any further purpose. + * + * If the stream has a `close()` method, then it will be called on + * destruction. + * + * After destruction, any attempt to write data, read data, or emit most + * events will be ignored. + * + * If an error argument is provided, then it will be emitted in an + * 'error' event. + */ + destroy(er) { + if (this[DESTROYED]) { + if (er) + this.emit('error', er); + else + this.emit(DESTROYED); + return this; + } + this[DESTROYED] = true; + this[DISCARDED] = true; + // throw away all buffered data, it's never coming out + this[BUFFER].length = 0; + this[BUFFERLENGTH] = 0; + const wc = this; + if (typeof wc.close === 'function' && !this[CLOSED]) + wc.close(); + if (er) + this.emit('error', er); + // if no error to emit, still reject pending promises + else + this.emit(DESTROYED); + return this; + } + /** + * Alias for {@link isStream} + * + * Former export location, maintained for backwards compatibility. + * + * @deprecated + */ + static get isStream() { + return isStream; + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/pacote/node_modules/minipass/dist/mjs/package.json b/node_modules/pacote/node_modules/minipass/dist/mjs/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/pacote/node_modules/minipass/dist/mjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/pacote/node_modules/minipass/package.json b/node_modules/pacote/node_modules/minipass/package.json new file mode 100644 index 0000000000000..355501c0a10c1 --- /dev/null +++ b/node_modules/pacote/node_modules/minipass/package.json @@ -0,0 +1,82 @@ +{ + "name": "minipass", + "version": "7.0.2", + "description": "minimal implementation of a PassThrough stream", + "main": "./dist/cjs/index.js", + "module": "./dist/mjs/index.js", + "types": "./dist/cjs/index.js", + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./package.json": "./package.json" + }, + "files": [ + "dist" + ], + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" + }, + "tap": { + "coverage": false, + "node-arg": [ + "--enable-source-maps", + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false + }, + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "devDependencies": { + "@types/node": "^20.1.2", + "@types/tap": "^15.0.8", + "c8": "^7.13.0", + "prettier": "^2.6.2", + "tap": "^16.3.0", + "ts-node": "^10.9.1", + "typedoc": "^0.24.8", + "typescript": "^5.1.3", + "end-of-stream": "^1.4.0", + "node-abort-controller": "^3.1.1", + "sync-content": "^1.0.2", + "through2": "^2.0.3" + }, + "repository": "https://github.com/isaacs/minipass", + "keywords": [ + "passthrough", + "stream" + ], + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } +} diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json index bc8d984704af5..d9119065bfc3d 100644 --- a/node_modules/pacote/package.json +++ b/node_modules/pacote/package.json @@ -1,6 +1,6 @@ { "name": "pacote", - "version": "15.2.0", + "version": "16.0.0", "description": "JavaScript package downloader", "author": "GitHub Inc.", "bin": { @@ -27,7 +27,7 @@ "devDependencies": { "@npmcli/arborist": "^6.0.0 || ^6.0.0-pre.0", "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.14.1", + "@npmcli/template-oss": "4.18.0", "hosted-git-info": "^6.0.0", "mutate-fs": "^2.1.1", "nock": "^13.2.4", @@ -50,11 +50,11 @@ "@npmcli/run-script": "^6.0.0", "cacache": "^17.0.0", "fs-minipass": "^3.0.0", - "minipass": "^5.0.0", + "minipass": "^7.0.2", "npm-package-arg": "^10.0.0", "npm-packlist": "^7.0.0", "npm-pick-manifest": "^8.0.0", - "npm-registry-fetch": "^14.0.0", + "npm-registry-fetch": "^15.0.0", "proc-log": "^3.0.0", "promise-retry": "^2.0.1", "read-package-json": "^6.0.0", @@ -64,7 +64,7 @@ "tar": "^6.1.11" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" }, "repository": { "type": "git", @@ -72,7 +72,13 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.14.1", + "ciVersions": [ + "16.13.0", + "16.x", + "18.0.0", + "18.x" + ], + "version": "4.18.0", "windowsCI": false, "publish": "true" } diff --git a/package-lock.json b/package-lock.json index c0c42086d1b01..3975fe8881dd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -138,7 +138,7 @@ "npm-user-validate": "^2.0.0", "npmlog": "^7.0.1", "p-map": "^4.0.0", - "pacote": "^15.2.0", + "pacote": "^16.0.0", "parse-conflict-json": "^3.0.1", "proc-log": "^3.0.0", "qrcode-terminal": "^0.12.0", @@ -230,7 +230,7 @@ "json-stringify-safe": "^5.0.1", "nock": "^13.3.0", "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8", + "pacote": "^16.0.0", "tap": "^16.3.4" }, "engines": { @@ -2473,6 +2473,54 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@npmcli/metavuln-calculator/node_modules/npm-registry-fetch": { + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", + "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@npmcli/mock-globals": { "resolved": "mock-globals", "link": true @@ -10219,9 +10267,9 @@ } }, "node_modules/pacote": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", - "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-16.0.0.tgz", + "integrity": "sha512-tXeSsl21IUIzw/zW0rzK/po2zlI5Nqbkpu0V6Pv99f3leHde7zdv+VjuP9pnVeTVV7OvaS49u+lgmvXjQ0TMJQ==", "inBundle": true, "dependencies": { "@npmcli/git": "^4.0.0", @@ -10230,11 +10278,11 @@ "@npmcli/run-script": "^6.0.0", "cacache": "^17.0.0", "fs-minipass": "^3.0.0", - "minipass": "^5.0.0", + "minipass": "^7.0.2", "npm-package-arg": "^10.0.0", "npm-packlist": "^7.0.0", "npm-pick-manifest": "^8.0.0", - "npm-registry-fetch": "^14.0.0", + "npm-registry-fetch": "^15.0.0", "proc-log": "^3.0.0", "promise-retry": "^2.0.1", "read-package-json": "^6.0.0", @@ -10247,25 +10295,16 @@ "pacote": "lib/bin.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, - "node_modules/pacote/node_modules/npm-registry-fetch": { - "version": "14.0.5", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", - "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "node_modules/pacote/node_modules/minipass": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.2.tgz", + "integrity": "sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA==", "inBundle": true, - "dependencies": { - "make-fetch-happen": "^11.0.0", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^10.0.0", - "proc-log": "^3.0.0" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=16 || 14 >=14.17" } }, "node_modules/parent-module": { @@ -15712,7 +15751,7 @@ "npm-pick-manifest": "^8.0.1", "npm-registry-fetch": "^15.0.0", "npmlog": "^7.0.1", - "pacote": "^15.0.8", + "pacote": "^16.0.0", "parse-conflict-json": "^3.0.0", "proc-log": "^3.0.0", "promise-all-reject-late": "^1.0.0", @@ -15737,7 +15776,7 @@ "tcompare": "^5.0.6" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "workspaces/config": { @@ -15779,7 +15818,7 @@ "tap": "^16.3.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "workspaces/libnpmdiff": { @@ -15793,7 +15832,7 @@ "diff": "^5.1.0", "minimatch": "^9.0.0", "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8", + "pacote": "^16.0.0", "tar": "^6.1.13" }, "devDependencies": { @@ -15814,7 +15853,7 @@ "ci-info": "^3.7.1", "npm-package-arg": "^10.1.0", "npmlog": "^7.0.1", - "pacote": "^15.0.8", + "pacote": "^16.0.0", "proc-log": "^3.0.0", "read": "^2.0.0", "read-package-json-fast": "^3.0.2", @@ -15864,7 +15903,7 @@ "tap": "^16.3.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "workspaces/libnpmorg": { @@ -15882,7 +15921,7 @@ "tap": "^16.3.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "workspaces/libnpmpack": { @@ -15892,7 +15931,7 @@ "@npmcli/arborist": "^6.3.0", "@npmcli/run-script": "^6.0.0", "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8" + "pacote": "^16.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", @@ -15927,7 +15966,7 @@ "tap": "^16.3.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "workspaces/libnpmsearch": { @@ -15943,7 +15982,7 @@ "tap": "^16.3.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "workspaces/libnpmteam": { @@ -15960,7 +15999,7 @@ "tap": "^16.3.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "workspaces/libnpmversion": { diff --git a/package.json b/package.json index d0e0cd2e3ea5e..8ab1f82e62799 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "npm-user-validate": "^2.0.0", "npmlog": "^7.0.1", "p-map": "^4.0.0", - "pacote": "^15.2.0", + "pacote": "^16.0.0", "parse-conflict-json": "^3.0.1", "proc-log": "^3.0.0", "qrcode-terminal": "^0.12.0", diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index 923b9004dcfd5..32e319f0a38ea 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -26,7 +26,7 @@ "npm-pick-manifest": "^8.0.1", "npm-registry-fetch": "^15.0.0", "npmlog": "^7.0.1", - "pacote": "^15.0.8", + "pacote": "^16.0.0", "parse-conflict-json": "^3.0.0", "proc-log": "^3.0.0", "promise-all-reject-late": "^1.0.0", diff --git a/workspaces/libnpmdiff/package.json b/workspaces/libnpmdiff/package.json index ce6eb3531b32e..b580aaf5bff3c 100644 --- a/workspaces/libnpmdiff/package.json +++ b/workspaces/libnpmdiff/package.json @@ -53,7 +53,7 @@ "diff": "^5.1.0", "minimatch": "^9.0.0", "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8", + "pacote": "^16.0.0", "tar": "^6.1.13" }, "templateOSS": { diff --git a/workspaces/libnpmexec/package.json b/workspaces/libnpmexec/package.json index 9b86b81a998ef..9117cc54c82f4 100644 --- a/workspaces/libnpmexec/package.json +++ b/workspaces/libnpmexec/package.json @@ -64,7 +64,7 @@ "ci-info": "^3.7.1", "npm-package-arg": "^10.1.0", "npmlog": "^7.0.1", - "pacote": "^15.0.8", + "pacote": "^16.0.0", "proc-log": "^3.0.0", "read": "^2.0.0", "read-package-json-fast": "^3.0.2", diff --git a/workspaces/libnpmpack/package.json b/workspaces/libnpmpack/package.json index d8861c337c4d9..12d1d4ea0f888 100644 --- a/workspaces/libnpmpack/package.json +++ b/workspaces/libnpmpack/package.json @@ -39,7 +39,7 @@ "@npmcli/arborist": "^6.3.0", "@npmcli/run-script": "^6.0.0", "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8" + "pacote": "^16.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0"