@eventra_dev/eventra-cli 0.1.34 → 0.2.1
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/dist/commands/check.js +14 -30
- package/dist/commands/sync.js +9 -27
- package/dist/commands/watch.js +38 -121
- package/dist/engine/engine.js +14 -9
- package/dist/engine/scanner.js +41 -28
- package/dist/utils/universal.js +1 -1
- package/package.json +1 -1
- package/src/commands/check.ts +17 -48
- package/src/commands/sync.ts +14 -44
- package/src/commands/watch.ts +48 -158
- package/src/engine/engine.ts +20 -12
- package/src/engine/scanner.ts +67 -27
- package/src/utils/universal.ts +1 -1
package/src/engine/scanner.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { resolveFunctionFromCall } from "./callResolver";
|
|
|
4
4
|
import { resolveExportedSymbol } from "./exportResolver";
|
|
5
5
|
import { EventraConfig, ScanResult } from "../types";
|
|
6
6
|
|
|
7
|
+
// HELPERS
|
|
7
8
|
function isValidEvent(v: string) {
|
|
8
9
|
return (
|
|
9
10
|
v &&
|
|
@@ -32,6 +33,7 @@ function getJsxAttrName(name: ts.JsxAttributeName): string {
|
|
|
32
33
|
return "";
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
// MAIN
|
|
35
37
|
export function scanSource(
|
|
36
38
|
source: ts.SourceFile,
|
|
37
39
|
checker: ts.TypeChecker,
|
|
@@ -47,35 +49,52 @@ export function scanSource(
|
|
|
47
49
|
if (visited.has(source.fileName)) {
|
|
48
50
|
return { events, detectedFunctionWrappers, detectedComponentWrappers };
|
|
49
51
|
}
|
|
52
|
+
|
|
50
53
|
visited.add(source.fileName);
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
// TRACK DETECTION
|
|
56
|
+
function isTrackCall(expr: ts.Expression) {
|
|
57
|
+
if (ts.isIdentifier(expr)) {
|
|
58
|
+
return expr.text === "track";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
62
|
+
return expr.name.text === "track";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function extractTrackCall(
|
|
69
|
+
node: ts.CallExpression,
|
|
70
|
+
paramMap: Map<string, ts.Expression>
|
|
71
|
+
) {
|
|
72
|
+
if (!isTrackCall(node.expression)) return;
|
|
73
|
+
|
|
74
|
+
const arg = node.arguments[0];
|
|
75
|
+
if (!arg) return;
|
|
54
76
|
|
|
55
|
-
|
|
56
|
-
const arg = node.arguments[0];
|
|
57
|
-
if (!arg) return;
|
|
77
|
+
const res = resolveNodeValue(arg, checker, paramMap);
|
|
58
78
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
79
|
+
for (const v of res.values) {
|
|
80
|
+
if (isValidEvent(v)) {
|
|
81
|
+
events.add(v);
|
|
62
82
|
}
|
|
63
83
|
}
|
|
64
84
|
}
|
|
65
85
|
|
|
86
|
+
// WRAPPER DETECTION
|
|
66
87
|
function isWrapperFunction(fn: ts.FunctionLikeDeclaration) {
|
|
67
88
|
let found = false;
|
|
68
89
|
|
|
69
90
|
function walk(n: ts.Node) {
|
|
70
91
|
if (found) return;
|
|
71
92
|
|
|
72
|
-
if (ts.isCallExpression(n)) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
found = true;
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
93
|
+
if (ts.isCallExpression(n) && isTrackCall(n.expression)) {
|
|
94
|
+
found = true;
|
|
95
|
+
return;
|
|
78
96
|
}
|
|
97
|
+
|
|
79
98
|
ts.forEachChild(n, walk);
|
|
80
99
|
}
|
|
81
100
|
|
|
@@ -83,15 +102,20 @@ export function scanSource(
|
|
|
83
102
|
return found;
|
|
84
103
|
}
|
|
85
104
|
|
|
105
|
+
// COMPONENT WRAPPER
|
|
86
106
|
function detectComponentWrapper(tag: ts.JsxTagNameExpression): string | null {
|
|
87
107
|
const tagName = getJsxTagName(tag);
|
|
88
108
|
|
|
89
|
-
if (wrapperCache.has(tagName))
|
|
109
|
+
if (wrapperCache.has(tagName)) {
|
|
110
|
+
return wrapperCache.get(tagName)!;
|
|
111
|
+
}
|
|
90
112
|
|
|
91
113
|
let symbol = checker.getSymbolAtLocation(tag);
|
|
114
|
+
|
|
92
115
|
if (symbol && (symbol.flags & ts.SymbolFlags.Alias)) {
|
|
93
116
|
symbol = checker.getAliasedSymbol(symbol);
|
|
94
117
|
}
|
|
118
|
+
|
|
95
119
|
if (!symbol) {
|
|
96
120
|
wrapperCache.set(tagName, null);
|
|
97
121
|
return null;
|
|
@@ -120,21 +144,20 @@ export function scanSource(
|
|
|
120
144
|
function walk(n: ts.Node) {
|
|
121
145
|
if (prop) return;
|
|
122
146
|
|
|
123
|
-
if (ts.isCallExpression(n)) {
|
|
124
|
-
const
|
|
147
|
+
if (ts.isCallExpression(n) && isTrackCall(n.expression)) {
|
|
148
|
+
const arg = n.arguments[0];
|
|
125
149
|
|
|
126
|
-
if (ts.isPropertyAccessExpression(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
prop = arg.name.text;
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
150
|
+
if (ts.isPropertyAccessExpression(arg)) {
|
|
151
|
+
prop = arg.name.text;
|
|
152
|
+
return;
|
|
132
153
|
}
|
|
133
154
|
}
|
|
155
|
+
|
|
134
156
|
ts.forEachChild(n, walk);
|
|
135
157
|
}
|
|
136
158
|
|
|
137
159
|
walk(fn.body);
|
|
160
|
+
|
|
138
161
|
wrapperCache.set(tagName, prop);
|
|
139
162
|
|
|
140
163
|
if (prop) {
|
|
@@ -147,6 +170,7 @@ export function scanSource(
|
|
|
147
170
|
return null;
|
|
148
171
|
}
|
|
149
172
|
|
|
173
|
+
// VISITOR
|
|
150
174
|
function visit(node: ts.Node) {
|
|
151
175
|
// JSX
|
|
152
176
|
if (ts.isJsxSelfClosingElement(node) || ts.isJsxOpeningElement(node)) {
|
|
@@ -205,29 +229,45 @@ export function scanSource(
|
|
|
205
229
|
resolvedFn.parameters.forEach((p, i) => {
|
|
206
230
|
const arg = node.arguments[i];
|
|
207
231
|
if (!arg) return;
|
|
232
|
+
|
|
208
233
|
if (ts.isIdentifier(p.name)) {
|
|
209
234
|
paramMap.set(p.name.text, arg);
|
|
210
235
|
}
|
|
211
236
|
});
|
|
212
237
|
}
|
|
213
238
|
|
|
214
|
-
// direct track
|
|
215
239
|
extractTrackCall(node, paramMap);
|
|
216
240
|
|
|
217
|
-
// wrapper
|
|
218
241
|
if (resolvedFn && isWrapperFunction(resolvedFn)) {
|
|
219
242
|
const name = getCallName(node.expression);
|
|
243
|
+
|
|
220
244
|
if (name && name !== "track") {
|
|
221
245
|
detectedFunctionWrappers.add(name);
|
|
222
246
|
}
|
|
247
|
+
|
|
223
248
|
if (resolvedFn.body) {
|
|
224
249
|
visit(resolvedFn.body);
|
|
225
250
|
}
|
|
226
251
|
}
|
|
227
252
|
|
|
228
|
-
|
|
229
|
-
|
|
253
|
+
if (resolvedFn && resolvedFn.body) {
|
|
254
|
+
const sf = resolvedFn.getSourceFile();
|
|
255
|
+
|
|
256
|
+
if (!visited.has(sf.fileName)) {
|
|
257
|
+
const res = scanSource(
|
|
258
|
+
sf,
|
|
259
|
+
checker,
|
|
260
|
+
config,
|
|
261
|
+
visited,
|
|
262
|
+
paramMap,
|
|
263
|
+
wrapperCache
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
res.events.forEach(e => events.add(e));
|
|
267
|
+
}
|
|
230
268
|
}
|
|
269
|
+
|
|
270
|
+
node.arguments.forEach(visit);
|
|
231
271
|
visit(node.expression);
|
|
232
272
|
|
|
233
273
|
return;
|