@eventra_dev/eventra-cli 0.1.33 → 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/callResolver.js +32 -131
- package/dist/engine/engine.js +14 -9
- package/dist/engine/languageService.js +7 -38
- package/dist/engine/resolver.js +88 -77
- package/dist/engine/scanner.js +131 -196
- 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/callResolver.ts +24 -159
- package/src/engine/engine.ts +20 -12
- package/src/engine/languageService.ts +22 -52
- package/src/engine/resolver.ts +99 -120
- package/src/engine/scanner.ts +149 -243
- package/src/utils/universal.ts +1 -1
package/dist/engine/scanner.js
CHANGED
|
@@ -7,23 +7,14 @@ exports.scanSource = scanSource;
|
|
|
7
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
8
8
|
const resolver_1 = require("./resolver");
|
|
9
9
|
const callResolver_1 = require("./callResolver");
|
|
10
|
-
const functionAnalyzer_1 = require("./functionAnalyzer");
|
|
11
10
|
const exportResolver_1 = require("./exportResolver");
|
|
12
|
-
//
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
function getJsxTagName(tag) {
|
|
21
|
-
if (typescript_1.default.isIdentifier(tag))
|
|
22
|
-
return tag.text;
|
|
23
|
-
if (typescript_1.default.isPropertyAccessExpression(tag)) {
|
|
24
|
-
return tag.name.text;
|
|
25
|
-
}
|
|
26
|
-
return "";
|
|
11
|
+
// HELPERS
|
|
12
|
+
function isValidEvent(v) {
|
|
13
|
+
return (v &&
|
|
14
|
+
v.length > 1 &&
|
|
15
|
+
v.length < 120 &&
|
|
16
|
+
!v.includes(" ") &&
|
|
17
|
+
/^[a-zA-Z0-9._:-]+$/.test(v));
|
|
27
18
|
}
|
|
28
19
|
function getCallName(expr) {
|
|
29
20
|
if (typescript_1.default.isIdentifier(expr))
|
|
@@ -32,163 +23,132 @@ function getCallName(expr) {
|
|
|
32
23
|
return expr.name.text;
|
|
33
24
|
return "";
|
|
34
25
|
}
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
function getJsxTagName(tag) {
|
|
27
|
+
if (typescript_1.default.isIdentifier(tag))
|
|
28
|
+
return tag.text;
|
|
29
|
+
if (typescript_1.default.isPropertyAccessExpression(tag))
|
|
30
|
+
return tag.name.text;
|
|
31
|
+
return tag.getText();
|
|
41
32
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
33
|
+
function getJsxAttrName(name) {
|
|
34
|
+
if (typescript_1.default.isIdentifier(name))
|
|
35
|
+
return name.text;
|
|
36
|
+
if (typescript_1.default.isJsxNamespacedName(name))
|
|
37
|
+
return name.name.text;
|
|
38
|
+
return "";
|
|
39
|
+
}
|
|
40
|
+
// MAIN
|
|
41
|
+
function scanSource(source, checker, config, visited = new Set(), inheritedParamMap, wrapperCache = new Map()) {
|
|
42
|
+
const events = new Set();
|
|
43
|
+
const detectedFunctionWrappers = new Set();
|
|
44
|
+
const detectedComponentWrappers = new Map();
|
|
45
|
+
if (visited.has(source.fileName)) {
|
|
46
|
+
return { events, detectedFunctionWrappers, detectedComponentWrappers };
|
|
47
|
+
}
|
|
48
|
+
visited.add(source.fileName);
|
|
49
|
+
// TRACK DETECTION
|
|
50
|
+
function isTrackCall(expr) {
|
|
51
|
+
if (typescript_1.default.isIdentifier(expr)) {
|
|
52
|
+
return expr.text === "track";
|
|
55
53
|
}
|
|
54
|
+
if (typescript_1.default.isPropertyAccessExpression(expr)) {
|
|
55
|
+
return expr.name.text === "track";
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
56
58
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
function extractTrackCall(node, paramMap) {
|
|
60
|
+
if (!isTrackCall(node.expression))
|
|
61
|
+
return;
|
|
62
|
+
const arg = node.arguments[0];
|
|
63
|
+
if (!arg)
|
|
64
|
+
return;
|
|
65
|
+
const res = (0, resolver_1.resolveNodeValue)(arg, checker, paramMap);
|
|
66
|
+
for (const v of res.values) {
|
|
67
|
+
if (isValidEvent(v)) {
|
|
68
|
+
events.add(v);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
60
71
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
// WRAPPER DETECTION
|
|
73
|
+
function isWrapperFunction(fn) {
|
|
74
|
+
let found = false;
|
|
75
|
+
function walk(n) {
|
|
76
|
+
if (found)
|
|
77
|
+
return;
|
|
78
|
+
if (typescript_1.default.isCallExpression(n) && isTrackCall(n.expression)) {
|
|
79
|
+
found = true;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
typescript_1.default.forEachChild(n, walk);
|
|
83
|
+
}
|
|
84
|
+
if (fn.body)
|
|
85
|
+
walk(fn.body);
|
|
86
|
+
return found;
|
|
87
|
+
}
|
|
88
|
+
// COMPONENT WRAPPER
|
|
89
|
+
function detectComponentWrapper(tag) {
|
|
90
|
+
const tagName = getJsxTagName(tag);
|
|
91
|
+
if (wrapperCache.has(tagName)) {
|
|
92
|
+
return wrapperCache.get(tagName);
|
|
93
|
+
}
|
|
94
|
+
let symbol = checker.getSymbolAtLocation(tag);
|
|
95
|
+
if (symbol && (symbol.flags & typescript_1.default.SymbolFlags.Alias)) {
|
|
96
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
97
|
+
}
|
|
98
|
+
if (!symbol) {
|
|
99
|
+
wrapperCache.set(tagName, null);
|
|
72
100
|
return null;
|
|
101
|
+
}
|
|
102
|
+
symbol = (0, exportResolver_1.resolveExportedSymbol)(symbol, checker) ?? symbol;
|
|
73
103
|
for (const decl of symbol.getDeclarations() ?? []) {
|
|
74
|
-
|
|
104
|
+
let fn = null;
|
|
105
|
+
if (typescript_1.default.isFunctionDeclaration(decl))
|
|
106
|
+
fn = decl;
|
|
75
107
|
if (typescript_1.default.isVariableDeclaration(decl) &&
|
|
76
108
|
decl.initializer &&
|
|
77
|
-
typescript_1.default.
|
|
78
|
-
|
|
109
|
+
(typescript_1.default.isArrowFunction(decl.initializer) ||
|
|
110
|
+
typescript_1.default.isFunctionExpression(decl.initializer))) {
|
|
111
|
+
fn = decl.initializer;
|
|
79
112
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
function visit(node) {
|
|
92
|
-
if (result)
|
|
93
|
-
return;
|
|
94
|
-
if (typescript_1.default.isCallExpression(node)) {
|
|
95
|
-
const expr = node.expression;
|
|
96
|
-
const isTrack = (typescript_1.default.isIdentifier(expr) && expr.text === "track") ||
|
|
97
|
-
(typescript_1.default.isPropertyAccessExpression(expr) &&
|
|
98
|
-
expr.name.text === "track");
|
|
99
|
-
if (!isTrack) {
|
|
100
|
-
typescript_1.default.forEachChild(node, visit);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
for (const arg of node.arguments) {
|
|
104
|
-
// track(event)
|
|
105
|
-
if (typescript_1.default.isIdentifier(arg)) {
|
|
106
|
-
const prop = resolveIdentifierToProp(arg);
|
|
107
|
-
if (prop) {
|
|
108
|
-
result = prop;
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
// track(props.a.b.event)
|
|
113
|
-
if (typescript_1.default.isPropertyAccessExpression(arg)) {
|
|
114
|
-
let current = arg;
|
|
115
|
-
while (typescript_1.default.isPropertyAccessExpression(current)) {
|
|
116
|
-
result = current.name.text;
|
|
113
|
+
if (!fn || !fn.body)
|
|
114
|
+
continue;
|
|
115
|
+
let prop = null;
|
|
116
|
+
function walk(n) {
|
|
117
|
+
if (prop)
|
|
118
|
+
return;
|
|
119
|
+
if (typescript_1.default.isCallExpression(n) && isTrackCall(n.expression)) {
|
|
120
|
+
const arg = n.arguments[0];
|
|
121
|
+
if (typescript_1.default.isPropertyAccessExpression(arg)) {
|
|
122
|
+
prop = arg.name.text;
|
|
117
123
|
return;
|
|
118
124
|
}
|
|
119
125
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
}
|
|
126
|
+
typescript_1.default.forEachChild(n, walk);
|
|
127
|
+
}
|
|
128
|
+
walk(fn.body);
|
|
129
|
+
wrapperCache.set(tagName, prop);
|
|
130
|
+
if (prop) {
|
|
131
|
+
detectedComponentWrappers.set(tagName, prop);
|
|
132
|
+
return prop;
|
|
129
133
|
}
|
|
130
134
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (fn.body)
|
|
134
|
-
visit(fn.body);
|
|
135
|
-
return result;
|
|
136
|
-
}
|
|
137
|
-
// MAIN SCANNER
|
|
138
|
-
function scanSource(source, checker, config, visited = new Set(), inheritedParamMap, wrapperCache = new Map()) {
|
|
139
|
-
const events = new Set();
|
|
140
|
-
const detectedFunctionWrappers = new Set();
|
|
141
|
-
const detectedComponentWrappers = new Map();
|
|
142
|
-
if (visited.has(source.fileName) || visited.size > 200) {
|
|
143
|
-
return { events, detectedFunctionWrappers, detectedComponentWrappers };
|
|
135
|
+
wrapperCache.set(tagName, null);
|
|
136
|
+
return null;
|
|
144
137
|
}
|
|
145
|
-
|
|
138
|
+
// VISITOR
|
|
146
139
|
function visit(node) {
|
|
147
|
-
// JSX
|
|
140
|
+
// JSX
|
|
148
141
|
if (typescript_1.default.isJsxSelfClosingElement(node) || typescript_1.default.isJsxOpeningElement(node)) {
|
|
149
142
|
const tagName = getJsxTagName(node.tagName);
|
|
150
|
-
// skip html
|
|
151
143
|
if (tagName[0] === tagName[0].toLowerCase()) {
|
|
152
144
|
typescript_1.default.forEachChild(node, visit);
|
|
153
145
|
return;
|
|
154
146
|
}
|
|
155
147
|
let wrapper = config.wrappers.find(w => w.name === tagName);
|
|
156
|
-
// AUTO DETECT
|
|
157
148
|
if (!wrapper) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
wrapper = { name: tagName, prop: cached };
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
let symbol = checker.getSymbolAtLocation(node.tagName);
|
|
165
|
-
if (symbol && (symbol.flags & typescript_1.default.SymbolFlags.Alias)) {
|
|
166
|
-
symbol = checker.getAliasedSymbol(symbol);
|
|
167
|
-
}
|
|
168
|
-
if (symbol) {
|
|
169
|
-
symbol = (0, exportResolver_1.resolveExportedSymbol)(symbol, checker) ?? symbol;
|
|
170
|
-
for (const decl of symbol.getDeclarations() ?? []) {
|
|
171
|
-
let fn = null;
|
|
172
|
-
if (typescript_1.default.isFunctionDeclaration(decl))
|
|
173
|
-
fn = decl;
|
|
174
|
-
if (typescript_1.default.isVariableDeclaration(decl) &&
|
|
175
|
-
decl.initializer &&
|
|
176
|
-
(typescript_1.default.isArrowFunction(decl.initializer) ||
|
|
177
|
-
typescript_1.default.isFunctionExpression(decl.initializer))) {
|
|
178
|
-
fn = decl.initializer;
|
|
179
|
-
}
|
|
180
|
-
if (!fn)
|
|
181
|
-
continue;
|
|
182
|
-
const prop = findTrackedPropName(fn, checker);
|
|
183
|
-
wrapperCache.set(tagName, prop ?? null);
|
|
184
|
-
if (prop) {
|
|
185
|
-
wrapper = { name: tagName, prop };
|
|
186
|
-
detectedComponentWrappers.set(tagName, prop);
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
149
|
+
const prop = detectComponentWrapper(node.tagName);
|
|
150
|
+
if (prop)
|
|
151
|
+
wrapper = { name: tagName, prop };
|
|
192
152
|
}
|
|
193
153
|
if (wrapper) {
|
|
194
154
|
for (const attr of node.attributes.properties) {
|
|
@@ -200,15 +160,15 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
|
|
|
200
160
|
if (!attr.initializer)
|
|
201
161
|
continue;
|
|
202
162
|
if (typescript_1.default.isStringLiteral(attr.initializer)) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
163
|
+
if (isValidEvent(attr.initializer.text)) {
|
|
164
|
+
events.add(attr.initializer.text);
|
|
165
|
+
}
|
|
206
166
|
}
|
|
207
167
|
if (typescript_1.default.isJsxExpression(attr.initializer)) {
|
|
208
168
|
const expr = attr.initializer.expression;
|
|
209
169
|
if (!expr)
|
|
210
170
|
continue;
|
|
211
|
-
const res = (0, resolver_1.resolveNodeValue)(expr, checker
|
|
171
|
+
const res = (0, resolver_1.resolveNodeValue)(expr, checker);
|
|
212
172
|
res.values.forEach(v => {
|
|
213
173
|
if (isValidEvent(v))
|
|
214
174
|
events.add(v);
|
|
@@ -219,65 +179,40 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
|
|
|
219
179
|
typescript_1.default.forEachChild(node, visit);
|
|
220
180
|
return;
|
|
221
181
|
}
|
|
222
|
-
//
|
|
182
|
+
// CALL
|
|
223
183
|
if (typescript_1.default.isCallExpression(node)) {
|
|
224
|
-
let trackParamIndex = null;
|
|
225
|
-
let isTracking = false;
|
|
226
|
-
const callName = getCallName(node.expression);
|
|
227
|
-
// direct .track()
|
|
228
|
-
if (typescript_1.default.isPropertyAccessExpression(node.expression) &&
|
|
229
|
-
node.expression.name.text === "track") {
|
|
230
|
-
isTracking = true;
|
|
231
|
-
trackParamIndex = 0;
|
|
232
|
-
}
|
|
233
|
-
// config wrapper
|
|
234
|
-
const manualWrapper = config.functionWrappers.find(w => w.name === callName);
|
|
235
|
-
if (manualWrapper) {
|
|
236
|
-
isTracking = true;
|
|
237
|
-
trackParamIndex = 0;
|
|
238
|
-
}
|
|
239
|
-
// resolve function → check body
|
|
240
184
|
const resolvedFn = (0, callResolver_1.resolveFunctionFromCall)(node.expression, checker);
|
|
241
|
-
if (resolvedFn) {
|
|
242
|
-
const idx = (0, functionAnalyzer_1.findTrackParamIndex)(resolvedFn);
|
|
243
|
-
if (idx !== null) {
|
|
244
|
-
isTracking = true;
|
|
245
|
-
trackParamIndex = idx;
|
|
246
|
-
if (!manualWrapper && callName !== "track") {
|
|
247
|
-
detectedFunctionWrappers.add(callName);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
if (!isTracking) {
|
|
252
|
-
typescript_1.default.forEachChild(node, visit);
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
185
|
const paramMap = new Map(inheritedParamMap ?? []);
|
|
256
|
-
if (resolvedFn
|
|
257
|
-
resolvedFn.parameters.forEach((
|
|
186
|
+
if (resolvedFn) {
|
|
187
|
+
resolvedFn.parameters.forEach((p, i) => {
|
|
258
188
|
const arg = node.arguments[i];
|
|
259
189
|
if (!arg)
|
|
260
190
|
return;
|
|
261
|
-
if (typescript_1.default.isIdentifier(
|
|
262
|
-
paramMap.set(
|
|
191
|
+
if (typescript_1.default.isIdentifier(p.name)) {
|
|
192
|
+
paramMap.set(p.name.text, arg);
|
|
263
193
|
}
|
|
264
194
|
});
|
|
265
195
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
196
|
+
extractTrackCall(node, paramMap);
|
|
197
|
+
if (resolvedFn && isWrapperFunction(resolvedFn)) {
|
|
198
|
+
const name = getCallName(node.expression);
|
|
199
|
+
if (name && name !== "track") {
|
|
200
|
+
detectedFunctionWrappers.add(name);
|
|
201
|
+
}
|
|
202
|
+
if (resolvedFn.body) {
|
|
203
|
+
visit(resolvedFn.body);
|
|
204
|
+
}
|
|
272
205
|
}
|
|
273
|
-
|
|
274
|
-
if (resolvedFn) {
|
|
206
|
+
if (resolvedFn && resolvedFn.body) {
|
|
275
207
|
const sf = resolvedFn.getSourceFile();
|
|
276
208
|
if (!visited.has(sf.fileName)) {
|
|
277
209
|
const res = scanSource(sf, checker, config, visited, paramMap, wrapperCache);
|
|
278
210
|
res.events.forEach(e => events.add(e));
|
|
279
211
|
}
|
|
280
212
|
}
|
|
213
|
+
node.arguments.forEach(visit);
|
|
214
|
+
visit(node.expression);
|
|
215
|
+
return;
|
|
281
216
|
}
|
|
282
217
|
typescript_1.default.forEachChild(node, visit);
|
|
283
218
|
}
|
package/dist/utils/universal.js
CHANGED
package/package.json
CHANGED
package/src/commands/check.ts
CHANGED
|
@@ -25,28 +25,20 @@ export async function check({ fix = false }: { fix?: boolean }) {
|
|
|
25
25
|
|
|
26
26
|
const engine = new EventraEngine(process.cwd());
|
|
27
27
|
|
|
28
|
+
const cache = new Map<string, { content: string; deps: string[] }>();
|
|
28
29
|
const toScan = new Set<string>();
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
string,
|
|
32
|
-
{ content: string; deps: string[] }
|
|
33
|
-
>();
|
|
34
|
-
|
|
35
|
-
// COLLECT + CACHE
|
|
31
|
+
// COLLECT
|
|
36
32
|
for (const file of files) {
|
|
37
33
|
try {
|
|
38
34
|
const raw = await fs.readFile(file, "utf-8");
|
|
39
|
-
|
|
40
35
|
if (raw.length > 2_000_000) continue;
|
|
41
36
|
|
|
42
37
|
const parsed = processFile(file, raw);
|
|
43
38
|
|
|
44
39
|
cache.set(file, parsed);
|
|
45
40
|
toScan.add(file);
|
|
46
|
-
|
|
47
|
-
for (const dep of parsed.deps) {
|
|
48
|
-
toScan.add(path.resolve(dep));
|
|
49
|
-
}
|
|
41
|
+
parsed.deps.forEach(dep => toScan.add(path.resolve(dep)));
|
|
50
42
|
|
|
51
43
|
} catch {}
|
|
52
44
|
}
|
|
@@ -54,17 +46,9 @@ export async function check({ fix = false }: { fix?: boolean }) {
|
|
|
54
46
|
// PRELOAD
|
|
55
47
|
for (const file of toScan) {
|
|
56
48
|
try {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const raw = await fs.readFile(file, "utf-8");
|
|
61
|
-
parsed = processFile(file, raw);
|
|
62
|
-
cache.set(file, parsed);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const virtual = getVirtualFile(file);
|
|
66
|
-
engine.preloadFile(virtual, parsed.content);
|
|
67
|
-
|
|
49
|
+
const parsed = cache.get(file);
|
|
50
|
+
if (!parsed) continue;
|
|
51
|
+
engine.preloadFile(getVirtualFile(file), parsed.content);
|
|
68
52
|
} catch {}
|
|
69
53
|
}
|
|
70
54
|
|
|
@@ -74,49 +58,34 @@ export async function check({ fix = false }: { fix?: boolean }) {
|
|
|
74
58
|
const parsed = cache.get(file);
|
|
75
59
|
if (!parsed) continue;
|
|
76
60
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
engine.scanFile(
|
|
62
|
+
getVirtualFile(file),
|
|
63
|
+
parsed.content,
|
|
64
|
+
config
|
|
65
|
+
);
|
|
80
66
|
|
|
81
67
|
} catch {}
|
|
82
68
|
}
|
|
83
69
|
|
|
84
|
-
// DIFF
|
|
85
70
|
const found = new Set(engine.getAllEvents());
|
|
86
71
|
const known = new Set(config.events ?? []);
|
|
87
72
|
|
|
88
|
-
const
|
|
73
|
+
const added = [...found].filter(e => !known.has(e));
|
|
89
74
|
const removed = [...known].filter(e => !found.has(e));
|
|
90
75
|
|
|
91
|
-
// FIX MODE
|
|
92
76
|
if (fix) {
|
|
93
77
|
config.events = [...found].sort();
|
|
94
78
|
await saveConfig(config);
|
|
95
|
-
|
|
96
|
-
console.log(
|
|
97
|
-
chalk.green(`\nSynced (${config.events.length} events)`)
|
|
98
|
-
);
|
|
79
|
+
console.log(chalk.green("Synced"));
|
|
99
80
|
return;
|
|
100
81
|
}
|
|
101
82
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
console.log(chalk.red("\nNew events:"));
|
|
106
|
-
newEvents.forEach(e =>
|
|
107
|
-
console.log(chalk.red(`+ ${e}`))
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (removed.length) {
|
|
112
|
-
console.log(chalk.yellow("\nRemoved events:"));
|
|
113
|
-
removed.forEach(e =>
|
|
114
|
-
console.log(chalk.yellow(`- ${e}`))
|
|
115
|
-
);
|
|
116
|
-
}
|
|
83
|
+
if (added.length || removed.length) {
|
|
84
|
+
added.forEach(e => console.log(chalk.red(`+ ${e}`)));
|
|
85
|
+
removed.forEach(e => console.log(chalk.yellow(`- ${e}`)));
|
|
117
86
|
|
|
118
87
|
process.exit(1);
|
|
119
88
|
}
|
|
120
89
|
|
|
121
|
-
console.log(chalk.green("
|
|
90
|
+
console.log(chalk.green("All good"));
|
|
122
91
|
}
|
package/src/commands/sync.ts
CHANGED
|
@@ -19,25 +19,15 @@ export async function sync() {
|
|
|
19
19
|
absolute: true,
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
if (!files.length) {
|
|
23
|
-
console.log(chalk.yellow("No files found"));
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
22
|
const engine = new EventraEngine(process.cwd());
|
|
28
23
|
|
|
24
|
+
const cache = new Map<string, { content: string; deps: string[] }>();
|
|
29
25
|
const toScan = new Set<string>();
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
string,
|
|
33
|
-
{ content: string; deps: string[] }
|
|
34
|
-
>();
|
|
35
|
-
|
|
36
|
-
// COLLECT + CACHE
|
|
27
|
+
// COLLECT
|
|
37
28
|
for (const file of files) {
|
|
38
29
|
try {
|
|
39
30
|
const raw = await fs.readFile(file, "utf-8");
|
|
40
|
-
|
|
41
31
|
if (raw.length > 2_000_000) continue;
|
|
42
32
|
|
|
43
33
|
const parsed = processFile(file, raw);
|
|
@@ -45,9 +35,7 @@ export async function sync() {
|
|
|
45
35
|
cache.set(file, parsed);
|
|
46
36
|
toScan.add(file);
|
|
47
37
|
|
|
48
|
-
|
|
49
|
-
toScan.add(path.resolve(dep));
|
|
50
|
-
}
|
|
38
|
+
parsed.deps.forEach(dep => toScan.add(path.resolve(dep)));
|
|
51
39
|
|
|
52
40
|
} catch {}
|
|
53
41
|
}
|
|
@@ -63,8 +51,7 @@ export async function sync() {
|
|
|
63
51
|
cache.set(file, parsed);
|
|
64
52
|
}
|
|
65
53
|
|
|
66
|
-
|
|
67
|
-
engine.preloadFile(virtual, parsed.content);
|
|
54
|
+
engine.preloadFile(getVirtualFile(file), parsed.content);
|
|
68
55
|
|
|
69
56
|
} catch {}
|
|
70
57
|
}
|
|
@@ -78,21 +65,16 @@ export async function sync() {
|
|
|
78
65
|
const parsed = cache.get(file);
|
|
79
66
|
if (!parsed) continue;
|
|
80
67
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
res.detectedFunctionWrappers.forEach(w =>
|
|
86
|
-
detectedFn.add(w)
|
|
68
|
+
const res = engine.updateFile(
|
|
69
|
+
getVirtualFile(file),
|
|
70
|
+
parsed.content,
|
|
71
|
+
config
|
|
87
72
|
);
|
|
88
73
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
74
|
+
res.detectedFunctionWrappers.forEach(w => detectedFn.add(w));
|
|
75
|
+
res.detectedComponentWrappers.forEach((v, k) => detectedCmp.set(k, v));
|
|
92
76
|
|
|
93
|
-
} catch {
|
|
94
|
-
console.log(chalk.gray(`skip: ${file}`));
|
|
95
|
-
}
|
|
77
|
+
} catch {}
|
|
96
78
|
}
|
|
97
79
|
|
|
98
80
|
// RESULT
|
|
@@ -108,10 +90,7 @@ export async function sync() {
|
|
|
108
90
|
|
|
109
91
|
config.wrappers = mergeUnique(
|
|
110
92
|
config.wrappers ?? [],
|
|
111
|
-
[...detectedCmp.entries()].map(([name, prop]) => ({
|
|
112
|
-
name,
|
|
113
|
-
prop,
|
|
114
|
-
})),
|
|
93
|
+
[...detectedCmp.entries()].map(([name, prop]) => ({ name, prop })),
|
|
115
94
|
w => `${w.name}:${w.prop}`
|
|
116
95
|
);
|
|
117
96
|
|
|
@@ -120,17 +99,8 @@ export async function sync() {
|
|
|
120
99
|
console.log(chalk.green(`Found ${events.length} events`));
|
|
121
100
|
}
|
|
122
101
|
|
|
123
|
-
|
|
124
|
-
function mergeUnique<T>(
|
|
125
|
-
a: T[],
|
|
126
|
-
b: T[],
|
|
127
|
-
key: (v: T) => string
|
|
128
|
-
): T[] {
|
|
102
|
+
function mergeUnique<T>(a: T[], b: T[], key: (v: T) => string): T[] {
|
|
129
103
|
const map = new Map<string, T>();
|
|
130
|
-
|
|
131
|
-
[...b, ...a].forEach(item => {
|
|
132
|
-
map.set(key(item), item);
|
|
133
|
-
});
|
|
134
|
-
|
|
104
|
+
[...b, ...a].forEach(item => map.set(key(item), item));
|
|
135
105
|
return [...map.values()];
|
|
136
106
|
}
|