diff-lockfiles 1.0.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.2.0 - 2025-09-25
4
+
5
+ - Added --format markdown
6
+
7
+ ## 1.1.0 - 2024-06-28
8
+
9
+ - Added --shallow to only handle direct dependencies (GH #31) (Jussi Kosunen)
10
+
3
11
  ## 1.0.3 - 2024-06-06
4
12
 
5
13
  - Only diff files whose string *ends* with package-lock.json (GH #24 Tim
package/README.md CHANGED
@@ -7,12 +7,17 @@ operates on Git commit ranges rather than on files.
7
7
 
8
8
  ## Example
9
9
 
10
+ Install `diff-lockfiles` globally:
11
+
10
12
  ```sh
11
- npm install diff-lockfiles
12
- diff-lockfiles --color origin/main dependabot/branch
13
+ npm install -g diff-lockfiles
13
14
  ```
14
15
 
16
+ Try it out:
17
+
15
18
  ```ssh
19
+ diff-lockfiles --color origin/main dependabot/branch
20
+
16
21
  diff-lockfiles --color HEAD~1 HEAD
17
22
  ```
18
23
 
@@ -29,6 +34,7 @@ Options:
29
34
  -f, --format <format> changes the output format (default: "table")
30
35
  -m, --max-buffer maximum read buffer size
31
36
  -c, --color colorizes certain output formats (default: false)
37
+ -s, --shallow only include direct dependencies of the project (default: false)
32
38
  -h, --help display help for command
33
39
  ```
34
40
 
@@ -36,13 +36,14 @@ cli
36
36
  .option('-f, --format <format>', 'changes the output format (table|json|text)', 'table')
37
37
  .option('-m, --max-buffer', 'maximum read buffer size', 1024 * 10000)
38
38
  .option('-c, --color', 'colorizes certain output formats', false)
39
+ .option('-s, --shallow', 'only include direct dependencies of the project', false)
39
40
  .action((from, to, options) => {
40
41
  lockFiles(from, to).then((v) => {
41
42
  for (let filename of v) {
42
43
  const a = lockFileString(options.maxBuffer, from, filename).then((s) => { return JSON.parse(s); });
43
44
  const b = lockFileString(options.maxBuffer, to, filename).then((s) => { return JSON.parse(s); });
44
45
  Promise.all([a, b]).then((values) => {
45
- const changes = diff(values[0], values[1]);
46
+ const changes = diff(values[0], values[1], options.shallow);
46
47
  print(changes, {
47
48
  color: options.color,
48
49
  format: options.format,
package/lib/index.js CHANGED
@@ -2,15 +2,29 @@
2
2
  import chalk from 'chalk';
3
3
  import semver from 'semver';
4
4
  import { table } from 'table';
5
+ import { markdownTable } from 'markdown-table';
5
6
 
6
- export function diff(oldLock, newLock) {
7
+ export function diff(oldLock, newLock, shallow) {
7
8
  const changes = {};
8
9
 
9
- Object.entries(oldLock.packages).forEach(([name, { version }]) => {
10
+ function filterPackages(packages) {
11
+ let entries = Object.entries(packages);
12
+ if (shallow) {
13
+ const selfPackage = packages[''];
14
+ const directDeps = new Set(
15
+ ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']
16
+ .flatMap(key => Object.keys(selfPackage[key] ?? {}))
17
+ .map(pkg => `node_modules/${pkg}`));
18
+ entries = entries.filter(([name]) => directDeps.has(name) || name === ''); // include self for compatibility
19
+ }
20
+ return entries;
21
+ }
22
+
23
+ filterPackages(oldLock.packages).forEach(([name, { version }]) => {
10
24
  changes[name] = [version, null];
11
25
  });
12
26
 
13
- Object.entries(newLock.packages).forEach(([name, { version }]) => {
27
+ filterPackages(newLock.packages).forEach(([name, { version }]) => {
14
28
  if (changes[name] && changes[name][0]) {
15
29
  if (semver.eq(changes[name][0], version)) {
16
30
  delete changes[name];
@@ -101,6 +115,45 @@ function printTable(changes, options) {
101
115
  /* eslint-disable no-console */
102
116
  }
103
117
 
118
+ function printMarkdown(changes, options) {
119
+ /* eslint-disable no-console */
120
+
121
+ // Helper function to format version changes with markdown emphasis
122
+ function formatVersionChange(oldVersion, newVersion) {
123
+ if (!oldVersion) return `**${newVersion}** (added)`;
124
+ if (!newVersion) return `~~${oldVersion}~~ (removed)`;
125
+
126
+ if (semver.valid(oldVersion) && semver.valid(newVersion)) {
127
+ if (semver.lt(oldVersion, newVersion)) {
128
+ return `${oldVersion} → **${newVersion}**`;
129
+ } else if (semver.gt(oldVersion, newVersion)) {
130
+ return `**${oldVersion}** → ${newVersion}`;
131
+ }
132
+ }
133
+
134
+ return `${oldVersion} → ${newVersion}`;
135
+ }
136
+
137
+ const tableData = [
138
+ ['Package', 'Old Version', 'New Version', 'Change'],
139
+ ...Object.entries(changes).map(([name, [oldVersion, newVersion]]) => [
140
+ name,
141
+ oldVersion || '—',
142
+ newVersion || '—',
143
+ formatVersionChange(oldVersion, newVersion)
144
+ ])
145
+ ];
146
+
147
+ // Add title if provided
148
+ if (options.title && options.title !== '') {
149
+ console.log(`## ${options.title}\n`);
150
+ }
151
+
152
+ console.log(markdownTable(tableData));
153
+
154
+ /* eslint-enable no-console */
155
+ }
156
+
104
157
  export function print(changes, options) {
105
158
  switch (options.format) {
106
159
  case 'json':
@@ -109,6 +162,9 @@ export function print(changes, options) {
109
162
  case 'table':
110
163
  printTable(changes, options);
111
164
  break;
165
+ case 'markdown':
166
+ printMarkdown(changes, options);
167
+ break;
112
168
  case 'text':
113
169
  default:
114
170
  printText(changes, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diff-lockfiles",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "description": "a diff for package-lock.json files",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,12 +20,13 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "chalk": "^5.3.0",
23
- "commander": "^12.0.0",
23
+ "commander": "^14.0.0",
24
+ "markdown-table": "^3.0.4",
24
25
  "semver": "^7.5.4",
25
26
  "table": "^6.8.1"
26
27
  },
27
28
  "devDependencies": {
28
29
  "eslint": "^9.0.0",
29
- "jest": "^29.6.2"
30
+ "jest": "^30.0.0"
30
31
  }
31
32
  }