or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-libnpmdiff

The registry diff library for comparing npm package versions via tarballs

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/libnpmdiff@8.0.x

To install, run

npx @tessl/cli install tessl/npm-libnpmdiff@8.0.0

index.mddocs/

libnpmdiff

libnpmdiff is a registry diff library that compares different versions of npm packages by fetching registry tarballs and generating unified diff outputs. It provides a Promise-based API for analyzing package changes with extensive configuration options for diff formatting and file filtering.

Package Information

  • Package Name: libnpmdiff
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install libnpmdiff

Core Imports

const diff = require("libnpmdiff");

Basic Usage

const diff = require("libnpmdiff");

// Compare two package versions
const patch = await diff([
  "abbrev@1.1.0",
  "abbrev@1.1.1"
]);
console.log(patch);

// Compare with options
const coloredPatch = await diff([
  "lodash@4.17.20",
  "lodash@4.17.21"
], {
  color: true,
  diffUnified: 5,
  diffFiles: ["package.json", "lib/**/*.js"]
});

Architecture

libnpmdiff follows a modular architecture with distinct phases for package comparison:

  • Manifest Resolution: Uses pacote.manifest() to resolve package specifications and extract version metadata
  • Tarball Fetching: Downloads package tarballs from the registry using the getTarball module
  • File Extraction: The untar module extracts and filters files from tarballs based on configuration options
  • Diff Generation: The formatDiff module generates unified diff patches using the diff library with customizable formatting
  • File Filtering: Built-in support for glob patterns and file matching using minimatch

The library operates asynchronously throughout, using Promise-based APIs for all network operations and file processing. Each phase can be configured independently through the options parameter.

Capabilities

Main Diff Function

Compares two npm package specifications and returns a unified diff string.

/**
 * Compare two npm package specifications and generate a unified diff
 * @param {string[]} specs - Array of exactly 2 npm package specs to compare
 * @param {DiffOptions} opts - Optional configuration options
 * @returns {Promise<string>} Unified diff patch string
 * @throws {TypeError} EDIFFARGS error if specs length is not exactly 2
 */
function diff(specs, opts = {});

Parameters:

  • specs (Array): Array of exactly 2 npm package specifications. Supports all npm spec formats:

    • Version specs: "package@1.0.0"
    • Version ranges: "package@^1.0.0"
    • Git URLs: "git+https://github.com/user/repo.git"
    • Local paths: "file:/path/to/package"
    • Tarball URLs: "https://registry.npmjs.org/package/-/package-1.0.0.tgz"
  • opts (Object, optional): Configuration options for diff generation

Returns: Promise that resolves to a string containing unified diff patches

Throws: TypeError with code 'EDIFFARGS' if specs array length is not exactly 2

Configuration Options

The diff function accepts extensive configuration options:

interface DiffOptions {
  // Diff formatting options
  color?: boolean;              // Add ANSI colors to output (default: false)
  tagVersionPrefix?: string;    // Prefix for version numbers (default: "v")
  diffUnified?: number;         // Lines of context before/after each diff (default: 3)
  diffNameOnly?: boolean;       // Print only file names, no patch content (default: false)
  diffNoPrefix?: boolean;       // Skip prefixes in filenames (default: false)
  diffSrcPrefix?: string;       // Prefix for source files (default: "a/")
  diffDstPrefix?: string;       // Prefix for destination files (default: "b/")
  diffText?: boolean;           // Treat all files as text, including binary (default: false)
  diffIgnoreAllSpace?: boolean; // Ignore whitespace changes (default: false)
  
  // File filtering options
  diffFiles?: string[];         // Only show patches for specified files/globs
  
  // Pacote options
  cache?: string;               // Cache directory path
  registry?: string;            // Registry URL
  where?: string;               // Working directory
  // ... other pacote options
}

Usage Examples

Basic Package Comparison

const diff = require("libnpmdiff");

const patch = await diff([
  "express@4.17.0",
  "express@4.18.0"
]);
console.log(patch);

Colored Output with Context

const coloredDiff = await diff([
  "react@17.0.0", 
  "react@18.0.0"
], {
  color: true,          // Enable ANSI colors
  diffUnified: 5        // Show 5 lines of context
});

File Filtering with Globs

const filtered = await diff([
  "webpack@5.0.0",
  "webpack@5.1.0"
], {
  diffFiles: [
    "package.json",     // Specific file
    "lib/**/*.js",      // Glob pattern
    "*.md"              // All markdown files
  ]
});

Name-Only Mode

const fileNames = await diff([
  "@babel/core@7.0.0",
  "@babel/core@7.1.0"
], {
  diffNameOnly: true    // Only show changed file names
});

Local File Comparison

const localDiff = await diff([
  "file:/path/to/package1",
  "file:/path/to/package2"
], {
  diffNoPrefix: true,   // Remove a/ and b/ prefixes
  diffText: true        // Force text mode for binary files
});

Whitespace-Insensitive Comparison

const cleanDiff = await diff([
  "prettier@2.0.0",
  "prettier@2.1.0"
], {
  diffIgnoreAllSpace: true,  // Ignore whitespace changes
  tagVersionPrefix: ""       // Remove version prefix
});

Custom Registry and Caching

const diff = await diff([
  "private-pkg@1.0.0",
  "private-pkg@1.1.0"
], {
  registry: "https://npm.example.com",
  cache: "/tmp/npm-cache",
  where: process.cwd()
});

Error Handling

EDIFFARGS Error

Thrown when the specs array doesn't contain exactly 2 elements:

try {
  await diff(["single-package@1.0.0"]);
} catch (error) {
  console.log(error.code);     // "EDIFFARGS"
  console.log(error.message);  // "libnpmdiff needs two arguments to compare"
}

EDIFFUNTAR Error

Thrown when tarball extraction fails during processing:

try {
  await diff(["corrupt-package@1.0.0", "corrupt-package@2.0.0"]);
} catch (error) {
  console.log(error.code);     // "EDIFFUNTAR"
  console.log(error.message);  // "failed to read files"
}

Types

// Error types
interface EDiffArgsError extends TypeError {
  code: "EDIFFARGS";
  message: "libnpmdiff needs two arguments to compare";
}

interface EDiffUntarError extends Error {
  code: "EDIFFUNTAR";
  message: "failed to read files";
}