npm-install-size
Version:
Check the install size of any NPM package before installing it.
102 lines (97 loc) • 3.87 kB
JavaScript
import { getLatestTarballUrl, downloadAndExtractTarball } from './fetch.js';
import { getDirStats, getAllFilesWithSizes, getFileTypeBreakdown as getFileTypeBreakdownInternal, estimateDownloadTime, cleanup, findMainJsFile } from './analyze.js';
import { getDependencyTreeSize as getDepTree } from './tree.js';
import { minifyAndGzipFile } from './minify.js';
import fs from 'fs/promises';
import os from 'os';
import path from 'path';
import { existsSync } from 'fs';
// Helper to check if a string is a local path
function isLocalPath(str) {
return str.startsWith('.') || str.startsWith('/') || str.match(/^[a-zA-Z]:\\/);
}
/**
* Get the install size and stats for a package or local directory.
* @param {string} pkg - Package name (optionally with version) or local path
* @param {object} options - { speed }
* @returns {Promise<object>} - { size, fileCount, largestFile, downloadTime }
*/
export async function getInstallSize(pkg, options = {}) {
if (isLocalPath(pkg) || existsSync(pkg)) {
const absPath = path.resolve(pkg);
const stats = await getDirStats(absPath);
return {
size: stats.total,
fileCount: stats.count,
largestFile: stats.largest,
downloadTime: estimateDownloadTime(stats.total, options.speed)
};
}
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), `npm-install-size-api-`));
try {
const { tarball } = await getLatestTarballUrl(pkg);
await downloadAndExtractTarball(tarball, tempDir);
const stats = await getDirStats(tempDir);
return {
size: stats.total,
fileCount: stats.count,
largestFile: stats.largest,
downloadTime: estimateDownloadTime(stats.total, options.speed)
};
} finally {
await cleanup(tempDir);
}
}
/**
* Get the full dependency tree size for a package.
* @param {string} pkg - Package name (optionally with version)
* @param {object} options
* @returns {Promise<object>} - { totalSize, tree }
*/
export async function getDependencyTreeSize(pkg, options = {}) {
return getDepTree(pkg, options);
}
/**
* Get minified and gzipped size for the main JS file of a package or local directory.
* @param {string} pkg - Package name (optionally with version) or local path
* @returns {Promise<object>} - { minifiedSize, gzippedSize }
*/
export async function getMinifiedAndGzippedSize(pkg) {
if (isLocalPath(pkg) || existsSync(pkg)) {
const absPath = path.resolve(pkg);
const mainJs = await findMainJsFile(absPath);
if (!mainJs) throw new Error('Main JS file not found');
return minifyAndGzipFile(mainJs);
}
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), `npm-install-size-api-`));
try {
const { tarball } = await getLatestTarballUrl(pkg);
await downloadAndExtractTarball(tarball, tempDir);
const mainJs = await findMainJsFile(tempDir);
if (!mainJs) throw new Error('Main JS file not found');
return minifyAndGzipFile(mainJs);
} finally {
await cleanup(tempDir);
}
}
/**
* Get file type breakdown for a package or local directory.
* @param {string} pkg - Package name (optionally with version) or local path
* @returns {Promise<object>} - { [ext]: size }
*/
export async function getFileTypeBreakdown(pkg) {
if (isLocalPath(pkg) || existsSync(pkg)) {
const absPath = path.resolve(pkg);
const files = await getAllFilesWithSizes(absPath);
return getFileTypeBreakdownInternal(files);
}
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), `npm-install-size-api-`));
try {
const { tarball } = await getLatestTarballUrl(pkg);
await downloadAndExtractTarball(tarball, tempDir);
const files = await getAllFilesWithSizes(tempDir);
return getFileTypeBreakdownInternal(files);
} finally {
await cleanup(tempDir);
}
}