@eventra_dev/eventra-cli 0.0.12 → 0.0.14

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.
@@ -45,7 +45,7 @@ async function sync() {
45
45
  : file + ".tsx";
46
46
  const source = project.createSourceFile(virtualFile, content, { overwrite: true });
47
47
  const found = [
48
- ...(0, track_1.scanTrack)(source),
48
+ ...(0, track_1.scanTrack)(source, config),
49
49
  ...(0, function_wrappers_1.scanFunctionWrappers)(source, config.functionWrappers ?? []),
50
50
  ...(0, component_wrappers_1.scanComponentWrappers)(source, config.wrappers ?? [])
51
51
  ];
@@ -16,6 +16,7 @@ function normalizeConfig(config) {
16
16
  events: config.events ?? [],
17
17
  wrappers: config.wrappers ?? [],
18
18
  functionWrappers: config.functionWrappers ?? [],
19
+ aliases: config.aliases ?? {},
19
20
  sync: config.sync ?? {
20
21
  include: [
21
22
  "**/*.{ts,tsx,js,jsx,vue,svelte,astro}"
@@ -15,28 +15,92 @@ function extractExpression(expr) {
15
15
  ts_morph_1.SyntaxKind.NoSubstitutionTemplateLiteral) {
16
16
  return {
17
17
  values: [
18
- expr
19
- .getText()
20
- .replace(/`/g, "")
18
+ expr.getText().replace(/`/g, "")
21
19
  ],
22
20
  dynamic: false
23
21
  };
24
22
  }
25
- // identifier
23
+ // identifier (TEST)
26
24
  if (ts_morph_1.Node.isIdentifier(expr)) {
25
+ const name = expr.getText();
26
+ const defs = "getDefinitions" in expr
27
+ ? expr.getDefinitions()
28
+ : [];
29
+ if (defs && defs.length > 0) {
30
+ const decl = defs[0]?.getDeclarationNode();
31
+ if (decl && ts_morph_1.Node.isVariableDeclaration(decl)) {
32
+ const initializer = decl.getInitializer();
33
+ // const TEST = "event"
34
+ if (initializer &&
35
+ ts_morph_1.Node.isStringLiteral(initializer)) {
36
+ return {
37
+ values: [initializer.getLiteralText()],
38
+ dynamic: false
39
+ };
40
+ }
41
+ // const TEST = `event`
42
+ if (initializer &&
43
+ initializer.getKind() ===
44
+ ts_morph_1.SyntaxKind.NoSubstitutionTemplateLiteral) {
45
+ return {
46
+ values: [
47
+ initializer.getText().replace(/`/g, "")
48
+ ],
49
+ dynamic: false
50
+ };
51
+ }
52
+ }
53
+ }
27
54
  return {
28
- values: [expr.getText()],
55
+ values: [name],
29
56
  dynamic: true
30
57
  };
31
58
  }
32
- // property access (ROUTES.ACCOUNT)
59
+ // property access (EVENTS.CLICK)
33
60
  if (ts_morph_1.Node.isPropertyAccessExpression(expr)) {
61
+ const fullName = expr.getText(); // EVENTS.CLICK
62
+ const propName = expr.getName(); // CLICK
63
+ const defs = "getDefinitions" in expr
64
+ ? expr.getDefinitions()
65
+ : [];
66
+ if (defs && defs.length > 0) {
67
+ const decl = defs[0]?.getDeclarationNode();
68
+ // const EVENTS = { CLICK: "event" }
69
+ if (decl && ts_morph_1.Node.isVariableDeclaration(decl)) {
70
+ const init = decl.getInitializer();
71
+ if (init && ts_morph_1.Node.isObjectLiteralExpression(init)) {
72
+ const prop = init.getProperty(propName);
73
+ if (prop &&
74
+ ts_morph_1.Node.isPropertyAssignment(prop)) {
75
+ const value = prop.getInitializer();
76
+ if (value &&
77
+ ts_morph_1.Node.isStringLiteral(value)) {
78
+ return {
79
+ values: [value.getLiteralText()],
80
+ dynamic: false
81
+ };
82
+ }
83
+ }
84
+ }
85
+ }
86
+ // fallback
87
+ if (decl && ts_morph_1.Node.isPropertyAssignment(decl)) {
88
+ const initializer = decl.getInitializer();
89
+ if (initializer &&
90
+ ts_morph_1.Node.isStringLiteral(initializer)) {
91
+ return {
92
+ values: [initializer.getLiteralText()],
93
+ dynamic: false
94
+ };
95
+ }
96
+ }
97
+ }
34
98
  return {
35
- values: [expr.getText()],
99
+ values: [fullName],
36
100
  dynamic: true
37
101
  };
38
102
  }
39
- // ternary
103
+ // ternary (a ? b : c)
40
104
  if (ts_morph_1.Node.isConditionalExpression(expr)) {
41
105
  const values = [];
42
106
  const whenTrue = extractExpression(expr.getWhenTrue());
@@ -50,20 +114,20 @@ function extractExpression(expr) {
50
114
  dynamic: true
51
115
  };
52
116
  }
53
- // template
117
+ // template `${}`
54
118
  if (ts_morph_1.Node.isTemplateExpression(expr)) {
55
119
  return {
56
- values: [expr.getText()],
120
+ values: [
121
+ expr.getText().replace(/`/g, "")
122
+ ],
57
123
  dynamic: true
58
124
  };
59
125
  }
60
- // call
126
+ // call (fn())
61
127
  if (ts_morph_1.Node.isCallExpression(expr)) {
62
128
  return {
63
129
  values: [
64
- expr
65
- .getExpression()
66
- .getText()
130
+ expr.getExpression().getText()
67
131
  ],
68
132
  dynamic: true
69
133
  };
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.scanTrack = scanTrack;
4
4
  const ts_morph_1 = require("ts-morph");
5
5
  const extract_1 = require("../extract");
6
- function scanTrack(source) {
6
+ function scanTrack(source, config) {
7
7
  const events = new Set();
8
8
  const calls = source.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
9
9
  for (const call of calls) {
@@ -11,16 +11,32 @@ function scanTrack(source) {
11
11
  let isTrack = false;
12
12
  // track()
13
13
  if (ts_morph_1.Node.isIdentifier(expr)) {
14
- isTrack =
15
- expr.getText() === "track";
14
+ isTrack = expr.getText() === "track";
16
15
  }
17
16
  // analytics.track()
18
17
  if (ts_morph_1.Node.isPropertyAccessExpression(expr)) {
19
- isTrack =
20
- expr.getName() === "track";
18
+ isTrack = expr.getName() === "track";
21
19
  }
22
20
  if (!isTrack)
23
21
  continue;
22
+ const func = call.getFirstAncestorByKind(ts_morph_1.SyntaxKind.FunctionDeclaration) ||
23
+ call.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ArrowFunction) ||
24
+ call.getFirstAncestorByKind(ts_morph_1.SyntaxKind.FunctionExpression);
25
+ let fnName;
26
+ if (func) {
27
+ if (ts_morph_1.Node.isFunctionDeclaration(func)) {
28
+ fnName = func.getName();
29
+ }
30
+ if (ts_morph_1.Node.isArrowFunction(func) ||
31
+ ts_morph_1.Node.isFunctionExpression(func)) {
32
+ const varDecl = func.getFirstAncestorByKind(ts_morph_1.SyntaxKind.VariableDeclaration);
33
+ fnName = varDecl?.getName();
34
+ }
35
+ }
36
+ if (fnName &&
37
+ config.functionWrappers?.some((w) => w.name === fnName)) {
38
+ continue;
39
+ }
24
40
  const arg = call.getArguments()[0];
25
41
  if (!arg)
26
42
  continue;
@@ -29,7 +45,7 @@ function scanTrack(source) {
29
45
  continue;
30
46
  result.values.forEach((value) => events.add({
31
47
  value,
32
- dynamic: result.dynamic
48
+ dynamic: result.dynamic,
33
49
  }));
34
50
  }
35
51
  return events;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventra_dev/eventra-cli",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "description": "Eventra CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -81,7 +81,7 @@ export async function sync() {
81
81
  );
82
82
 
83
83
  const found: ExtractedEvent[] = [
84
- ...scanTrack(source),
84
+ ...scanTrack(source, config),
85
85
  ...scanFunctionWrappers(
86
86
  source,
87
87
  config.functionWrappers ?? []
@@ -13,6 +13,7 @@ export function normalizeConfig(
13
13
  wrappers: config.wrappers ?? [],
14
14
  functionWrappers:
15
15
  config.functionWrappers ?? [],
16
+ aliases: config.aliases ?? {},
16
17
  sync: config.sync ?? {
17
18
  include: [
18
19
  "**/*.{ts,tsx,js,jsx,vue,svelte,astro}"
@@ -27,59 +27,133 @@ export function extractExpression(
27
27
  ) {
28
28
  return {
29
29
  values: [
30
- expr
31
- .getText()
32
- .replace(/`/g, "")
30
+ expr.getText().replace(/`/g, "")
33
31
  ],
34
32
  dynamic: false
35
33
  };
36
34
  }
37
35
 
38
- // identifier
39
- if (
40
- Node.isIdentifier(expr)
41
- ) {
36
+ // identifier (TEST)
37
+ if (Node.isIdentifier(expr)) {
38
+ const name = expr.getText();
39
+
40
+ const defs =
41
+ "getDefinitions" in expr
42
+ ? (expr as any).getDefinitions()
43
+ : [];
44
+
45
+ if (defs && defs.length > 0) {
46
+ const decl = defs[0]?.getDeclarationNode();
47
+
48
+ if (decl && Node.isVariableDeclaration(decl)) {
49
+ const initializer = decl.getInitializer();
50
+
51
+ // const TEST = "event"
52
+ if (
53
+ initializer &&
54
+ Node.isStringLiteral(initializer)
55
+ ) {
56
+ return {
57
+ values: [initializer.getLiteralText()],
58
+ dynamic: false
59
+ };
60
+ }
61
+
62
+ // const TEST = `event`
63
+ if (
64
+ initializer &&
65
+ initializer.getKind() ===
66
+ SyntaxKind.NoSubstitutionTemplateLiteral
67
+ ) {
68
+ return {
69
+ values: [
70
+ initializer.getText().replace(/`/g, "")
71
+ ],
72
+ dynamic: false
73
+ };
74
+ }
75
+ }
76
+ }
77
+
42
78
  return {
43
- values: [expr.getText()],
79
+ values: [name],
44
80
  dynamic: true
45
81
  };
46
82
  }
47
83
 
48
- // property access (ROUTES.ACCOUNT)
49
- if (
50
- Node.isPropertyAccessExpression(expr)
51
- ) {
84
+ // property access (EVENTS.CLICK)
85
+ if (Node.isPropertyAccessExpression(expr)) {
86
+ const fullName = expr.getText(); // EVENTS.CLICK
87
+ const propName = expr.getName(); // CLICK
88
+
89
+ const defs =
90
+ "getDefinitions" in expr
91
+ ? (expr as any).getDefinitions()
92
+ : [];
93
+
94
+ if (defs && defs.length > 0) {
95
+ const decl = defs[0]?.getDeclarationNode();
96
+
97
+ // const EVENTS = { CLICK: "event" }
98
+ if (decl && Node.isVariableDeclaration(decl)) {
99
+ const init = decl.getInitializer();
100
+
101
+ if (init && Node.isObjectLiteralExpression(init)) {
102
+ const prop = init.getProperty(propName);
103
+
104
+ if (
105
+ prop &&
106
+ Node.isPropertyAssignment(prop)
107
+ ) {
108
+ const value = prop.getInitializer();
109
+
110
+ if (
111
+ value &&
112
+ Node.isStringLiteral(value)
113
+ ) {
114
+ return {
115
+ values: [value.getLiteralText()],
116
+ dynamic: false
117
+ };
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ // fallback
124
+ if (decl && Node.isPropertyAssignment(decl)) {
125
+ const initializer = decl.getInitializer();
126
+
127
+ if (
128
+ initializer &&
129
+ Node.isStringLiteral(initializer)
130
+ ) {
131
+ return {
132
+ values: [initializer.getLiteralText()],
133
+ dynamic: false
134
+ };
135
+ }
136
+ }
137
+ }
138
+
52
139
  return {
53
- values: [expr.getText()],
140
+ values: [fullName],
54
141
  dynamic: true
55
142
  };
56
143
  }
57
144
 
58
- // ternary
59
- if (
60
- Node.isConditionalExpression(expr)
61
- ) {
145
+ // ternary (a ? b : c)
146
+ if (Node.isConditionalExpression(expr)) {
62
147
  const values: string[] = [];
63
148
 
64
149
  const whenTrue =
65
- extractExpression(
66
- expr.getWhenTrue()
67
- );
150
+ extractExpression(expr.getWhenTrue());
68
151
 
69
152
  const whenFalse =
70
- extractExpression(
71
- expr.getWhenFalse()
72
- );
153
+ extractExpression(expr.getWhenFalse());
73
154
 
74
- if (whenTrue)
75
- values.push(
76
- ...whenTrue.values
77
- );
78
-
79
- if (whenFalse)
80
- values.push(
81
- ...whenFalse.values
82
- );
155
+ if (whenTrue) values.push(...whenTrue.values);
156
+ if (whenFalse) values.push(...whenFalse.values);
83
157
 
84
158
  return {
85
159
  values,
@@ -87,25 +161,21 @@ export function extractExpression(
87
161
  };
88
162
  }
89
163
 
90
- // template
91
- if (
92
- Node.isTemplateExpression(expr)
93
- ) {
164
+ // template `${}`
165
+ if (Node.isTemplateExpression(expr)) {
94
166
  return {
95
- values: [expr.getText()],
167
+ values: [
168
+ expr.getText().replace(/`/g, "")
169
+ ],
96
170
  dynamic: true
97
171
  };
98
172
  }
99
173
 
100
- // call
101
- if (
102
- Node.isCallExpression(expr)
103
- ) {
174
+ // call (fn())
175
+ if (Node.isCallExpression(expr)) {
104
176
  return {
105
177
  values: [
106
- expr
107
- .getExpression()
108
- .getText()
178
+ expr.getExpression().getText()
109
179
  ],
110
180
  dynamic: true
111
181
  };
@@ -2,67 +2,81 @@ import {
2
2
  SourceFile,
3
3
  SyntaxKind,
4
4
  Node,
5
- CallExpression,
6
- PropertyAccessExpression
7
5
  } from "ts-morph";
8
6
 
9
- import { ExtractedEvent } from "../../types";
7
+ import { ExtractedEvent, EventraConfig } from "../../types";
10
8
  import { extractExpression } from "../extract";
11
9
 
12
10
  export function scanTrack(
13
- source: SourceFile
11
+ source: SourceFile,
12
+ config: EventraConfig
14
13
  ) {
15
- const events =
16
- new Set<ExtractedEvent>();
14
+ const events = new Set<ExtractedEvent>();
17
15
 
18
- const calls =
19
- source.getDescendantsOfKind(
20
- SyntaxKind.CallExpression
21
- );
16
+ const calls = source.getDescendantsOfKind(
17
+ SyntaxKind.CallExpression
18
+ );
22
19
 
23
20
  for (const call of calls) {
24
- const expr =
25
- call.getExpression();
21
+ const expr = call.getExpression();
26
22
 
27
23
  let isTrack = false;
28
24
 
29
25
  // track()
30
- if (
31
- Node.isIdentifier(expr)
32
- ) {
33
- isTrack =
34
- expr.getText() === "track";
26
+ if (Node.isIdentifier(expr)) {
27
+ isTrack = expr.getText() === "track";
35
28
  }
36
29
 
37
30
  // analytics.track()
38
- if (
39
- Node.isPropertyAccessExpression(
40
- expr
41
- )
42
- ) {
43
- isTrack =
44
- expr.getName() === "track";
31
+ if (Node.isPropertyAccessExpression(expr)) {
32
+ isTrack = expr.getName() === "track";
45
33
  }
46
34
 
47
35
  if (!isTrack) continue;
48
36
 
49
- const arg =
50
- call.getArguments()[0];
37
+ const func =
38
+ call.getFirstAncestorByKind(SyntaxKind.FunctionDeclaration) ||
39
+ call.getFirstAncestorByKind(SyntaxKind.ArrowFunction) ||
40
+ call.getFirstAncestorByKind(SyntaxKind.FunctionExpression);
51
41
 
52
- if (!arg) continue;
42
+ let fnName: string | undefined;
43
+
44
+ if (func) {
45
+ if (Node.isFunctionDeclaration(func)) {
46
+ fnName = func.getName();
47
+ }
53
48
 
54
- const result =
55
- extractExpression(arg);
49
+ if (
50
+ Node.isArrowFunction(func) ||
51
+ Node.isFunctionExpression(func)
52
+ ) {
53
+ const varDecl = func.getFirstAncestorByKind(
54
+ SyntaxKind.VariableDeclaration
55
+ );
56
+ fnName = varDecl?.getName();
57
+ }
58
+ }
59
+
60
+ if (
61
+ fnName &&
62
+ config.functionWrappers?.some(
63
+ (w) => w.name === fnName
64
+ )
65
+ ) {
66
+ continue;
67
+ }
68
+
69
+ const arg = call.getArguments()[0];
70
+ if (!arg) continue;
56
71
 
72
+ const result = extractExpression(arg);
57
73
  if (!result) continue;
58
74
 
59
- result.values.forEach(
60
- (value) =>
61
- events.add({
62
- value,
63
- dynamic:
64
- result.dynamic
65
- })
75
+ result.values.forEach((value) =>
76
+ events.add({
77
+ value,
78
+ dynamic: result.dynamic,
79
+ })
66
80
  );
67
81
  }
68
82