@eventra_dev/eventra-cli 0.0.19 → 0.1.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.
Files changed (45) hide show
  1. package/dist/commands/check.js +17 -117
  2. package/dist/commands/sync.js +20 -115
  3. package/dist/commands/watch.js +107 -69
  4. package/dist/engine/callResolver.js +31 -0
  5. package/dist/engine/engine.js +33 -0
  6. package/dist/engine/extract.js +53 -0
  7. package/dist/engine/flow.js +38 -0
  8. package/dist/engine/graph.js +22 -0
  9. package/dist/engine/project.js +74 -0
  10. package/dist/engine/resolver.js +38 -0
  11. package/dist/engine/scanner.js +78 -0
  12. package/dist/engine/symbol.js +31 -0
  13. package/dist/utils/parsers/vue.js +16 -12
  14. package/dist/utils/processFile.js +20 -0
  15. package/package.json +1 -1
  16. package/src/commands/check.ts +19 -151
  17. package/src/commands/sync.ts +23 -194
  18. package/src/commands/watch.ts +119 -66
  19. package/src/engine/callResolver.ts +37 -0
  20. package/src/engine/engine.ts +39 -0
  21. package/src/engine/extract.ts +74 -0
  22. package/src/engine/flow.ts +54 -0
  23. package/src/engine/graph.ts +23 -0
  24. package/src/engine/project.ts +75 -0
  25. package/src/engine/resolver.ts +53 -0
  26. package/src/engine/scanner.ts +90 -0
  27. package/src/engine/symbol.ts +42 -0
  28. package/src/types.ts +3 -9
  29. package/src/utils/parsers/vue.ts +19 -20
  30. package/src/utils/processFile.ts +18 -0
  31. package/tests/fixtures/backend/express/app.ts +167 -12
  32. package/tests/fixtures/wrappers/component/test.tsx +1 -1
  33. package/tests/run.ts +4 -17
  34. package/dist/utils/detect-aliases.js +0 -39
  35. package/dist/utils/detect-wrappers.js +0 -84
  36. package/dist/utils/extract.js +0 -56
  37. package/dist/utils/scanners/component-wrappers.js +0 -73
  38. package/dist/utils/scanners/function-wrappers.js +0 -83
  39. package/dist/utils/scanners/track.js +0 -64
  40. package/src/utils/detect-aliases.ts +0 -46
  41. package/src/utils/detect-wrappers.ts +0 -119
  42. package/src/utils/extract.ts +0 -72
  43. package/src/utils/scanners/component-wrappers.ts +0 -109
  44. package/src/utils/scanners/function-wrappers.ts +0 -137
  45. package/src/utils/scanners/track.ts +0 -99
