@eventra_dev/eventra-cli 0.1.30 → 0.1.32

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.
@@ -1,28 +1,77 @@
1
1
  import path from "path";
2
2
  import { ParseResult } from "../types";
3
3
 
4
- // Remove comments
4
+ /* ---------------------------------- */
5
+ /* COMMENT STRIP (SAFE) */
6
+ /* ---------------------------------- */
5
7
  function stripComments(input: string): string {
6
8
  return input
7
9
  .replace(/<!--[\s\S]*?-->/g, "")
8
- .replace(/\/\*[\s\S]*?\*\//g, "")
9
- .replace(/\/\/.*$/gm, "");
10
+ .replace(/\/\*[\s\S]*?\*\//g, "");
10
11
  }
11
12
 
12
- // Basic filter
13
+ /* ---------------------------------- */
14
+ /* TRACK DETECTOR */
15
+ /* ---------------------------------- */
13
16
  function looksLikeTracking(code: string) {
14
- return /track/i.test(code);
17
+ return /\btrack\s*\(|\.track\s*\(/.test(code);
15
18
  }
16
19
 
17
- // HTML inline handlers (onclick="")
20
+ /* ---------------------------------- */
21
+ /* SAFE {} PARSER (JSX / TEMPLATES) */
22
+ /* ---------------------------------- */
23
+ function extractBracedExpressions(input: string): string[] {
24
+ const result: string[] = [];
25
+
26
+ let depth = 0;
27
+ let start = -1;
28
+ let inString: string | null = null;
29
+
30
+ for (let i = 0; i < input.length; i++) {
31
+ const char = input[i];
32
+
33
+ // handle strings
34
+ if (inString) {
35
+ if (char === inString && input[i - 1] !== "\\") {
36
+ inString = null;
37
+ }
38
+ continue;
39
+ }
40
+
41
+ if (char === '"' || char === "'" || char === "`") {
42
+ inString = char;
43
+ continue;
44
+ }
45
+
46
+ if (char === "{") {
47
+ if (depth === 0) start = i + 1;
48
+ depth++;
49
+ } else if (char === "}") {
50
+ depth--;
51
+ if (depth === 0 && start !== -1) {
52
+ const expr = input.slice(start, i);
53
+
54
+ if (looksLikeTracking(expr)) {
55
+ result.push(expr);
56
+ }
57
+
58
+ start = -1;
59
+ }
60
+ }
61
+ }
62
+
63
+ return result;
64
+ }
65
+
66
+ /* ---------------------------------- */
67
+ /* HTML HANDLERS */
68
+ /* ---------------------------------- */
18
69
  function extractHTMLHandlers(input: string): string[] {
19
70
  const result: string[] = [];
20
71
 
21
- const matches = input.matchAll(
22
- /\bon\w+\s*=\s*["']([^"']+)["']/g
23
- );
72
+ const regex = /\bon\w+\s*=\s*["']([^"']+)["']/g;
24
73
 
25
- for (const m of matches) {
74
+ for (const m of input.matchAll(regex)) {
26
75
  if (looksLikeTracking(m[1])) {
27
76
  result.push(m[1]);
28
77
  }
@@ -31,15 +80,15 @@ function extractHTMLHandlers(input: string): string[] {
31
80
  return result;
32
81
  }
33
82
 
34
- // Vue handlers (@click / v-on)
83
+ /* ---------------------------------- */
84
+ /* VUE HANDLERS */
85
+ /* ---------------------------------- */
35
86
  function extractVueHandlers(input: string): string[] {
36
87
  const result: string[] = [];
37
88
 
38
- const matches = input.matchAll(
39
- /(?:@|v-on:)[\w:-]+\s*=\s*["']([^"']+)["']/g
40
- );
89
+ const regex = /(?:@|v-on:)[\w:-]+\s*=\s*["']([^"']+)["']/g;
41
90
 
42
- for (const m of matches) {
91
+ for (const m of input.matchAll(regex)) {
43
92
  if (looksLikeTracking(m[1])) {
44
93
  result.push(m[1]);
45
94
  }
@@ -48,51 +97,95 @@ function extractVueHandlers(input: string): string[] {
48
97
  return result;
49
98
  }
50
99
 
51
- // Svelte handlers (on:click)
100
+ /* ---------------------------------- */
101
+ /* SVELTE HANDLERS */
102
+ /* ---------------------------------- */
52
103
  function extractSvelteHandlers(input: string): string[] {
53
104
  const result: string[] = [];
54
105
 
55
- const matches = input.matchAll(
56
- /\bon:[\w]+\s*=\s*{([^}]+)}/g
57
- );
106
+ const regex = /\bon:[\w]+\s*=\s*{([\s\S]*?)}/g;
58
107
 
59
- for (const m of matches) {
60
- if (looksLikeTracking(m[1])) {
61
- result.push(m[1]);
62
- }
108
+ for (const m of input.matchAll(regex)) {
109
+ const expr = m[1];
110
+
111
+ const nested = extractBracedExpressions(`{${expr}}`);
112
+ result.push(...nested);
63
113
  }
64
114
 
65
115
  return result;
66
116
  }
67
117
 
68
- // JSX / template { ... }
69
- function extractJSExpressions(input: string): string[] {
70
- const result: string[] = [];
118
+ /* ---------------------------------- */
119
+ /* SCRIPT EXTRACTION */
120
+ /* ---------------------------------- */
121
+ function extractScripts(input: string, file: string) {
122
+ const scripts: string[] = [];
123
+ const deps: string[] = [];
71
124
 
72
- const matches = input.matchAll(/\{([^}]+)\}/g);
125
+ // <script src="">
126
+ const srcRegex =
127
+ /<script\b[^>]*?\bsrc=["'](.+?)["'][^>]*>/gi;
73
128
 
74
- for (const m of matches) {
75
- if (looksLikeTracking(m[1])) {
76
- result.push(m[1]);
129
+ for (const m of input.matchAll(srcRegex)) {
130
+ const src = m[1];
131
+
132
+ const resolved = src.startsWith("/")
133
+ ? path.resolve(process.cwd(), "." + src)
134
+ : path.resolve(path.dirname(file), src);
135
+
136
+ deps.push(resolved);
137
+ }
138
+
139
+ // inline <script>
140
+ const scriptRegex =
141
+ /<script\b[^>]*>([\s\S]*?)<\/script>/gi;
142
+
143
+ for (const m of input.matchAll(scriptRegex)) {
144
+ if (m[1]?.trim()) {
145
+ scripts.push(m[1]);
77
146
  }
78
147
  }
79
148
 
80
- return result;
149
+ const noScripts = input.replace(scriptRegex, "");
150
+
151
+ return { scripts, deps, noScripts };
81
152
  }
82
153
 
83
- // dynamic import()
84
- function extractDynamicImports(
85
- input: string,
86
- file: string
87
- ): { deps: string[]; calls: string[] } {
154
+ /* ---------------------------------- */
155
+ /* STATIC IMPORTS */
156
+ /* ---------------------------------- */
157
+ function extractStaticImports(input: string, file: string) {
158
+ const deps: string[] = [];
159
+
160
+ const regex =
161
+ /import\s+(?:.+?\s+from\s+)?["'](.+?)["']/g;
162
+
163
+ for (const m of input.matchAll(regex)) {
164
+ const mod = m[1];
165
+
166
+ if (!mod.startsWith(".") && !mod.startsWith("/")) continue;
167
+
168
+ const resolved = path.resolve(
169
+ path.dirname(file),
170
+ mod
171
+ );
172
+
173
+ deps.push(resolved);
174
+ }
175
+
176
+ return deps;
177
+ }
178
+
179
+ /* ---------------------------------- */
180
+ /* DYNAMIC IMPORTS */
181
+ /* ---------------------------------- */
182
+ function extractDynamicImports(input: string, file: string) {
88
183
  const deps: string[] = [];
89
184
  const calls: string[] = [];
90
185
 
91
- const matches = input.matchAll(
92
- /import\(\s*["'](.+?)["']\s*\)/g
93
- );
186
+ const regex = /import\(\s*["'](.+?)["']\s*\)/g;
94
187
 
95
- for (const m of matches) {
188
+ for (const m of input.matchAll(regex)) {
96
189
  const mod = m[1];
97
190
 
98
191
  const resolved = mod.startsWith("/")
@@ -109,7 +202,9 @@ function extractDynamicImports(
109
202
  return { deps, calls };
110
203
  }
111
204
 
112
- // UNIVERSAL PARSER
205
+ /* ---------------------------------- */
206
+ /* MAIN */
207
+ /* ---------------------------------- */
113
208
  export function parseUniversal(
114
209
  content: string,
115
210
  file: string
@@ -119,53 +214,30 @@ export function parseUniversal(
119
214
 
120
215
  const clean = stripComments(content);
121
216
 
122
- // ASTRO FRONTMATTER
123
- const fm = clean.match(/^---([\s\S]*?)---/);
217
+ /* ---------- ASTRO FRONTMATTER ---------- */
218
+ const fm = clean.match(/^\s*---([\s\S]*?)---/);
124
219
  if (fm?.[1]) {
125
220
  parts.push(fm[1]);
126
221
  }
127
222
 
128
- // <script src="">
129
- const scriptSrc = clean.matchAll(
130
- /<script\b[^>]*?\bsrc=["'](.+?)["'][^>]*>/g
131
- );
132
-
133
- for (const s of scriptSrc) {
134
- const src = s[1];
223
+ /* ---------- SCRIPTS ---------- */
224
+ const { scripts, deps: scriptDeps, noScripts } =
225
+ extractScripts(clean, file);
135
226
 
136
- const resolved = src.startsWith("/")
137
- ? path.resolve(process.cwd(), "." + src)
138
- : path.resolve(path.dirname(file), src);
227
+ parts.push(...scripts);
228
+ deps.push(...scriptDeps);
139
229
 
140
- deps.push(resolved);
141
- }
142
-
143
- // INLINE <script>
144
- const scripts = clean.matchAll(
145
- /<script\b([^>]*)>([\s\S]*?)<\/script>/g
146
- );
147
-
148
- for (const m of scripts) {
149
- if (m[2].trim()) {
150
- parts.push(m[2]);
151
- }
152
- }
153
-
154
- // TEMPLATE PART
155
- const noScripts = clean.replace(
156
- /<script[\s\S]*?<\/script>/g,
157
- ""
158
- );
159
-
160
- // handlers
230
+ /* ---------- HANDLERS ---------- */
161
231
  parts.push(...extractHTMLHandlers(noScripts));
162
232
  parts.push(...extractVueHandlers(noScripts));
163
233
  parts.push(...extractSvelteHandlers(noScripts));
164
234
 
165
- // JSX / Astro / Vue expressions
166
- parts.push(...extractJSExpressions(clean));
235
+ /* ---------- JSX / TEMPLATE ---------- */
236
+ parts.push(...extractBracedExpressions(clean));
237
+
238
+ /* ---------- IMPORTS ---------- */
239
+ deps.push(...extractStaticImports(clean, file));
167
240
 
168
- // dynamic imports
169
241
  const dyn = extractDynamicImports(clean, file);
170
242
  deps.push(...dyn.deps);
171
243
  parts.push(...dyn.calls);
package/tests/run.ts CHANGED
@@ -40,7 +40,6 @@ function ensureTestConfig(dir: string) {
40
40
  events: [],
41
41
  wrappers: [],
42
42
  functionWrappers: [],
43
- aliases: {},
44
43
  sync: {
45
44
  include: [
46
45
  "**/*.{ts,tsx,js,jsx,vue,svelte,astro}"
@@ -1,17 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.isTrackingCall = isTrackingCall;
7
- const typescript_1 = __importDefault(require("typescript"));
8
- function isTrackingCall(node) {
9
- const expr = node.expression;
10
- if (typescript_1.default.isIdentifier(expr)) {
11
- return expr.text === "track";
12
- }
13
- if (typescript_1.default.isPropertyAccessExpression(expr)) {
14
- return expr.name.text === "track";
15
- }
16
- return false;
17
- }
@@ -1,17 +0,0 @@
1
- import ts from "typescript";
2
-
3
- export function isTrackingCall(
4
- node: ts.CallExpression
5
- ): boolean {
6
- const expr = node.expression;
7
-
8
- if (ts.isIdentifier(expr)) {
9
- return expr.text === "track";
10
- }
11
-
12
- if (ts.isPropertyAccessExpression(expr)) {
13
- return expr.name.text === "track";
14
- }
15
-
16
- return false;
17
- }