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
Standalone utility functions for specialized package operations and processing. These functions are used internally by pacote but are also exposed as part of the public API for advanced usage scenarios.
Add SHA hashes to git URL specifications for precise version control.
/**
* Add SHA hash to git URL specification
* @param {string} spec - Git URL specification
* @param {string} sha - SHA hash to append
* @returns {string} Modified git URL with SHA
*/
function addGitSha(spec, sha);Usage Examples:
const { addGitSha } = require('pacote/lib/util/add-git-sha');
// Add commit SHA to GitHub URL
const gitUrl = addGitSha('git+https://github.com/user/repo.git', 'abc123def456');
console.log(gitUrl); // 'git+https://github.com/user/repo.git#abc123def456'
// Add SHA to shorthand GitHub spec
const shortUrl = addGitSha('github:user/repo', '789def012abc');
console.log(shortUrl); // 'github:user/repo#789def012abc'Get platform-specific cache directory paths for pacote operations.
/**
* Get cache directory paths for different platforms
* @param {string} fakePlatform - Platform identifier for testing
* @returns {Object} Cache directory configuration
*/
function cacheDir(fakePlatform);
interface CacheDirResult {
/** Main cache directory for packages and metadata */
cacache: string;
/** TUF cache directory for attestation keys */
tufcache: string;
}Usage Examples:
const { cacheDir } = require('pacote/lib/util/cache-dir');
// Get default cache directories
const dirs = cacheDir();
console.log('Main cache:', dirs.cacache);
console.log('TUF cache:', dirs.tufcache);
// Get cache directories for specific platform (testing)
const winDirs = cacheDir('win32');
const linuxDirs = cacheDir('linux');
const macDirs = cacheDir('darwin');Platform-specific cache locations:
%LOCALAPPDATA%/npm-cache and %LOCALAPPDATA%/npm-cache/_tuf~/Library/Caches/npm and ~/Library/Caches/npm/_tuf~/.npm and ~/.npm/_tufCheck if a file path corresponds to a package binary script.
/**
* Check if path is a package binary script
* @param {Object} pkg - Package manifest object
* @param {string} path - File path to check
* @returns {boolean} True if path is a package binary
*/
function isPackageBin(pkg, path);Usage Examples:
const { isPackageBin } = require('pacote/lib/util/is-package-bin');
const manifest = {
name: 'example-package',
bin: {
'example': './bin/example.js',
'helper': './scripts/helper.js'
}
};
// Check various paths
console.log(isPackageBin(manifest, 'bin/example.js')); // true
console.log(isPackageBin(manifest, 'scripts/helper.js')); // true
console.log(isPackageBin(manifest, 'lib/index.js')); // false
// Works with string bin field too
const simpleBin = { name: 'simple', bin: './cli.js' };
console.log(isPackageBin(simpleBin, 'cli.js')); // trueGenerate tar creation options for reproducible package archives.
/**
* Generate tar creation options for package archiving
* @param {Object} manifest - Package manifest object
* @returns {Object} Tar creation options
*/
function tarCreateOptions(manifest);
interface TarCreateOptions {
cwd: string;
prefix: string;
gzip: boolean;
file?: string;
portable: boolean;
noMtime: boolean;
filter: (path: string, stat: Object) => boolean;
}Usage Examples:
const { tarCreateOptions } = require('pacote/lib/util/tar-create-options');
const tar = require('tar');
const manifest = {
name: 'my-package',
version: '1.0.0'
};
// Get tar options for reproducible archives
const opts = tarCreateOptions(manifest);
console.log('Archive prefix:', opts.prefix); // 'package/'
console.log('Gzip enabled:', opts.gzip); // true
console.log('Portable format:', opts.portable); // true
// Create tar archive with consistent options
await tar.create(opts, ['src/', 'package.json', 'README.md']);
// Custom tar file destination
const fileOpts = { ...opts, file: './my-package-1.0.0.tgz' };
await tar.create(fileOpts, ['.']);Remove trailing slashes from file paths and URLs.
/**
* Remove trailing slashes from input string
* @param {string} input - Input path or URL
* @returns {string} Path without trailing slashes
*/
function removeTrailingSlashes(input);Usage Examples:
const { removeTrailingSlashes } = require('pacote/lib/util/trailing-slashes');
// Clean file paths
console.log(removeTrailingSlashes('/path/to/dir/')); // '/path/to/dir'
console.log(removeTrailingSlashes('/path/to/dir///')); // '/path/to/dir'
// Clean URLs
console.log(removeTrailingSlashes('https://registry.npmjs.org/'));
// 'https://registry.npmjs.org'
// Preserve single paths
console.log(removeTrailingSlashes('/')); // '/'
console.log(removeTrailingSlashes('file.txt')); // 'file.txt'Execute npm commands with proper environment and error handling.
/**
* Execute npm command with spawn
* @param {string} npmBin - npm binary path
* @param {string[]} npmCommand - npm command arguments array
* @param {string} cwd - Working directory
* @param {Object} env - Environment variables
* @param {Object} extra - Additional spawn options
* @returns {Promise<Object>} Spawn result with stdout/stderr
*/
function npm(npmBin, npmCommand, cwd, env, extra);
interface NpmResult {
stdout: string;
stderr: string;
code: number;
signal: string | null;
}Usage Examples:
const { npm } = require('pacote/lib/util/npm');
// Run npm install
const result = await npm('npm', ['install'], './my-project', process.env, {
stdio: 'pipe'
});
console.log('Exit code:', result.code);
console.log('Output:', result.stdout);
// Run with custom npm binary
await npm('yarn', ['install', '--frozen-lockfile'], './workspace', {
...process.env,
NODE_ENV: 'production'
}, { stdio: 'inherit' });
// Run npm scripts
const scriptResult = await npm('npm', ['run', 'build'], './package', {
...process.env,
CI: 'true'
});
if (scriptResult.code !== 0) {
throw new Error(`Build failed: ${scriptResult.stderr}`);
}These utilities can be imported individually for specific use cases:
// Import specific utilities
const { addGitSha } = require('pacote/lib/util/add-git-sha');
const { cacheDir } = require('pacote/lib/util/cache-dir');
const { isPackageBin } = require('pacote/lib/util/is-package-bin');
const { tarCreateOptions } = require('pacote/lib/util/tar-create-options');
const { removeTrailingSlashes } = require('pacote/lib/util/trailing-slashes');
const { npm } = require('pacote/lib/util/npm');
// Or use through main pacote module (less common)
const pacote = require('pacote');
// Utilities are not re-exported, must import directlyconst { tarCreateOptions, isPackageBin } = require('pacote/lib/util/tar-create-options');
const { isPackageBin } = require('pacote/lib/util/is-package-bin');
const tar = require('tar');
const fs = require('fs');
async function processPackage(manifest, sourceDir) {
// Get tar options
const tarOpts = tarCreateOptions(manifest);
// Custom filter to exclude non-binary files from executable check
tarOpts.filter = (path, stat) => {
if (stat.isFile() && isPackageBin(manifest, path)) {
// Ensure binary files are executable
stat.mode |= 0o111;
}
return true;
};
// Create reproducible archive
await tar.create({
...tarOpts,
file: `${manifest.name}-${manifest.version}.tgz`,
cwd: sourceDir
}, ['.']);
}const { cacheDir } = require('pacote/lib/util/cache-dir');
const fs = require('fs').promises;
async function setupCustomCache() {
const dirs = cacheDir();
// Ensure cache directories exist
await fs.mkdir(dirs.cacache, { recursive: true });
await fs.mkdir(dirs.tufcache, { recursive: true });
// Set custom cache in pacote options
return {
cache: dirs.cacache,
tufCache: dirs.tufcache
};
}
// Use in pacote operations
const cacheOpts = await setupCustomCache();
const manifest = await pacote.manifest('express@latest', cacheOpts);Install with Tessl CLI
npx tessl i tessl/npm-pacote