/
index.js
84 lines (74 loc) · 2.61 KB
/
index.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import path from 'path';
import lodash from 'lodash';
import minimatch from 'minimatch';
import check from './check';
import { readJSON } from './utils';
import {
defaultOptions,
availableParsers,
availableDetectors,
availableSpecials,
} from './constants';
function isIgnored(ignoreMatches, dependency) {
const match = lodash.partial(minimatch, dependency);
return ignoreMatches.some(match);
}
function hasBin(rootDir, dependency) {
try {
const metadata = readJSON(path.join(rootDir, 'node_modules', dependency, 'package.json'));
return {}.hasOwnProperty.call(metadata, 'bin');
} catch (error) {
return rootDir === path.parse(rootDir).root
? false
: hasBin(path.dirname(rootDir), dependency);
}
}
function filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, dependencies) {
return lodash(dependencies)
.keys()
.reject((dep) =>
(isIgnored(ignoreMatches, dep))
|| (ignoreBinPackage && hasBin(rootDir, dep)))
.value();
}
export default function depcheck(rootDir, options, callback) {
const getOption = (key) =>
(lodash.isUndefined(options[key]) ? defaultOptions[key] : options[key]);
const ignoreBinPackage = getOption('ignoreBinPackage');
const ignoreMatches = getOption('ignoreMatches');
const ignoreDirs = lodash.union(defaultOptions.ignoreDirs, options.ignoreDirs);
const skipMissing = getOption('skipMissing');
const detectors = getOption('detectors');
const parsers = lodash(getOption('parsers'))
.mapValues((value) => (lodash.isArray(value) ? value : [value]))
.merge({ '*': getOption('specials') })
.value();
const metadata = options.package || readJSON(path.join(rootDir, 'package.json'));
const dependencies = metadata.dependencies || {};
const devDependencies = metadata.devDependencies ? metadata.devDependencies : {};
const peerDeps = Object.keys(metadata.peerDependencies || {});
const optionalDeps = Object.keys(metadata.optionalDependencies || {});
const deps = filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, dependencies);
const devDeps = filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, devDependencies);
return check({
rootDir,
ignoreDirs,
skipMissing,
deps,
devDeps,
peerDeps,
optionalDeps,
parsers,
detectors,
})
.then((results) => Object.assign(results, {
missing: lodash.pick(
results.missing,
filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, results.missing),
),
}))
.then(callback);
}
depcheck.parser = availableParsers;
depcheck.detector = availableDetectors;
depcheck.special = availableSpecials;