@@ -1,109 +0,0 @@
1
- import {
2
- SourceFile,
3
- SyntaxKind,
4
- Node
5
- } from "ts-morph";
6
-
7
- import {
8
- ComponentWrapper,
9
- ExtractedEvent
10
- } from "../../types";
11
-
12
- import { extractExpression } from "../extract";
13
-
14
- export function scanComponentWrappers(
15
- source: SourceFile,
16
- wrappers: ComponentWrapper[],
17
- aliases: Record<string, string>
18
- ) {
19
- const events = new Map<string, ExtractedEvent>();
20
-
21
- const elements = [
22
- ...source.getDescendantsOfKind(
23
- SyntaxKind.JsxOpeningElement
24
- ),
25
- ...source.getDescendantsOfKind(
26
- SyntaxKind.JsxSelfClosingElement
27
- )
28
- ];
29
-
30
- for (const el of elements) {
31
- const name = el
32
- .getTagNameNode()
33
- .getText()
34
- .toLowerCase();
35
-
36
- for (const wrapper of wrappers) {
37
- if (name !== wrapper.name.toLowerCase())
38
- continue;
39
-
40
- for (const attr of el.getAttributes()) {
41
-
42
- if (Node.isJsxSpreadAttribute(attr))
43
- continue;
44
-
45
- const attrNode =
46
- attr.asKind(SyntaxKind.JsxAttribute);
47
-
48
- if (!attrNode) continue;
49
-
50
- const key =
51
- attrNode
52
- .getNameNode()
53
- .getText()
54
- .toLowerCase();
55
-
56
- if (key !== wrapper.prop.toLowerCase())
57
- continue;
58
-
59
- const init = attrNode.getInitializer();
60
-
61
- // <Button event />
62
- if (!init) {
63
- const value = key;
64
- const k = `${value}:true`;
65
-
66
- events.set(k, {
67
- value,
68
- dynamic: true
69
- });
70
-
71
- continue;
72
- }
73
-
74
- // <Button event="click" />
75
- if (Node.isStringLiteral(init)) {
76
- const value = init.getLiteralText();
77
- const k = `${value}:false`;
78
-
79
- events.set(k, {
80
- value,
81
- dynamic: false
82
- });
83
-
84
- continue;
85
- }
86
-
87
- // <Button event={...} />
88
- if (Node.isJsxExpression(init)) {
89
- const expr = init.getExpression();
90
- if (!expr) continue;
91
-
92
- const result = extractExpression(expr, aliases);
93
- if (!result) continue;
94
-
95
- for (const value of result.values) {
96
- const k = `${value}:${result.dynamic}`;
97
-
98
- events.set(k, {
99
- value,
100
- dynamic: result.dynamic
101
- });
102
- }
103
- }
104
- }
105
- }
106
- }
107
-
108
- return [...events.values()];
109
- }
@@ -1,137 +0,0 @@
1
- import {
2
- SourceFile,
3
- SyntaxKind,
4
- Node,
5
- CallExpression,
6
- PropertyAccessExpression,
7
- } from "ts-morph";
8
-
9
- import {
10
- FunctionWrapper,
11
- ExtractedEvent
12
- } from "../../types";
13
-
14
- import { extractExpression } from "../extract";
15
-
16
- export function scanFunctionWrappers(
17
- source: SourceFile,
18
- wrappers: FunctionWrapper[],
19
- aliases: Record<string, string>
20
- ) {
21
- const events = new Map<string, ExtractedEvent>();
22
-
23
- const calls =
24
- source.getDescendantsOfKind(
25
- SyntaxKind.CallExpression
26
- );
27
-
28
- for (const call of calls) {
29
- const name = getFunctionName(call);
30
- if (!name) continue;
31
-
32
- for (const wrapper of wrappers) {
33
- if (wrapper.name !== name) continue;
34
-
35
- const results = extractEventFromArgs(
36
- call,
37
- wrapper.event,
38
- aliases
39
- );
40
-
41
- if (!results) continue;
42
-
43
- for (const r of results) {
44
- const key = `${r.value}:${r.dynamic}`;
45
- events.set(key, r);
46
- }
47
- }
48
- }
49
-
50
- return [...events.values()];
51
- }
52
-
53
- function getFunctionName(
54
- call: CallExpression
55
- ): string | null {
56
-
57
- const expression = call.getExpression();
58
-
59
- if (Node.isIdentifier(expression)) {
60
- return expression.getText();
61
- }
62
-
63
- if (Node.isPropertyAccessExpression(expression)) {
64
- return getDeepName(expression);
65
- }
66
-
67
- return null;
68
- }
69
-
70
- function getDeepName(
71
- node: PropertyAccessExpression
72
- ): string {
73
-
74
- let current: Node | undefined = node;
75
- let name = "";
76
-
77
- while (Node.isPropertyAccessExpression(current)) {
78
- name = current.getName();
79
- current = current.getExpression();
80
- }
81
-
82
- return name;
83
- }
84
-
85
- function extractEventFromArgs(
86
- call: CallExpression,
87
- event: string | undefined,
88
- aliases: Record<string, string>
89
- ): ExtractedEvent[] | null {
90
-
91
- const args = call.getArguments();
92
- const events: ExtractedEvent[] = [];
93
-
94
- for (const arg of args) {
95
-
96
- // track("event")
97
- if (!event) {
98
- const result = extractExpression(arg, aliases);
99
- if (!result) continue;
100
-
101
- result.values.forEach((value) =>
102
- events.push({
103
- value,
104
- dynamic: result.dynamic
105
- })
106
- );
107
- }
108
-
109
- // track({ event })
110
- if (event) {
111
- const obj = arg.asKind(
112
- SyntaxKind.ObjectLiteralExpression
113
- );
114
- if (!obj) continue;
115
-
116
- const prop = obj.getProperty(event);
117
- if (!prop) continue;
118
-
119
- if (Node.isPropertyAssignment(prop)) {
120
- const init = prop.getInitializer();
121
- if (!init) continue;
122
-
123
- const result = extractExpression(init, aliases);
124
- if (!result) continue;
125
-
126
- result.values.forEach((value) =>
127
- events.push({
128
- value,
129
- dynamic: result.dynamic
130
- })
131
- );
132
- }
133
- }
134
- }
135
-
136
- return events.length ? events : null;
137
- }
@@ -1,99 +0,0 @@
1
- import {
2
- SourceFile,
3
- SyntaxKind,
4
- Node,
5
- } from "ts-morph";
6
-
7
- import path from "path";
8
-
9
- import { ExtractedEvent, EventraConfig } from "../../types";
10
- import { extractExpression } from "../extract";
11
-
12
- export function scanTrack(
13
- source: SourceFile,
14
- config: EventraConfig,
15
- aliases: Record<string, string>
16
- ) {
17
- const events = new Map<string, ExtractedEvent>();
18
-
19
- const calls = source.getDescendantsOfKind(
20
- SyntaxKind.CallExpression
21
- );
22
-
23
- for (const call of calls) {
24
- const expr = call.getExpression();
25
-
26
- let isTrack = false;
27
-
28
- // track()
29
- if (Node.isIdentifier(expr)) {
30
- isTrack = expr.getText() === "track";
31
- }
32
-
33
- // analytics.track()
34
- if (Node.isPropertyAccessExpression(expr)) {
35
- isTrack = expr.getName() === "track";
36
- }
37
-
38
- if (!isTrack) continue;
39
-
40
- // ❗ skip wrapper functions
41
- const func =
42
- call.getFirstAncestorByKind(SyntaxKind.FunctionDeclaration) ||
43
- call.getFirstAncestorByKind(SyntaxKind.ArrowFunction) ||
44
- call.getFirstAncestorByKind(SyntaxKind.FunctionExpression);
45
-
46
- let fnName: string | undefined;
47
-
48
- if (func) {
49
- if (Node.isFunctionDeclaration(func)) {
50
- fnName = func.getName();
51
- }
52
-
53
- if (
54
- Node.isArrowFunction(func) ||
55
- Node.isFunctionExpression(func)
56
- ) {
57
- const varDecl = func.getFirstAncestorByKind(
58
- SyntaxKind.VariableDeclaration
59
- );
60
- fnName = varDecl?.getName();
61
- }
62
- }
63
-
64
- if (
65
- fnName &&
66
- config.functionWrappers?.some(
67
- (w) => w.name === fnName
68
- )
69
- ) {
70
- continue;
71
- }
72
-
73
- const arg = call.getArguments()[0];
74
- if (!arg) continue;
75
-
76
- const result = extractExpression(arg, aliases);
77
- if (!result) continue;
78
-
79
- const line = call.getStartLineNumber();
80
-
81
- const file = path.relative(
82
- process.cwd(),
83
- source.getFilePath()
84
- );
85
-
86
- for (const value of result.values) {
87
- const key = `${value}:${file}:${line}`;
88
-
89
- events.set(key, {
90
- value,
91
- dynamic: result.dynamic,
92
- file,
93
- line
94
- });
95
- }
96
- }
97
-
98
- return [...events.values()];
99
- }