CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-libnpmdiff

The registry diff library for comparing npm package versions via tarballs

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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";
}
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/libnpmdiff@8.0.x
Publish Source
CLI
Badge
tessl/npm-libnpmdiff badge