JavaScript package downloader and fetcher that serves as the core package handling library for npm
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Specialized fetcher classes for different package sources and advanced usage patterns. Each fetcher handles a specific type of package specifier and provides the same unified interface through the base FetcherBase class.
All fetcher classes extend FetcherBase, which provides the common interface and functionality.
/**
* Base class for all fetchers
*/
class FetcherBase {
/**
* Create a fetcher instance
* @param {string} spec - Package specifier
* @param {Object} opts - Configuration options
*/
constructor(spec, opts);
/**
* Resolve package to concrete location
* @returns {Promise<string>} Resolved URL or path
*/
resolve();
/**
* Get package manifest
* @returns {Promise<PackageManifest>} Package manifest
*/
manifest();
/**
* Get package packument
* @returns {Promise<Packument>} Package document
*/
packument();
/**
* Extract package to directory
* @param {string} dest - Destination directory
* @returns {Promise<ExtractionResult>} Extraction result
*/
extract(dest);
/**
* Get tarball as buffer
* @returns {Promise<TarballResult>} Tarball data
*/
tarball();
/**
* Stream tarball through handler
* @param {Function} handler - Stream handler function
* @returns {Promise<void>} Handler completion promise
*/
tarballStream(handler);
/**
* Save tarball to file
* @param {string} dest - Destination file path
* @returns {Promise<TarballResult>} Tarball metadata
*/
tarballFile(dest);
/**
* Clean up cached content
* @returns {Promise<void>} Cleanup completion promise
*/
cleanupCached();
/**
* Pick best integrity algorithm from available options
* @returns {string} Best available integrity algorithm
*/
pickIntegrityAlgorithm();
/**
* Check if error indicates data corruption
* @param {Error} er - Error to check
* @returns {boolean} True if error indicates corruption
*/
isDataCorruptionError(er);
/**
* Check if error is retriable
* @param {Error} er - Error to check
* @returns {boolean} True if error can be retried
*/
isRetriableError(er);
// Instance properties
/** @type {Object} Parsed package specification */
spec;
/** @type {string} Original package specifier */
from;
/** @type {string} Resolved package URL/path */
resolved;
/** @type {string} Package integrity hash */
integrity;
/** @type {string} Fetcher class name */
type;
/** @type {string} Cache directory path */
cache;
/** @type {string} TUF cache directory path */
tufCache;
/** @type {string} Registry URL */
registry;
/** @type {Object} Cached manifest object */
package;
/** @type {Object} Configuration options */
opts;
}
/**
* Factory method to get appropriate fetcher for spec
* @param {string} spec - Package specifier
* @param {Object} opts - Configuration options
* @returns {FetcherBase} Appropriate fetcher instance
*/
FetcherBase.get(spec, opts);Handles npm registry packages with support for signature verification and attestation validation.
/**
* Fetcher for npm registry packages
* Supports spec types: ['tag', 'version', 'range']
*/
class RegistryFetcher extends FetcherBase {
constructor(spec, opts);
// Additional properties
/** @type {Map} Packument caching system */
packumentCache;
/** @type {string} Registry packument URL */
packumentUrl;
/** @type {Array} Registry signing keys */
registryKeys;
}Usage Examples:
const { RegistryFetcher } = require('pacote');
// Create registry fetcher directly
const fetcher = new RegistryFetcher('express@4.18.0', {
registry: 'https://registry.npmjs.org',
verifySignatures: true
});
const manifest = await fetcher.manifest();
console.log('Package:', manifest.name, manifest.version);
// Fetcher includes registry-specific features
const packument = await fetcher.packument(); // Supports corgi format
const resolved = await fetcher.resolve(); // Returns registry tarball URLRegistry-Specific Features:
Handles git repository dependencies with support for various hosting services and commit resolution.
/**
* Fetcher for git repository packages
* Supports spec types: ['git']
*/
class GitFetcher extends FetcherBase {
constructor(spec, opts);
/**
* Construct repository URL from hosted git info
* @param {Object} hosted - Hosted git information
* @param {Object} opts - Configuration options
* @returns {string} Repository URL
*/
static repoUrl(hosted, opts);
// Additional properties
/** @type {Object} Git reference object */
resolvedRef;
/** @type {string} Resolved commit SHA */
resolvedSha;
/** @type {Function} Arborist constructor option */
Arborist;
}Usage Examples:
const { GitFetcher } = require('pacote');
// GitHub repository
const gitFetcher = new GitFetcher('github:facebook/react#v18.0.0', {
cache: './git-cache'
});
const manifest = await gitFetcher.manifest();
console.log('Git package:', manifest.name);
// GitLab repository
const gitlabFetcher = new GitFetcher('gitlab:user/project#main');
const resolved = await gitlabFetcher.resolve();
// Direct git URL
const directGit = new GitFetcher('git+https://github.com/npm/cli.git#latest');
await directGit.extract('./npm-cli');Git-Specific Features:
Handles local tarball files with manifest extraction and proper permission handling.
/**
* Fetcher for local tarball files
* Supports spec types: ['file']
*/
class FileFetcher extends FetcherBase {
constructor(spec, opts);
/**
* Make package bin scripts executable
* @param {Object} pkg - Package manifest
* @param {string} dest - Destination directory
* @returns {Promise<void>} Completion promise
*/
async exeBins(pkg, dest);
}Usage Examples:
const { FileFetcher } = require('pacote');
// Local tarball file
const fileFetcher = new FileFetcher('file:./packages/my-package.tgz');
const manifest = await fileFetcher.manifest();
console.log('Local package:', manifest.name);
// Extract local tarball
await fileFetcher.extract('./extracted-package');
// Relative file path
const relativeFetcher = new FileFetcher('file:../dist/package.tgz', {
where: '/current/working/directory'
});File-Specific Features:
Handles local directories with packaging and prepare script execution.
/**
* Fetcher for local directories
* Supports spec types: ['directory']
*/
class DirFetcher extends FetcherBase {
constructor(spec, opts);
/**
* Get tar creation options for directory packaging
* @param {Object} manifest - Package manifest
* @returns {Object} Tar creation options
*/
static tarCreateOptions(manifest);
// Additional properties
/** @type {Object} Arborist tree object */
tree;
/** @type {Function} Arborist constructor */
Arborist;
}Usage Examples:
const { DirFetcher } = require('pacote');
// Local directory
const dirFetcher = new DirFetcher('file:./my-package', {
Arborist: require('@npmcli/arborist')
});
const manifest = await dirFetcher.manifest();
console.log('Directory package:', manifest.name);
// Create tarball from directory
const tarball = await dirFetcher.tarball();
console.log('Directory tarball size:', tarball.length);
// Package directory with prepare scripts
await dirFetcher.extract('./packaged-dir');Directory-Specific Features:
Handles remote tarball URLs with streaming downloads and integrity verification.
/**
* Fetcher for remote tarball URLs
* Supports spec types: ['remote']
*/
class RemoteFetcher extends FetcherBase {
constructor(spec, opts);
// Additional properties
/** @type {string} Package identifier for headers */
pkgid;
}Usage Examples:
const { RemoteFetcher } = require('pacote');
// Remote tarball URL
const remoteFetcher = new RemoteFetcher('https://example.com/package.tgz');
const manifest = await remoteFetcher.manifest();
console.log('Remote package:', manifest.name);
// Download and extract remote tarball
await remoteFetcher.extract('./remote-package');
// Remote tarball with integrity verification
const verifiedFetcher = new RemoteFetcher('https://cdn.example.com/pkg.tgz', {
integrity: 'sha512-...'
});Remote-Specific Features:
const { RegistryFetcher, GitFetcher } = require('pacote');
// Create fetchers directly for advanced control
const registryFetcher = new RegistryFetcher('lodash@4.17.21', {
packumentCache: new Map(),
verifySignatures: true
});
const gitFetcher = new GitFetcher('github:npm/cli#latest', {
allowGitIgnore: true
});
// Use fetchers independently
const [registryManifest, gitManifest] = await Promise.all([
registryFetcher.manifest(),
gitFetcher.manifest()
]);const { FetcherBase } = require('pacote');
// Automatic fetcher selection
const fetcher1 = FetcherBase.get('express@latest'); // RegistryFetcher
const fetcher2 = FetcherBase.get('github:user/repo'); // GitFetcher
const fetcher3 = FetcherBase.get('file:./package.tgz'); // FileFetcher
const fetcher4 = FetcherBase.get('https://example.com/pkg.tgz'); // RemoteFetcher
const fetcher5 = FetcherBase.get('file:./src'); // DirFetcher
// All fetchers have the same interface
const manifests = await Promise.all([
fetcher1.manifest(),
fetcher2.manifest(),
fetcher3.manifest(),
fetcher4.manifest(),
fetcher5.manifest()
]);All fetcher instances expose useful properties:
const fetcher = new RegistryFetcher('express@4.18.0');
console.log('Spec:', fetcher.spec); // Parsed package spec
console.log('From:', fetcher.from); // Original specifier
console.log('Type:', fetcher.type); // 'RegistryFetcher'
console.log('Registry:', fetcher.registry); // Registry URL
console.log('Cache:', fetcher.cache); // Cache directory
console.log('Resolved:', fetcher.resolved); // Pre-resolved URL (if any)Install with Tessl CLI
npx tessl i tessl/npm-pacote