/
index.ts
115 lines (106 loc) · 3.79 KB
/
index.ts
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import * as _ from 'lodash';
import * as semver from 'semver';
import { DEPENDENCY_TYPES, RANGE_ANY, RANGE_LOOSE } from '../../constants';
import { IDictionary, IManifest } from '../../typings';
import { getNewest, getVersionNumber } from '../../version';
import { format } from './format';
export type GetMismatchedVersions = (manifests: IManifest[]) => IDictionary<string[]>;
export type GetVersions = (manifests: IManifest[]) => IDictionary<string[]>;
export type SetVersion = (name: string, version: string, manifests: IManifest[]) => IManifest[];
export type SetVersionRange = (range: string, manifests: IManifest[]) => IManifest[];
export type SetVersionsToNewestMismatch = (manifests: IManifest[]) => IManifest[];
const isObject = (value: any) => Boolean(value && typeof value === 'object');
const join = ({ name, version }: IDictionary<string>) => `${name}@${version}`;
const gatherDependencies = (manifest: IManifest) =>
_.chain(DEPENDENCY_TYPES)
.map((property) => manifest[property])
.filter(Boolean)
.flatMap((dependencies) => _.map(dependencies, (version, name) => ({ name, version })))
.value();
const isManifest = (value: any): boolean =>
Boolean(
isObject(value) &&
'name' in value &&
('dependencies' in value || 'devDependencies' in value || 'peerDependencies' in value)
);
const getMismatchedVersions: GetMismatchedVersions = (manifests) =>
_.chain(manifests)
.map(gatherDependencies)
.flatten()
.uniqBy(join)
.sortBy(join)
.groupBy('name')
.reduce((index: IDictionary<string[]>, dependencies, name) => {
if (dependencies.length > 1) {
index[name] = dependencies.map(_.property('version'));
}
return index;
}, {})
.value();
const getVersions: GetVersions = (manifests) =>
_.chain(manifests)
.map(gatherDependencies)
.flatten()
.uniqBy(join)
.sortBy(join)
.groupBy('name')
.reduce((index: IDictionary<string[]>, dependencies, name) => {
index[name] = dependencies.map(_.property('version'));
return index;
}, {})
.value();
const setVersion: SetVersion = (name, version, manifests) => {
_(manifests).each((manifest) =>
_(DEPENDENCY_TYPES)
.map((property) => manifest[property])
.filter(Boolean)
.filter((dependencies) => name in dependencies)
.each((dependencies) => {
dependencies[name] = version;
})
);
return manifests;
};
const setVersionRange: SetVersionRange = (range, manifests) => {
_(manifests).each((manifest) =>
_(DEPENDENCY_TYPES)
.map((property) => manifest[property])
.filter(Boolean)
.each((dependencies) => {
_(dependencies).each((version, name) => {
const versionNumber = getVersionNumber(version);
if (version !== '*' && semver.validRange(version)) {
if (range === RANGE_ANY) {
dependencies[name] = '*';
} else if (range === RANGE_LOOSE) {
dependencies[name] =
semver.major(versionNumber) === 0
? `${semver.major(versionNumber)}.${semver.minor(versionNumber)}.x`
: `${semver.major(versionNumber)}.x.x`;
} else {
dependencies[name] = `${range}${versionNumber}`;
}
}
});
})
);
return manifests;
};
const setVersionsToNewestMismatch: SetVersionsToNewestMismatch = (manifests) => {
_(getMismatchedVersions(manifests))
.map((versions, name) => ({ name, newest: getNewest(versions) }))
.filter(({ newest }) => typeof newest === 'string')
.each(({ name, newest }) => {
setVersion(name, newest as string, manifests);
});
return manifests;
};
export const manifestData = {
format,
getMismatchedVersions,
getVersions,
isManifest,
setVersion,
setVersionRange,
setVersionsToNewestMismatch
};