-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
/
dependencyExtractor.ts
93 lines (80 loc) · 2.23 KB
/
dependencyExtractor.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
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import isRegExpSupported from './isRegExpSupported';
// Negative look behind is only supported in Node 9+
const NOT_A_DOT = isRegExpSupported('(?<!\\.\\s*)')
? '(?<!\\.\\s*)'
: '(?:^|[^.]\\s*)';
const CAPTURE_STRING_LITERAL = (pos: number) =>
`([\`'"])([^'"\`]*?)(?:\\${pos})`;
const WORD_SEPARATOR = '\\b';
const LEFT_PARENTHESIS = '\\(';
const RIGHT_PARENTHESIS = '\\)';
const WHITESPACE = '\\s*';
const OPTIONAL_COMMA = '(:?,\\s*)?';
function createRegExp(parts: Array<string>, flags: string) {
return new RegExp(parts.join(''), flags);
}
function alternatives(...parts: Array<string>) {
return `(?:${parts.join('|')})`;
}
function functionCallStart(...names: Array<string>) {
return [
NOT_A_DOT,
WORD_SEPARATOR,
alternatives(...names),
WHITESPACE,
LEFT_PARENTHESIS,
WHITESPACE,
];
}
const BLOCK_COMMENT_RE = /\/\*[^]*?\*\//g;
const LINE_COMMENT_RE = /\/\/.*/g;
const REQUIRE_OR_DYNAMIC_IMPORT_RE = createRegExp(
[
...functionCallStart('require', 'import'),
CAPTURE_STRING_LITERAL(1),
WHITESPACE,
OPTIONAL_COMMA,
RIGHT_PARENTHESIS,
],
'g',
);
const IMPORT_OR_EXPORT_RE = createRegExp(
[
'\\b(?:import|export)\\s+(?!type(?:of)?\\s+)(?:[^\'"]+\\s+from\\s+)?',
CAPTURE_STRING_LITERAL(1),
],
'g',
);
const JEST_EXTENSIONS_RE = createRegExp(
[
...functionCallStart(
'require\\s*\\.\\s*(?:requireActual|requireMock)',
'jest\\s*\\.\\s*(?:requireActual|requireMock|genMockFromModule)',
),
CAPTURE_STRING_LITERAL(1),
WHITESPACE,
OPTIONAL_COMMA,
RIGHT_PARENTHESIS,
],
'g',
);
export function extract(code: string): Set<string> {
const dependencies = new Set<string>();
const addDependency = (match: string, _: string, dep: string) => {
dependencies.add(dep);
return match;
};
code
.replace(BLOCK_COMMENT_RE, '')
.replace(LINE_COMMENT_RE, '')
.replace(IMPORT_OR_EXPORT_RE, addDependency)
.replace(REQUIRE_OR_DYNAMIC_IMPORT_RE, addDependency)
.replace(JEST_EXTENSIONS_RE, addDependency);
return dependencies;
}