@eventra_dev/eventra-cli 0.1.34 → 0.2.2

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.
@@ -8,6 +8,7 @@ const typescript_1 = __importDefault(require("typescript"));
8
8
  const resolver_1 = require("./resolver");
9
9
  const callResolver_1 = require("./callResolver");
10
10
  const exportResolver_1 = require("./exportResolver");
11
+ // HELPERS
11
12
  function isValidEvent(v) {
12
13
  return (v &&
13
14
  v.length > 1 &&
@@ -36,6 +37,7 @@ function getJsxAttrName(name) {
36
37
  return name.name.text;
37
38
  return "";
38
39
  }
40
+ // MAIN
39
41
  function scanSource(source, checker, config, visited = new Set(), inheritedParamMap, wrapperCache = new Map()) {
40
42
  const events = new Set();
41
43
  const detectedFunctionWrappers = new Set();
@@ -44,30 +46,38 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
44
46
  return { events, detectedFunctionWrappers, detectedComponentWrappers };
45
47
  }
46
48
  visited.add(source.fileName);
49
+ // TRACK DETECTION
50
+ function isTrackCall(expr) {
51
+ if (typescript_1.default.isIdentifier(expr)) {
52
+ return expr.text === "track";
53
+ }
54
+ if (typescript_1.default.isPropertyAccessExpression(expr)) {
55
+ return expr.name.text === "track";
56
+ }
57
+ return false;
58
+ }
47
59
  function extractTrackCall(node, paramMap) {
48
- const expr = node.expression;
49
- if (typescript_1.default.isPropertyAccessExpression(expr) && expr.name.text === "track") {
50
- const arg = node.arguments[0];
51
- if (!arg)
52
- return;
53
- const res = (0, resolver_1.resolveNodeValue)(arg, checker, paramMap);
54
- for (const v of res.values) {
55
- if (isValidEvent(v))
56
- events.add(v);
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);
57
69
  }
58
70
  }
59
71
  }
72
+ // WRAPPER DETECTION
60
73
  function isWrapperFunction(fn) {
61
74
  let found = false;
62
75
  function walk(n) {
63
76
  if (found)
64
77
  return;
65
- if (typescript_1.default.isCallExpression(n)) {
66
- const expr = n.expression;
67
- if (typescript_1.default.isPropertyAccessExpression(expr) && expr.name.text === "track") {
68
- found = true;
69
- return;
70
- }
78
+ if (typescript_1.default.isCallExpression(n) && isTrackCall(n.expression)) {
79
+ found = true;
80
+ return;
71
81
  }
72
82
  typescript_1.default.forEachChild(n, walk);
73
83
  }
@@ -75,10 +85,12 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
75
85
  walk(fn.body);
76
86
  return found;
77
87
  }
88
+ // COMPONENT WRAPPER
78
89
  function detectComponentWrapper(tag) {
79
90
  const tagName = getJsxTagName(tag);
80
- if (wrapperCache.has(tagName))
91
+ if (wrapperCache.has(tagName)) {
81
92
  return wrapperCache.get(tagName);
93
+ }
82
94
  let symbol = checker.getSymbolAtLocation(tag);
83
95
  if (symbol && (symbol.flags & typescript_1.default.SymbolFlags.Alias)) {
84
96
  symbol = checker.getAliasedSymbol(symbol);
@@ -104,14 +116,11 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
104
116
  function walk(n) {
105
117
  if (prop)
106
118
  return;
107
- if (typescript_1.default.isCallExpression(n)) {
108
- const expr = n.expression;
109
- if (typescript_1.default.isPropertyAccessExpression(expr) && expr.name.text === "track") {
110
- const arg = n.arguments[0];
111
- if (typescript_1.default.isPropertyAccessExpression(arg)) {
112
- prop = arg.name.text;
113
- return;
114
- }
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;
123
+ return;
115
124
  }
116
125
  }
117
126
  typescript_1.default.forEachChild(n, walk);
@@ -126,6 +135,7 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
126
135
  wrapperCache.set(tagName, null);
127
136
  return null;
128
137
  }
138
+ // VISITOR
129
139
  function visit(node) {
130
140
  // JSX
131
141
  if (typescript_1.default.isJsxSelfClosingElement(node) || typescript_1.default.isJsxOpeningElement(node)) {
@@ -183,9 +193,7 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
183
193
  }
184
194
  });
185
195
  }
186
- // direct track
187
196
  extractTrackCall(node, paramMap);
188
- // wrapper
189
197
  if (resolvedFn && isWrapperFunction(resolvedFn)) {
190
198
  const name = getCallName(node.expression);
191
199
  if (name && name !== "track") {
@@ -195,9 +203,14 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
195
203
  visit(resolvedFn.body);
196
204
  }
197
205
  }
198
- for (const arg of node.arguments) {
199
- visit(arg);
206
+ if (resolvedFn && resolvedFn.body) {
207
+ const sf = resolvedFn.getSourceFile();
208
+ if (!visited.has(sf.fileName)) {
209
+ const res = scanSource(sf, checker, config, visited, paramMap, wrapperCache);
210
+ res.events.forEach(e => events.add(e));
211
+ }
200
212
  }
213
+ node.arguments.forEach(visit);
201
214
  visit(node.expression);
202
215
  return;
203
216
  }
@@ -1,8 +1,25 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.processFile = processFile;
7
+ const path_1 = __importDefault(require("path"));
4
8
  const universal_1 = require("./universal");
9
+ function extractImports(content, file) {
10
+ return (0, universal_1.parseUniversal)(content, file).deps;
11
+ }
5
12
  function processFile(file, content) {
13
+ const ext = path_1.default.extname(file);
14
+ if (ext === ".ts" ||
15
+ ext === ".tsx" ||
16
+ ext === ".js" ||
17
+ ext === ".jsx") {
18
+ return {
19
+ content,
20
+ deps: extractImports(content, file),
21
+ };
22
+ }
6
23
  const parsed = (0, universal_1.parseUniversal)(content, file);
7
24
  return {
8
25
  content: parsed.code || "",
@@ -184,7 +184,7 @@ function parseUniversal(content, file) {
184
184
  deps.push(...dyn.deps);
185
185
  parts.push(...dyn.calls);
186
186
  return {
187
- code: [...new Set(parts)].join("\n"),
187
+ code: parts.length ? parts.join("\n") : content,
188
188
  deps: [...new Set(deps.filter(Boolean))],
189
189
  };
190
190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventra_dev/eventra-cli",
3
- "version": "0.1.34",
3
+ "version": "0.2.2",
4
4
  "description": "Eventra CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -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
- const cache = new Map<
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
- let parsed = cache.get(file);
58
-
59
- if (!parsed) {
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
- const virtual = getVirtualFile(file);
78
-
79
- engine.scanFile(virtual, parsed.content, config);
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 newEvents = [...found].filter(e => !known.has(e));
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
- // CHECK MODE
103
- if (newEvents.length || removed.length) {
104
- if (newEvents.length) {
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("\nAll good"));
90
+ console.log(chalk.green("All good"));
122
91
  }
@@ -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
- const cache = new Map<
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
- for (const dep of parsed.deps) {
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
- const virtual = getVirtualFile(file);
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 virtual = getVirtualFile(file);
82
-
83
- const res = engine.scanFile(virtual, parsed.content, config);
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
- for (const [k, v] of res.detectedComponentWrappers) {
90
- detectedCmp.set(k, v);
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
- // HELPERS
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
  }