-
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathlockfile.ts
More file actions
80 lines (71 loc) · 2.03 KB
/
lockfile.ts
File metadata and controls
80 lines (71 loc) · 2.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import {type ParsedLockFile, traverse, type VisitorFn} from 'lockparse';
import {existsSync} from 'node:fs';
import {join} from 'node:path';
export type VersionsSet = Map<string, Set<string>>;
export const supportedLockfiles = [
'pnpm-lock.yaml',
'package-lock.json',
'yarn.lock',
'bun.lock'
] as const;
export function computeDependencyVersions(
lockFile: ParsedLockFile,
includeDevDeps: boolean
): VersionsSet {
const result: VersionsSet = new Map();
if (!includeDevDeps) {
const visitorFn: VisitorFn = (node) => {
if (!node.name || !node.version) return;
addVersion(result, node.name, node.version);
};
traverse(lockFile.root, {
dependency: visitorFn,
optionalDependency: visitorFn,
peerDependency: visitorFn
});
} else {
for (const pkg of lockFile.packages) {
if (!pkg.name || !pkg.version) continue;
addVersion(result, pkg.name, pkg.version);
}
}
return result;
}
export function detectLockfile(workspacePath: string): string | undefined {
for (const c of supportedLockfiles) {
if (existsSync(join(workspacePath, c))) return c;
}
return undefined;
}
function addVersion(map: VersionsSet, name: string, version: string): void {
let set = map.get(name);
if (!set) {
set = new Set();
map.set(name, set);
}
set.add(version);
}
export function diffDependencySets(
prev: VersionsSet,
curr: VersionsSet
): Array<{name: string; previous: Set<string>; current: Set<string>}> {
const names = new Set<string>([...prev.keys(), ...curr.keys()]);
const changes: Array<{
name: string;
previous: Set<string>;
current: Set<string>;
}> = [];
for (const name of names) {
const a = prev.get(name) || new Set<string>();
const b = curr.get(name) || new Set<string>();
if (!setsEqual(a, b)) changes.push({name, previous: a, current: b});
}
return changes;
}
function setsEqual(a: Set<string>, b: Set<string>): boolean {
if (a.size !== b.size) return false;
for (const v of a) {
if (!b.has(v)) return false;
}
return true;
}