/
bin.js
66 lines (54 loc) · 1.64 KB
/
bin.js
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
import path from 'path';
import lodash from 'lodash';
import { readJSON, getScripts } from '../utils';
const metadataCache = {};
function getCacheOrRequire(packagePath) {
if (metadataCache[packagePath]) {
return metadataCache[packagePath];
}
const metadata = readJSON(packagePath);
metadataCache[packagePath] = metadata;
return metadata;
}
function loadMetadata(dep, dir) {
try {
const packagePath = path.resolve(dir, 'node_modules', dep, 'package.json');
return getCacheOrRequire(packagePath);
} catch (error) {
return dir === path.parse(dir).root
? {} // ignore silently
: loadMetadata(dep, path.dirname(dir));
}
}
function getBinaryFeatures(dep, [key, value]) {
const binPath = path.join('node_modules', dep, value).replace(/\\/g, '/');
const features = [
key,
`--require ${key}`,
`--require ${key}/register`,
`$(npm bin)/${key}`,
`node_modules/.bin/${key}`,
`./node_modules/.bin/${key}`,
binPath,
`./${binPath}`,
];
return features;
}
function getBinaries(dep, dir) {
const metadata = loadMetadata(dep, dir);
if (typeof metadata.bin === 'string') {
return [[dep, metadata.bin]];
}
return lodash.toPairs(metadata.bin || {});
}
function isBinaryInUse(dep, scripts, dir) {
const binaries = getBinaries(dep, dir);
return binaries.some((bin) =>
getBinaryFeatures(dep, bin).some((feature) =>
scripts.some((script) =>
lodash.includes(` ${script} `, ` ${feature} `))));
}
export default function parseBinary(content, filepath, deps, dir) {
const scripts = getScripts(filepath, content);
return deps.filter((dep) => isBinaryInUse(dep, scripts, dir));
}