0
# libnpmdiff
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: libnpmdiff
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install libnpmdiff`
10
11
## Core Imports
12
13
```javascript
14
const diff = require("libnpmdiff");
15
```
16
17
## Basic Usage
18
19
```javascript
20
const diff = require("libnpmdiff");
21
22
// Compare two package versions
23
const patch = await diff([
24
"abbrev@1.1.0",
25
"abbrev@1.1.1"
26
]);
27
console.log(patch);
28
29
// Compare with options
30
const coloredPatch = await diff([
31
"lodash@4.17.20",
32
"lodash@4.17.21"
33
], {
34
color: true,
35
diffUnified: 5,
36
diffFiles: ["package.json", "lib/**/*.js"]
37
});
38
```
39
40
## Architecture
41
42
libnpmdiff follows a modular architecture with distinct phases for package comparison:
43
44
- **Manifest Resolution**: Uses `pacote.manifest()` to resolve package specifications and extract version metadata
45
- **Tarball Fetching**: Downloads package tarballs from the registry using the `getTarball` module
46
- **File Extraction**: The `untar` module extracts and filters files from tarballs based on configuration options
47
- **Diff Generation**: The `formatDiff` module generates unified diff patches using the `diff` library with customizable formatting
48
- **File Filtering**: Built-in support for glob patterns and file matching using `minimatch`
49
50
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.
51
52
## Capabilities
53
54
### Main Diff Function
55
56
Compares two npm package specifications and returns a unified diff string.
57
58
```javascript { .api }
59
/**
60
* Compare two npm package specifications and generate a unified diff
61
* @param {string[]} specs - Array of exactly 2 npm package specs to compare
62
* @param {DiffOptions} opts - Optional configuration options
63
* @returns {Promise<string>} Unified diff patch string
64
* @throws {TypeError} EDIFFARGS error if specs length is not exactly 2
65
*/
66
function diff(specs, opts = {});
67
```
68
69
**Parameters:**
70
71
- `specs` (Array): Array of exactly 2 npm package specifications. Supports all npm spec formats:
72
- Version specs: `"package@1.0.0"`
73
- Version ranges: `"package@^1.0.0"`
74
- Git URLs: `"git+https://github.com/user/repo.git"`
75
- Local paths: `"file:/path/to/package"`
76
- Tarball URLs: `"https://registry.npmjs.org/package/-/package-1.0.0.tgz"`
77
78
- `opts` (Object, optional): Configuration options for diff generation
79
80
**Returns:** Promise that resolves to a string containing unified diff patches
81
82
**Throws:** TypeError with code 'EDIFFARGS' if specs array length is not exactly 2
83
84
### Configuration Options
85
86
The diff function accepts extensive configuration options:
87
88
```javascript { .api }
89
interface DiffOptions {
90
// Diff formatting options
91
color?: boolean; // Add ANSI colors to output (default: false)
92
tagVersionPrefix?: string; // Prefix for version numbers (default: "v")
93
diffUnified?: number; // Lines of context before/after each diff (default: 3)
94
diffNameOnly?: boolean; // Print only file names, no patch content (default: false)
95
diffNoPrefix?: boolean; // Skip prefixes in filenames (default: false)
96
diffSrcPrefix?: string; // Prefix for source files (default: "a/")
97
diffDstPrefix?: string; // Prefix for destination files (default: "b/")
98
diffText?: boolean; // Treat all files as text, including binary (default: false)
99
diffIgnoreAllSpace?: boolean; // Ignore whitespace changes (default: false)
100
101
// File filtering options
102
diffFiles?: string[]; // Only show patches for specified files/globs
103
104
// Pacote options
105
cache?: string; // Cache directory path
106
registry?: string; // Registry URL
107
where?: string; // Working directory
108
// ... other pacote options
109
}
110
```
111
112
## Usage Examples
113
114
### Basic Package Comparison
115
116
```javascript
117
const diff = require("libnpmdiff");
118
119
const patch = await diff([
120
"express@4.17.0",
121
"express@4.18.0"
122
]);
123
console.log(patch);
124
```
125
126
### Colored Output with Context
127
128
```javascript
129
const coloredDiff = await diff([
130
"react@17.0.0",
131
"react@18.0.0"
132
], {
133
color: true, // Enable ANSI colors
134
diffUnified: 5 // Show 5 lines of context
135
});
136
```
137
138
### File Filtering with Globs
139
140
```javascript
141
const filtered = await diff([
142
"webpack@5.0.0",
143
"webpack@5.1.0"
144
], {
145
diffFiles: [
146
"package.json", // Specific file
147
"lib/**/*.js", // Glob pattern
148
"*.md" // All markdown files
149
]
150
});
151
```
152
153
### Name-Only Mode
154
155
```javascript
156
const fileNames = await diff([
157
"@babel/core@7.0.0",
158
"@babel/core@7.1.0"
159
], {
160
diffNameOnly: true // Only show changed file names
161
});
162
```
163
164
### Local File Comparison
165
166
```javascript
167
const localDiff = await diff([
168
"file:/path/to/package1",
169
"file:/path/to/package2"
170
], {
171
diffNoPrefix: true, // Remove a/ and b/ prefixes
172
diffText: true // Force text mode for binary files
173
});
174
```
175
176
### Whitespace-Insensitive Comparison
177
178
```javascript
179
const cleanDiff = await diff([
180
"prettier@2.0.0",
181
"prettier@2.1.0"
182
], {
183
diffIgnoreAllSpace: true, // Ignore whitespace changes
184
tagVersionPrefix: "" // Remove version prefix
185
});
186
```
187
188
### Custom Registry and Caching
189
190
```javascript
191
const diff = await diff([
192
"private-pkg@1.0.0",
193
"private-pkg@1.1.0"
194
], {
195
registry: "https://npm.example.com",
196
cache: "/tmp/npm-cache",
197
where: process.cwd()
198
});
199
```
200
201
## Error Handling
202
203
### EDIFFARGS Error
204
205
Thrown when the specs array doesn't contain exactly 2 elements:
206
207
```javascript
208
try {
209
await diff(["single-package@1.0.0"]);
210
} catch (error) {
211
console.log(error.code); // "EDIFFARGS"
212
console.log(error.message); // "libnpmdiff needs two arguments to compare"
213
}
214
```
215
216
### EDIFFUNTAR Error
217
218
Thrown when tarball extraction fails during processing:
219
220
```javascript
221
try {
222
await diff(["corrupt-package@1.0.0", "corrupt-package@2.0.0"]);
223
} catch (error) {
224
console.log(error.code); // "EDIFFUNTAR"
225
console.log(error.message); // "failed to read files"
226
}
227
```
228
229
## Types
230
231
```javascript { .api }
232
// Error types
233
interface EDiffArgsError extends TypeError {
234
code: "EDIFFARGS";
235
message: "libnpmdiff needs two arguments to compare";
236
}
237
238
interface EDiffUntarError extends Error {
239
code: "EDIFFUNTAR";
240
message: "failed to read files";
241
}
242
```