@nodesecure/js-x-ray 9.0.0 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +9 -209
- package/dist/AstAnalyser.d.ts +64 -0
- package/dist/AstAnalyser.d.ts.map +1 -0
- package/dist/AstAnalyser.js +165 -0
- package/dist/AstAnalyser.js.map +1 -0
- package/dist/Deobfuscator.d.ts +36 -0
- package/dist/Deobfuscator.d.ts.map +1 -0
- package/dist/Deobfuscator.js +154 -0
- package/dist/Deobfuscator.js.map +1 -0
- package/dist/EntryFilesAnalyser.d.ts +20 -0
- package/dist/EntryFilesAnalyser.d.ts.map +1 -0
- package/dist/EntryFilesAnalyser.js +121 -0
- package/dist/EntryFilesAnalyser.js.map +1 -0
- package/dist/JsSourceParser.d.ts +18 -0
- package/dist/JsSourceParser.d.ts.map +1 -0
- package/dist/JsSourceParser.js +38 -0
- package/dist/JsSourceParser.js.map +1 -0
- package/dist/NodeCounter.d.ts +24 -0
- package/dist/NodeCounter.d.ts.map +1 -0
- package/dist/NodeCounter.js +62 -0
- package/dist/NodeCounter.js.map +1 -0
- package/dist/ProbeRunner.d.ts +40 -0
- package/dist/ProbeRunner.d.ts.map +1 -0
- package/dist/ProbeRunner.js +106 -0
- package/dist/ProbeRunner.js.map +1 -0
- package/dist/SourceFile.d.ts +43 -0
- package/dist/SourceFile.d.ts.map +1 -0
- package/dist/SourceFile.js +137 -0
- package/dist/SourceFile.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/obfuscators/freejsobfuscator.d.ts +3 -0
- package/dist/obfuscators/freejsobfuscator.d.ts.map +1 -0
- package/dist/obfuscators/freejsobfuscator.js +10 -0
- package/dist/obfuscators/freejsobfuscator.js.map +1 -0
- package/dist/obfuscators/jjencode.d.ts +3 -0
- package/dist/obfuscators/jjencode.d.ts.map +1 -0
- package/dist/obfuscators/jjencode.js +24 -0
- package/dist/obfuscators/jjencode.js.map +1 -0
- package/dist/obfuscators/jsfuck.d.ts +3 -0
- package/dist/obfuscators/jsfuck.d.ts.map +1 -0
- package/dist/obfuscators/jsfuck.js +13 -0
- package/dist/obfuscators/jsfuck.js.map +1 -0
- package/dist/obfuscators/obfuscator-io.d.ts +3 -0
- package/dist/obfuscators/obfuscator-io.d.ts.map +1 -0
- package/dist/obfuscators/obfuscator-io.js +15 -0
- package/dist/obfuscators/obfuscator-io.js.map +1 -0
- package/dist/obfuscators/trojan-source.d.ts +2 -0
- package/dist/obfuscators/trojan-source.d.ts.map +1 -0
- package/dist/obfuscators/trojan-source.js +27 -0
- package/dist/obfuscators/trojan-source.js.map +1 -0
- package/dist/probes/isArrayExpression.d.ts +21 -0
- package/dist/probes/isArrayExpression.d.ts.map +1 -0
- package/{src → dist}/probes/isArrayExpression.js +10 -15
- package/dist/probes/isArrayExpression.js.map +1 -0
- package/dist/probes/isBinaryExpression.d.ts +21 -0
- package/dist/probes/isBinaryExpression.d.ts.map +1 -0
- package/dist/probes/isBinaryExpression.js +54 -0
- package/dist/probes/isBinaryExpression.js.map +1 -0
- package/dist/probes/isESMExport.d.ts +24 -0
- package/dist/probes/isESMExport.d.ts.map +1 -0
- package/dist/probes/isESMExport.js +30 -0
- package/dist/probes/isESMExport.js.map +1 -0
- package/dist/probes/isFetch.d.ts +14 -0
- package/dist/probes/isFetch.d.ts.map +1 -0
- package/dist/probes/isFetch.js +18 -0
- package/dist/probes/isFetch.js.map +1 -0
- package/dist/probes/isImportDeclaration.d.ts +26 -0
- package/dist/probes/isImportDeclaration.d.ts.map +1 -0
- package/dist/probes/isImportDeclaration.js +38 -0
- package/dist/probes/isImportDeclaration.js.map +1 -0
- package/dist/probes/isLiteral.d.ts +21 -0
- package/dist/probes/isLiteral.d.ts.map +1 -0
- package/dist/probes/isLiteral.js +66 -0
- package/dist/probes/isLiteral.js.map +1 -0
- package/dist/probes/isLiteralRegex.d.ts +20 -0
- package/dist/probes/isLiteralRegex.d.ts.map +1 -0
- package/dist/probes/isLiteralRegex.js +30 -0
- package/dist/probes/isLiteralRegex.js.map +1 -0
- package/dist/probes/isRegexObject.d.ts +22 -0
- package/dist/probes/isRegexObject.d.ts.map +1 -0
- package/dist/probes/isRegexObject.js +50 -0
- package/dist/probes/isRegexObject.js.map +1 -0
- package/dist/probes/isRequire/RequireCallExpressionWalker.d.ts +15 -0
- package/dist/probes/isRequire/RequireCallExpressionWalker.d.ts.map +1 -0
- package/dist/probes/isRequire/RequireCallExpressionWalker.js +95 -0
- package/dist/probes/isRequire/RequireCallExpressionWalker.js.map +1 -0
- package/dist/probes/isRequire/isRequire.d.ts +20 -0
- package/dist/probes/isRequire/isRequire.d.ts.map +1 -0
- package/dist/probes/isRequire/isRequire.js +138 -0
- package/dist/probes/isRequire/isRequire.js.map +1 -0
- package/dist/probes/isSerializeEnv.d.ts +24 -0
- package/dist/probes/isSerializeEnv.d.ts.map +1 -0
- package/dist/probes/isSerializeEnv.js +66 -0
- package/dist/probes/isSerializeEnv.js.map +1 -0
- package/dist/probes/isSyncIO.d.ts +16 -0
- package/dist/probes/isSyncIO.d.ts.map +1 -0
- package/dist/probes/isSyncIO.js +74 -0
- package/dist/probes/isSyncIO.js.map +1 -0
- package/dist/probes/isUnsafeCallee.d.ts +22 -0
- package/dist/probes/isUnsafeCallee.d.ts.map +1 -0
- package/dist/probes/isUnsafeCallee.js +60 -0
- package/dist/probes/isUnsafeCallee.js.map +1 -0
- package/dist/probes/isUnsafeCommand.d.ts +24 -0
- package/dist/probes/isUnsafeCommand.d.ts.map +1 -0
- package/dist/probes/isUnsafeCommand.js +100 -0
- package/dist/probes/isUnsafeCommand.js.map +1 -0
- package/dist/probes/isWeakCrypto.d.ts +16 -0
- package/dist/probes/isWeakCrypto.d.ts.map +1 -0
- package/dist/probes/isWeakCrypto.js +46 -0
- package/dist/probes/isWeakCrypto.js.map +1 -0
- package/dist/types/estree.d.ts +11 -0
- package/dist/types/estree.d.ts.map +1 -0
- package/dist/types/estree.js +15 -0
- package/dist/types/estree.js.map +1 -0
- package/dist/utils/extractNode.d.ts +5 -0
- package/dist/utils/extractNode.d.ts.map +1 -0
- package/dist/utils/extractNode.js +13 -0
- package/dist/utils/extractNode.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/isOneLineExpressionExport.d.ts +3 -0
- package/dist/utils/isOneLineExpressionExport.d.ts.map +1 -0
- package/dist/utils/isOneLineExpressionExport.js +49 -0
- package/dist/utils/isOneLineExpressionExport.js.map +1 -0
- package/dist/utils/notNullOrUndefined.d.ts +2 -0
- package/dist/utils/notNullOrUndefined.d.ts.map +1 -0
- package/dist/utils/notNullOrUndefined.js +4 -0
- package/dist/utils/notNullOrUndefined.js.map +1 -0
- package/dist/utils/toArrayLocation.d.ts +5 -0
- package/dist/utils/toArrayLocation.d.ts.map +1 -0
- package/dist/utils/toArrayLocation.js +14 -0
- package/dist/utils/toArrayLocation.js.map +1 -0
- package/dist/warnings.d.ts +88 -0
- package/dist/warnings.d.ts.map +1 -0
- package/dist/warnings.js +91 -0
- package/dist/warnings.js.map +1 -0
- package/package.json +59 -77
- package/index.d.ts +0 -46
- package/index.js +0 -4
- package/src/AstAnalyser.js +0 -222
- package/src/Deobfuscator.js +0 -195
- package/src/EntryFilesAnalyser.js +0 -167
- package/src/JsSourceParser.js +0 -57
- package/src/NodeCounter.js +0 -76
- package/src/ProbeRunner.js +0 -144
- package/src/SourceFile.js +0 -147
- package/src/obfuscators/freejsobfuscator.js +0 -9
- package/src/obfuscators/jjencode.js +0 -27
- package/src/obfuscators/jsfuck.js +0 -11
- package/src/obfuscators/obfuscator-io.js +0 -13
- package/src/obfuscators/trojan-source.js +0 -28
- package/src/probes/isBinaryExpression.js +0 -55
- package/src/probes/isESMExport.js +0 -31
- package/src/probes/isFetch.js +0 -19
- package/src/probes/isImportDeclaration.js +0 -33
- package/src/probes/isLiteral.js +0 -70
- package/src/probes/isLiteralRegex.js +0 -31
- package/src/probes/isRegexObject.js +0 -49
- package/src/probes/isRequire/RequireCallExpressionWalker.js +0 -93
- package/src/probes/isRequire/isRequire.js +0 -148
- package/src/probes/isUnsafeCallee.js +0 -35
- package/src/probes/isWeakCrypto.js +0 -37
- package/src/utils/exportAssignmentHasRequireLeave.js +0 -40
- package/src/utils/extractNode.js +0 -14
- package/src/utils/index.js +0 -8
- package/src/utils/isNode.js +0 -5
- package/src/utils/isOneLineExpressionExport.js +0 -24
- package/src/utils/isUnsafeCallee.js +0 -28
- package/src/utils/notNullOrUndefined.js +0 -3
- package/src/utils/rootLocation.js +0 -3
- package/src/utils/toArrayLocation.js +0 -11
- package/src/warnings.js +0 -77
- package/types/api.d.ts +0 -177
- package/types/warnings.d.ts +0 -36
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import { getVariableDeclarationIdentifiers } from "@nodesecure/estree-ast-utils";
|
|
3
|
+
import { Utils, Patterns } from "@nodesecure/sec-literal";
|
|
4
|
+
import { match } from "ts-pattern";
|
|
5
|
+
// Import Internal Dependencies
|
|
6
|
+
import { NodeCounter } from "./NodeCounter.js";
|
|
7
|
+
import { extractNode } from "./utils/index.js";
|
|
8
|
+
import * as jjencode from "./obfuscators/jjencode.js";
|
|
9
|
+
import * as jsfuck from "./obfuscators/jsfuck.js";
|
|
10
|
+
import * as freejsobfuscator from "./obfuscators/freejsobfuscator.js";
|
|
11
|
+
import * as obfuscatorio from "./obfuscators/obfuscator-io.js";
|
|
12
|
+
// CONSTANTS
|
|
13
|
+
const kIdentifierNodeExtractor = extractNode("Identifier");
|
|
14
|
+
const kDictionaryStrParts = [
|
|
15
|
+
"abcdefghijklmnopqrstuvwxyz",
|
|
16
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
17
|
+
"0123456789"
|
|
18
|
+
];
|
|
19
|
+
const kMinimumIdsCount = 5;
|
|
20
|
+
export class Deobfuscator {
|
|
21
|
+
deepBinaryExpression = 0;
|
|
22
|
+
encodedArrayValue = 0;
|
|
23
|
+
hasDictionaryString = false;
|
|
24
|
+
hasPrefixedIdentifiers = false;
|
|
25
|
+
morseLiterals = new Set();
|
|
26
|
+
literalScores = [];
|
|
27
|
+
identifiers = [];
|
|
28
|
+
#counters = [
|
|
29
|
+
new NodeCounter("VariableDeclaration[kind]"),
|
|
30
|
+
new NodeCounter("AssignmentExpression", {
|
|
31
|
+
match: (node, nc) => this.#extractCounterIdentifiers(nc, node.left)
|
|
32
|
+
}),
|
|
33
|
+
new NodeCounter("FunctionDeclaration", {
|
|
34
|
+
match: (node, nc) => this.#extractCounterIdentifiers(nc, node.id)
|
|
35
|
+
}),
|
|
36
|
+
new NodeCounter("MemberExpression[computed]"),
|
|
37
|
+
new NodeCounter("Property", {
|
|
38
|
+
filter: (node) => node.key.type === "Identifier",
|
|
39
|
+
match: (node, nc) => this.#extractCounterIdentifiers(nc, node.key)
|
|
40
|
+
}),
|
|
41
|
+
new NodeCounter("UnaryExpression", {
|
|
42
|
+
name: "DoubleUnaryExpression",
|
|
43
|
+
filter: ({ argument }) => argument.type === "UnaryExpression" && argument.argument.type === "ArrayExpression"
|
|
44
|
+
}),
|
|
45
|
+
new NodeCounter("VariableDeclarator", {
|
|
46
|
+
match: (node, nc) => this.#extractCounterIdentifiers(nc, node.id)
|
|
47
|
+
})
|
|
48
|
+
];
|
|
49
|
+
#extractCounterIdentifiers(nc, node) {
|
|
50
|
+
if (node === null) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const { type } = nc;
|
|
54
|
+
switch (type) {
|
|
55
|
+
case "VariableDeclarator":
|
|
56
|
+
case "AssignmentExpression": {
|
|
57
|
+
for (const { name } of getVariableDeclarationIdentifiers(node)) {
|
|
58
|
+
this.identifiers.push({ name, type });
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
case "Property":
|
|
63
|
+
case "FunctionDeclaration":
|
|
64
|
+
if (node.type === "Identifier") {
|
|
65
|
+
this.identifiers.push({ name: node.name, type });
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
analyzeString(str) {
|
|
71
|
+
const score = Utils.stringSuspicionScore(str);
|
|
72
|
+
if (score !== 0) {
|
|
73
|
+
this.literalScores.push(score);
|
|
74
|
+
}
|
|
75
|
+
if (!this.hasDictionaryString) {
|
|
76
|
+
const isDictionaryStr = kDictionaryStrParts.every((word) => str.includes(word));
|
|
77
|
+
if (isDictionaryStr) {
|
|
78
|
+
this.hasDictionaryString = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Searching for morse string like "--.- --.--"
|
|
82
|
+
if (Utils.isMorse(str)) {
|
|
83
|
+
this.morseLiterals.add(str);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
walk(node) {
|
|
87
|
+
const nodesToExtract = match(node)
|
|
88
|
+
.with({ type: "ClassDeclaration" }, (node) => [node.id, node.superClass])
|
|
89
|
+
.with({ type: "FunctionDeclaration" }, (node) => node.params)
|
|
90
|
+
.with({ type: "FunctionExpression" }, (node) => node.params)
|
|
91
|
+
.with({ type: "MethodDefinition" }, (node) => [node.key])
|
|
92
|
+
.otherwise(() => []);
|
|
93
|
+
const isFunctionParams = node.type === "FunctionDeclaration" ||
|
|
94
|
+
node.type === "FunctionExpression";
|
|
95
|
+
kIdentifierNodeExtractor(({ name }) => this.identifiers.push({
|
|
96
|
+
name,
|
|
97
|
+
type: isFunctionParams ? "FunctionParams" : node.type
|
|
98
|
+
}), nodesToExtract);
|
|
99
|
+
this.#counters.forEach((counter) => counter.walk(node));
|
|
100
|
+
}
|
|
101
|
+
aggregateCounters() {
|
|
102
|
+
return this.#counters.reduce((result, counter) => {
|
|
103
|
+
result[counter.name] = counter.lookup ?
|
|
104
|
+
counter.properties :
|
|
105
|
+
counter.count;
|
|
106
|
+
return result;
|
|
107
|
+
}, {
|
|
108
|
+
Identifiers: this.identifiers.length
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
#calcAvgPrefixedIdentifiers(counters, prefix) {
|
|
112
|
+
const valuesArr = Object
|
|
113
|
+
.values(prefix)
|
|
114
|
+
.slice()
|
|
115
|
+
.sort((left, right) => left - right);
|
|
116
|
+
if (valuesArr.length === 0) {
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
const nbOfPrefixedIds = valuesArr.length === 1 ?
|
|
120
|
+
valuesArr.pop() :
|
|
121
|
+
(valuesArr.pop() + valuesArr.pop());
|
|
122
|
+
const maxIds = counters.Identifiers - (counters.Property ?? 0);
|
|
123
|
+
return ((nbOfPrefixedIds / maxIds) * 100);
|
|
124
|
+
}
|
|
125
|
+
assertObfuscation() {
|
|
126
|
+
const counters = this.aggregateCounters();
|
|
127
|
+
if (jsfuck.verify(counters)) {
|
|
128
|
+
return "jsfuck";
|
|
129
|
+
}
|
|
130
|
+
if (jjencode.verify(this.identifiers, counters)) {
|
|
131
|
+
return "jjencode";
|
|
132
|
+
}
|
|
133
|
+
if (this.morseLiterals.size >= 36) {
|
|
134
|
+
return "morse";
|
|
135
|
+
}
|
|
136
|
+
const { prefix } = Patterns.commonHexadecimalPrefix(this.identifiers.flatMap(({ name }) => (typeof name === "string" ? [name] : [])));
|
|
137
|
+
const uPrefixNames = new Set(Object.keys(prefix));
|
|
138
|
+
if (this.identifiers.length > kMinimumIdsCount && uPrefixNames.size > 0) {
|
|
139
|
+
this.hasPrefixedIdentifiers = this.#calcAvgPrefixedIdentifiers(counters, prefix) > 80;
|
|
140
|
+
}
|
|
141
|
+
if (uPrefixNames.size === 1 && freejsobfuscator.verify(this.identifiers, prefix)) {
|
|
142
|
+
return "freejsobfuscator";
|
|
143
|
+
}
|
|
144
|
+
if (obfuscatorio.verify(this, counters)) {
|
|
145
|
+
return "obfuscator.io";
|
|
146
|
+
}
|
|
147
|
+
// if ((identifierLength > (kMinimumIdsCount * 3) && this.hasPrefixedIdentifiers)
|
|
148
|
+
// && (oneTimeOccurence <= 3 || this.encodedArrayValue > 0)) {
|
|
149
|
+
// return "unknown";
|
|
150
|
+
// }
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=Deobfuscator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Deobfuscator.js","sourceRoot":"","sources":["../src/Deobfuscator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DiGraph, type VertexBody, type VertexDefinition } from "digraph-js";
|
|
2
|
+
import { AstAnalyser, type ReportOnFile, type RuntimeFileOptions } from "./AstAnalyser.js";
|
|
3
|
+
export interface EntryFilesAnalyserOptions {
|
|
4
|
+
astAnalyzer?: AstAnalyser;
|
|
5
|
+
loadExtensions?: (defaults: string[]) => string[];
|
|
6
|
+
rootPath?: string | URL;
|
|
7
|
+
ignoreENOENT?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class EntryFilesAnalyser {
|
|
10
|
+
#private;
|
|
11
|
+
astAnalyzer: AstAnalyser;
|
|
12
|
+
allowedExtensions: Set<string>;
|
|
13
|
+
dependencies: DiGraph<VertexDefinition<VertexBody>>;
|
|
14
|
+
ignoreENOENT: boolean;
|
|
15
|
+
constructor(options?: EntryFilesAnalyserOptions);
|
|
16
|
+
analyse(entryFiles: Iterable<string | URL>, options?: RuntimeFileOptions): AsyncGenerator<ReportOnFile & {
|
|
17
|
+
file: string;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=EntryFilesAnalyser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntryFilesAnalyser.d.ts","sourceRoot":"","sources":["../src/EntryFilesAnalyser.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,OAAO,EACP,KAAK,UAAU,EACf,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAK1B,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,kBAAkB;;IAE7B,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,YAAY,EAAE,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;IACpD,YAAY,EAAE,OAAO,CAAC;gBAGpB,OAAO,GAAE,yBAA8B;IAoBlC,OAAO,CACZ,UAAU,EAAE,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,EAClC,OAAO,GAAE,kBAAuB,GAC/B,cAAc,CAAC,YAAY,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;KAAE,CAAC;CAyIpD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Import Node.js Dependencies
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
// Import Third-party Dependencies
|
|
6
|
+
import { DiGraph } from "digraph-js";
|
|
7
|
+
// Import Internal Dependencies
|
|
8
|
+
import { AstAnalyser } from "./AstAnalyser.js";
|
|
9
|
+
// CONSTANTS
|
|
10
|
+
const kDefaultExtensions = ["js", "cjs", "mjs", "node"];
|
|
11
|
+
export class EntryFilesAnalyser {
|
|
12
|
+
#rootPath = null;
|
|
13
|
+
astAnalyzer;
|
|
14
|
+
allowedExtensions;
|
|
15
|
+
dependencies;
|
|
16
|
+
ignoreENOENT;
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
const { astAnalyzer = new AstAnalyser(), loadExtensions, rootPath = null, ignoreENOENT = false } = options;
|
|
19
|
+
this.astAnalyzer = astAnalyzer;
|
|
20
|
+
const rawAllowedExtensions = loadExtensions
|
|
21
|
+
? loadExtensions(kDefaultExtensions)
|
|
22
|
+
: kDefaultExtensions;
|
|
23
|
+
this.allowedExtensions = new Set(rawAllowedExtensions);
|
|
24
|
+
this.#rootPath = rootPath === null ?
|
|
25
|
+
null : fileURLToPathExtended(rootPath);
|
|
26
|
+
this.ignoreENOENT = ignoreENOENT;
|
|
27
|
+
}
|
|
28
|
+
async *analyse(entryFiles, options = {}) {
|
|
29
|
+
this.dependencies = new DiGraph();
|
|
30
|
+
for (const entryFile of new Set(entryFiles)) {
|
|
31
|
+
const normalizedEntryFile = this.#normalizeAndCleanEntryFile(entryFile);
|
|
32
|
+
if (this.ignoreENOENT &&
|
|
33
|
+
!await this.#fileExists(normalizedEntryFile)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
yield* this.#analyseFile(normalizedEntryFile, this.#getRelativeFilePath(normalizedEntryFile), options);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
#normalizeAndCleanEntryFile(file) {
|
|
40
|
+
let normalizedEntryFile = path.normalize(fileURLToPathExtended(file));
|
|
41
|
+
if (this.#rootPath !== null && !path.isAbsolute(normalizedEntryFile)) {
|
|
42
|
+
normalizedEntryFile = path.join(this.#rootPath, normalizedEntryFile);
|
|
43
|
+
}
|
|
44
|
+
return normalizedEntryFile;
|
|
45
|
+
}
|
|
46
|
+
#getRelativeFilePath(file) {
|
|
47
|
+
return this.#rootPath ?
|
|
48
|
+
path.relative(this.#rootPath, file) :
|
|
49
|
+
file;
|
|
50
|
+
}
|
|
51
|
+
async *#analyseFile(file, relativeFile, options) {
|
|
52
|
+
this.dependencies.addVertex({
|
|
53
|
+
id: relativeFile,
|
|
54
|
+
adjacentTo: [],
|
|
55
|
+
body: {}
|
|
56
|
+
});
|
|
57
|
+
const report = await this.astAnalyzer.analyseFile(file, options);
|
|
58
|
+
yield { file: relativeFile, ...report };
|
|
59
|
+
if (!report.ok || typeof report.dependencies === "undefined") {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
for (const [name] of report.dependencies) {
|
|
63
|
+
const depFile = await this.#getInternalDepPath(path.join(path.dirname(file), name));
|
|
64
|
+
if (depFile === null) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const depRelativeFile = this.#getRelativeFilePath(depFile);
|
|
68
|
+
if (!this.dependencies.hasVertex(depRelativeFile)) {
|
|
69
|
+
this.dependencies.addVertex({
|
|
70
|
+
id: depRelativeFile,
|
|
71
|
+
adjacentTo: [],
|
|
72
|
+
body: {}
|
|
73
|
+
});
|
|
74
|
+
yield* this.#analyseFile(depFile, depRelativeFile, options);
|
|
75
|
+
}
|
|
76
|
+
this.dependencies.addEdge({
|
|
77
|
+
from: relativeFile, to: depRelativeFile
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async #getInternalDepPath(filePath) {
|
|
82
|
+
const fileExtension = path.extname(filePath);
|
|
83
|
+
if (fileExtension === "") {
|
|
84
|
+
for (const ext of this.allowedExtensions) {
|
|
85
|
+
const depPathWithExt = `${filePath}.${ext}`;
|
|
86
|
+
const fileExist = await this.#fileExists(depPathWithExt);
|
|
87
|
+
if (fileExist) {
|
|
88
|
+
return depPathWithExt;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
if (!this.allowedExtensions.has(fileExtension.slice(1))) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const fileExist = await this.#fileExists(filePath);
|
|
97
|
+
if (fileExist) {
|
|
98
|
+
return filePath;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
async #fileExists(filePath) {
|
|
104
|
+
try {
|
|
105
|
+
await fs.access(filePath, fs.constants.R_OK);
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error.code !== "ENOENT") {
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function fileURLToPathExtended(file) {
|
|
117
|
+
return file instanceof URL ?
|
|
118
|
+
fileURLToPath(file) :
|
|
119
|
+
file;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=EntryFilesAnalyser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntryFilesAnalyser.js","sourceRoot":"","sources":["../src/EntryFilesAnalyser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ESTree } from "meriyah";
|
|
2
|
+
export type SourceParserSyntaxError = SyntaxError & {
|
|
3
|
+
start: number;
|
|
4
|
+
end: number;
|
|
5
|
+
range: [number, number];
|
|
6
|
+
description: string;
|
|
7
|
+
loc: ESTree.SourceLocation;
|
|
8
|
+
};
|
|
9
|
+
export interface SourceParser {
|
|
10
|
+
parse(source: string, options: unknown): ESTree.Statement[];
|
|
11
|
+
}
|
|
12
|
+
export interface JsSourceParserOptions {
|
|
13
|
+
isEcmaScriptModule?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare class JsSourceParser implements SourceParser {
|
|
16
|
+
parse(source: string, options?: JsSourceParserOptions): ESTree.Program["body"];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=JsSourceParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsSourceParser.d.ts","sourceRoot":"","sources":["../src/JsSourceParser.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,MAAM,EAEZ,MAAM,SAAS,CAAC;AAUjB,MAAM,MAAM,uBAAuB,GAAG,WAAW,GAAG;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,qBAAa,cAAe,YAAW,YAAY;IACjD,KAAK,CACH,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;CAyC1B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import { parseScript } from "meriyah";
|
|
3
|
+
// CONSTANTS
|
|
4
|
+
const kParsingOptions = {
|
|
5
|
+
next: true,
|
|
6
|
+
loc: true,
|
|
7
|
+
raw: true,
|
|
8
|
+
jsx: true
|
|
9
|
+
};
|
|
10
|
+
export class JsSourceParser {
|
|
11
|
+
parse(source, options = {}) {
|
|
12
|
+
const { isEcmaScriptModule } = options;
|
|
13
|
+
try {
|
|
14
|
+
const { body } = parseScript(source, {
|
|
15
|
+
...kParsingOptions,
|
|
16
|
+
module: isEcmaScriptModule,
|
|
17
|
+
globalReturn: !isEcmaScriptModule
|
|
18
|
+
});
|
|
19
|
+
return body;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
const syntaxError = error;
|
|
23
|
+
const isIllegalReturn = syntaxError.description.includes("Illegal return statement");
|
|
24
|
+
if (syntaxError.name === "SyntaxError" && (syntaxError.description.includes("The import keyword") ||
|
|
25
|
+
syntaxError.description.includes("The export keyword") ||
|
|
26
|
+
isIllegalReturn)) {
|
|
27
|
+
const { body } = parseScript(source, {
|
|
28
|
+
...kParsingOptions,
|
|
29
|
+
module: true,
|
|
30
|
+
globalReturn: isIllegalReturn
|
|
31
|
+
});
|
|
32
|
+
return body;
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=JsSourceParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsSourceParser.js","sourceRoot":"","sources":["../src/JsSourceParser.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EACL,WAAW,EAGZ,MAAM,SAAS,CAAC;AAEjB,YAAY;AACZ,MAAM,eAAe,GAAqB;IACxC,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;CACV,CAAC;AAkBF,MAAM,OAAO,cAAc;IACzB,KAAK,CACH,MAAc,EACd,UAAiC,EAAE;QAEnC,MAAM,EACJ,kBAAkB,EACnB,GAAG,OAAO,CAAC;QAEZ,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAC1B,MAAM,EACN;gBACE,GAAG,eAAe;gBAClB,MAAM,EAAE,kBAAkB;gBAC1B,YAAY,EAAE,CAAC,kBAAkB;aAClC,CACF,CAAC;YAEF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAc,EAAE,CAAC;YACtB,MAAM,WAAW,GAAG,KAAgC,CAAC;YACrD,MAAM,eAAe,GAAG,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;YAErF,IAAI,WAAW,CAAC,IAAI,KAAK,aAAa,IAAI,CACxC,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,oBAAoB,CAAC;gBACtD,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,oBAAoB,CAAC;gBACtD,eAAe,CAChB,EAAE,CAAC;gBACF,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAC1B,MAAM,EACN;oBACE,GAAG,eAAe;oBAClB,MAAM,EAAE,IAAI;oBACZ,YAAY,EAAE,eAAe;iBAC9B,CACF,CAAC;gBAEF,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ESTree } from "meriyah";
|
|
2
|
+
export type NodeCounterFilterCallback<T extends ESTree.Node> = (node: T) => boolean;
|
|
3
|
+
export type NodeCounterMatchCallback<T extends ESTree.Node> = (node: T, nc: NodeCounter<T>) => void;
|
|
4
|
+
export interface NodeCounterOptions<T extends ESTree.Node> {
|
|
5
|
+
name?: string;
|
|
6
|
+
filter?: NodeCounterFilterCallback<T>;
|
|
7
|
+
match?: NodeCounterMatchCallback<T>;
|
|
8
|
+
}
|
|
9
|
+
export declare class NodeCounter<T extends ESTree.Node = ESTree.Node> {
|
|
10
|
+
#private;
|
|
11
|
+
type: string;
|
|
12
|
+
name: string;
|
|
13
|
+
lookup: string | null;
|
|
14
|
+
/**
|
|
15
|
+
* @example
|
|
16
|
+
* new NodeCounter("FunctionDeclaration");
|
|
17
|
+
* new NodeCounter("VariableDeclaration[kind]");
|
|
18
|
+
*/
|
|
19
|
+
constructor(type: string, options?: NodeCounterOptions<T>);
|
|
20
|
+
get count(): number;
|
|
21
|
+
get properties(): Record<string, number>;
|
|
22
|
+
walk(node: ESTree.Node): void;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=NodeCounter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeCounter.d.ts","sourceRoot":"","sources":["../src/NodeCounter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAStC,MAAM,MAAM,yBAAyB,CAAC,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;AACpF,MAAM,MAAM,wBAAwB,CAAC,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAEpG,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,IAAI;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,yBAAyB,CAAC,CAAC,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAC;CACrC;AAED,qBAAa,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAO7B;;;;OAIG;gBAED,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAkB,CAAC,CAAC,CAAM;IAqBrC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIvC;IAED,IAAI,CACF,IAAI,EAAE,MAAM,CAAC,IAAI,GAChB,IAAI;CAmBR"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import FrequencySet from "frequency-set";
|
|
3
|
+
// Import Internal Dependencies
|
|
4
|
+
import { isNode } from "./types/estree.js";
|
|
5
|
+
function noop() {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
export class NodeCounter {
|
|
9
|
+
type;
|
|
10
|
+
name;
|
|
11
|
+
lookup = null;
|
|
12
|
+
#count = 0;
|
|
13
|
+
#properties = null;
|
|
14
|
+
#filterFn = noop;
|
|
15
|
+
#matchFn = noop;
|
|
16
|
+
/**
|
|
17
|
+
* @example
|
|
18
|
+
* new NodeCounter("FunctionDeclaration");
|
|
19
|
+
* new NodeCounter("VariableDeclaration[kind]");
|
|
20
|
+
*/
|
|
21
|
+
constructor(type, options = {}) {
|
|
22
|
+
if (typeof type !== "string") {
|
|
23
|
+
throw new TypeError("type must be a string");
|
|
24
|
+
}
|
|
25
|
+
const typeResult = /([A-Za-z]+)(\[[a-zA-Z]+\])?/g.exec(type);
|
|
26
|
+
if (typeResult === null) {
|
|
27
|
+
throw new Error("invalid type argument syntax");
|
|
28
|
+
}
|
|
29
|
+
this.type = typeResult[1];
|
|
30
|
+
this.lookup = typeResult[2]?.slice(1, -1) ?? null;
|
|
31
|
+
this.name = options?.name ?? this.type;
|
|
32
|
+
if (this.lookup) {
|
|
33
|
+
this.#properties = new FrequencySet();
|
|
34
|
+
}
|
|
35
|
+
this.#filterFn = options.filter ?? noop;
|
|
36
|
+
this.#matchFn = options.match ?? noop;
|
|
37
|
+
}
|
|
38
|
+
get count() {
|
|
39
|
+
return this.#count;
|
|
40
|
+
}
|
|
41
|
+
get properties() {
|
|
42
|
+
return Object.fromEntries(this.#properties?.entries() ?? []);
|
|
43
|
+
}
|
|
44
|
+
walk(node) {
|
|
45
|
+
if (!isNode(node) || node.type !== this.type) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const castedNode = node;
|
|
49
|
+
if (!this.#filterFn(castedNode)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.#count++;
|
|
53
|
+
if (this.lookup === null) {
|
|
54
|
+
this.#matchFn(castedNode, this);
|
|
55
|
+
}
|
|
56
|
+
else if (this.lookup in node) {
|
|
57
|
+
this.#properties?.add(node[this.lookup]);
|
|
58
|
+
this.#matchFn(castedNode, this);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=NodeCounter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeCounter.js","sourceRoot":"","sources":["../src/NodeCounter.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,YAAY,MAAM,eAAe,CAAC;AAGzC,+BAA+B;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,SAAS,IAAI;IACX,OAAO,IAAI,CAAC;AACd,CAAC;AAWD,MAAM,OAAO,WAAW;IACtB,IAAI,CAAS;IACb,IAAI,CAAS;IACb,MAAM,GAAkB,IAAI,CAAC;IAE7B,MAAM,GAAG,CAAC,CAAC;IACX,WAAW,GAAgC,IAAI,CAAC;IAChD,SAAS,GAAiC,IAAI,CAAC;IAC/C,QAAQ,GAAgC,IAAI,CAAC;IAE7C;;;;OAIG;IACH,YACE,IAAY,EACZ,UAAiC,EAAE;QAEnC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,UAAU,GAAG,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;QACvC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,EAAE,CAAC;QACxC,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;IACxC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,MAAM,CAAC,WAAW,CACvB,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAClC,CAAC;IACJ,CAAC;IAED,IAAI,CACF,IAAiB;QAEjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7C,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,IAAS,CAAC;QAE7B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;aACI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ESTree } from "meriyah";
|
|
2
|
+
import type { SourceFile } from "./SourceFile.js";
|
|
3
|
+
import type { OptionalWarningName } from "./warnings.js";
|
|
4
|
+
export type ProbeReturn = void | null | symbol;
|
|
5
|
+
export type ProbeInitializeCallback = (sourceFile: SourceFile) => void;
|
|
6
|
+
export type ProbeMainCallback = (node: any, options: {
|
|
7
|
+
sourceFile: SourceFile;
|
|
8
|
+
data?: any;
|
|
9
|
+
}) => ProbeReturn;
|
|
10
|
+
export type ProbeTeardownCallback = (options: {
|
|
11
|
+
sourceFile: SourceFile;
|
|
12
|
+
}) => void;
|
|
13
|
+
export type ProbeValidationCallback = (node: ESTree.Node, sourceFile: SourceFile) => [boolean, any?];
|
|
14
|
+
export interface Probe {
|
|
15
|
+
name: string;
|
|
16
|
+
initialize?: ProbeInitializeCallback;
|
|
17
|
+
validateNode: ProbeValidationCallback | ProbeValidationCallback[];
|
|
18
|
+
main: ProbeMainCallback;
|
|
19
|
+
teardown?: ProbeTeardownCallback;
|
|
20
|
+
breakOnMatch?: boolean;
|
|
21
|
+
breakGroup?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const ProbeSignals: Readonly<{
|
|
24
|
+
Break: symbol;
|
|
25
|
+
Skip: symbol;
|
|
26
|
+
}>;
|
|
27
|
+
export declare class ProbeRunner {
|
|
28
|
+
#private;
|
|
29
|
+
probes: Probe[];
|
|
30
|
+
sourceFile: SourceFile;
|
|
31
|
+
/**
|
|
32
|
+
* Note:
|
|
33
|
+
* The order of the table has an importance/impact on the correct execution of the probes
|
|
34
|
+
*/
|
|
35
|
+
static Defaults: Probe[];
|
|
36
|
+
static Optionals: Record<OptionalWarningName, Probe>;
|
|
37
|
+
constructor(sourceFile: SourceFile, probes?: Probe[]);
|
|
38
|
+
walk(node: ESTree.Node): null | "skip";
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=ProbeRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProbeRunner.d.ts","sourceRoot":"","sources":["../src/ProbeRunner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAkBtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAC/C,MAAM,MAAM,uBAAuB,GAAG,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;AACvE,MAAM,MAAM,iBAAiB,GAAG,CAC9B,IAAI,EAAE,GAAG,EACT,OAAO,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,CAAC;CAAE,KAC7C,WAAW,CAAC;AACjB,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;CAAE,KAAK,IAAI,CAAC;AACnF,MAAM,MAAM,uBAAuB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;AAErG,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,YAAY,EAAE,uBAAuB,GAAG,uBAAuB,EAAE,CAAC;IAClE,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,YAAY;;;EAGvB,CAAC;AAEH,qBAAa,WAAW;;IACtB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,CActB;IAEF,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAElD;gBAGA,UAAU,EAAE,UAAU,EACtB,MAAM,GAAE,KAAK,EAAyB;IAgDxC,IAAI,CACF,IAAI,EAAE,MAAM,CAAC,IAAI,GAChB,IAAI,GAAG,MAAM;CAqCjB"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Import Node.js Dependencies
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
// Import Internal Dependencies
|
|
4
|
+
import isUnsafeCallee from "./probes/isUnsafeCallee.js";
|
|
5
|
+
import isLiteral from "./probes/isLiteral.js";
|
|
6
|
+
import isLiteralRegex from "./probes/isLiteralRegex.js";
|
|
7
|
+
import isRegexObject from "./probes/isRegexObject.js";
|
|
8
|
+
import isRequire from "./probes/isRequire/isRequire.js";
|
|
9
|
+
import isImportDeclaration from "./probes/isImportDeclaration.js";
|
|
10
|
+
import isWeakCrypto from "./probes/isWeakCrypto.js";
|
|
11
|
+
import isBinaryExpression from "./probes/isBinaryExpression.js";
|
|
12
|
+
import isArrayExpression from "./probes/isArrayExpression.js";
|
|
13
|
+
import isESMExport from "./probes/isESMExport.js";
|
|
14
|
+
import isFetch from "./probes/isFetch.js";
|
|
15
|
+
import isUnsafeCommand from "./probes/isUnsafeCommand.js";
|
|
16
|
+
import isSyncIO from "./probes/isSyncIO.js";
|
|
17
|
+
import isSerializeEnv from "./probes/isSerializeEnv.js";
|
|
18
|
+
export const ProbeSignals = Object.freeze({
|
|
19
|
+
Break: Symbol.for("breakWalk"),
|
|
20
|
+
Skip: Symbol.for("skipWalk")
|
|
21
|
+
});
|
|
22
|
+
export class ProbeRunner {
|
|
23
|
+
probes;
|
|
24
|
+
sourceFile;
|
|
25
|
+
/**
|
|
26
|
+
* Note:
|
|
27
|
+
* The order of the table has an importance/impact on the correct execution of the probes
|
|
28
|
+
*/
|
|
29
|
+
static Defaults = [
|
|
30
|
+
isFetch,
|
|
31
|
+
isRequire,
|
|
32
|
+
isESMExport,
|
|
33
|
+
isUnsafeCallee,
|
|
34
|
+
isLiteral,
|
|
35
|
+
isLiteralRegex,
|
|
36
|
+
isRegexObject,
|
|
37
|
+
isImportDeclaration,
|
|
38
|
+
isWeakCrypto,
|
|
39
|
+
isBinaryExpression,
|
|
40
|
+
isArrayExpression,
|
|
41
|
+
isUnsafeCommand,
|
|
42
|
+
isSerializeEnv
|
|
43
|
+
];
|
|
44
|
+
static Optionals = {
|
|
45
|
+
"synchronous-io": isSyncIO
|
|
46
|
+
};
|
|
47
|
+
constructor(sourceFile, probes = ProbeRunner.Defaults) {
|
|
48
|
+
this.sourceFile = sourceFile;
|
|
49
|
+
for (const probe of probes) {
|
|
50
|
+
assert(typeof probe.validateNode === "function" || Array.isArray(probe.validateNode), `Invalid probe ${probe.name}: validateNode must be a function or an array of functions`);
|
|
51
|
+
assert(typeof probe.main === "function", `Invalid probe ${probe.name}: main must be a function`);
|
|
52
|
+
assert(typeof probe.initialize === "function" || probe.initialize === undefined, `Invalid probe ${probe.name}: initialize must be a function or undefined`);
|
|
53
|
+
if (probe.initialize) {
|
|
54
|
+
probe.initialize(sourceFile);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
this.probes = probes;
|
|
58
|
+
}
|
|
59
|
+
#runProbe(probe, node) {
|
|
60
|
+
const validationFns = Array.isArray(probe.validateNode) ?
|
|
61
|
+
probe.validateNode : [probe.validateNode];
|
|
62
|
+
for (const validateNode of validationFns) {
|
|
63
|
+
const [isMatching, data = null] = validateNode(node, this.sourceFile);
|
|
64
|
+
if (isMatching) {
|
|
65
|
+
return probe.main(node, {
|
|
66
|
+
sourceFile: this.sourceFile,
|
|
67
|
+
data
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
walk(node) {
|
|
74
|
+
const breakGroups = new Set();
|
|
75
|
+
for (const probe of this.probes) {
|
|
76
|
+
if (probe.breakGroup && breakGroups.has(probe.breakGroup)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const result = this.#runProbe(probe, node);
|
|
81
|
+
if (result === null) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (result === ProbeSignals.Skip) {
|
|
85
|
+
return "skip";
|
|
86
|
+
}
|
|
87
|
+
if (result === ProbeSignals.Break || probe.breakOnMatch) {
|
|
88
|
+
const breakGroup = probe.breakGroup || null;
|
|
89
|
+
if (breakGroup === null) {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
breakGroups.add(breakGroup);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
if (probe.teardown) {
|
|
99
|
+
probe.teardown({ sourceFile: this.sourceFile });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=ProbeRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProbeRunner.js","sourceRoot":"","sources":["../src/ProbeRunner.ts"],"names":[],"mappings":"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"}
|