@eventra_dev/eventra-cli 0.1.17 → 0.1.19

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.
@@ -24,31 +24,37 @@ async function check({ fix = false }) {
24
24
  for (const file of files) {
25
25
  try {
26
26
  const raw = await promises_1.default.readFile(file, "utf-8");
27
- const { content, virtualFile } = (0, processFile_1.processFile)(file, raw);
27
+ const { content, virtualFile, deps } = (0, processFile_1.processFile)(file, raw);
28
28
  engine.scanFile(virtualFile, content, config);
29
+ for (const dep of deps) {
30
+ try {
31
+ const depRaw = await promises_1.default.readFile(dep, "utf-8");
32
+ const { content: depContent, virtualFile: depVirtual, } = (0, processFile_1.processFile)(dep, depRaw);
33
+ engine.scanFile(depVirtual, depContent, config);
34
+ }
35
+ catch { }
36
+ }
29
37
  }
30
38
  catch (err) {
31
39
  console.log(chalk_1.default.yellow(`Skipped: ${file}`));
32
- if (err instanceof Error) {
33
- console.log(chalk_1.default.gray(err.message));
34
- }
35
40
  }
36
41
  }
37
42
  const found = new Set(engine.getAllEvents());
38
43
  const known = new Set(config.events ?? []);
39
44
  const newEvents = [...found].filter(e => !known.has(e));
40
45
  const removed = [...known].filter(e => !found.has(e));
46
+ // FIX MODE
41
47
  if (fix) {
42
- const merged = new Set(config.events ?? []);
43
- newEvents.forEach(e => {
44
- merged.add(e);
45
- console.log(chalk_1.default.green(`+ ${e}`));
46
- });
47
- config.events = [...merged].sort();
48
+ const next = new Set();
49
+ found.forEach(e => next.add(e));
50
+ newEvents.forEach(e => console.log(chalk_1.default.green(`+ ${e}`)));
51
+ removed.forEach(e => console.log(chalk_1.default.red(`- ${e}`)));
52
+ config.events = [...next].sort();
48
53
  await (0, config_1.saveConfig)(config);
49
- console.log(chalk_1.default.green("\nFixed"));
54
+ console.log(chalk_1.default.green(`\nSynced (${config.events.length} events)`));
50
55
  return;
51
56
  }
57
+ // CHECK MODE
52
58
  if (newEvents.length || removed.length) {
53
59
  if (newEvents.length) {
54
60
  console.log(chalk_1.default.red("\nNew events:"));
@@ -29,13 +29,21 @@ async function sync() {
29
29
  for (const file of files) {
30
30
  try {
31
31
  const raw = await promises_1.default.readFile(file, "utf-8");
32
- const { content, virtualFile } = (0, processFile_1.processFile)(file, raw);
32
+ const { content, virtualFile, deps } = (0, processFile_1.processFile)(file, raw);
33
33
  engine["ts"].updateFile(virtualFile, content);
34
34
  fileCache.push({ file: virtualFile, content });
35
+ // deps
36
+ for (const dep of deps) {
37
+ try {
38
+ const depRaw = await promises_1.default.readFile(dep, "utf-8");
39
+ const { content: depContent, virtualFile: depVirtual, } = (0, processFile_1.processFile)(dep, depRaw);
40
+ engine["ts"].updateFile(depVirtual, depContent);
41
+ fileCache.push({ file: depVirtual, content: depContent });
42
+ }
43
+ catch { }
44
+ }
35
45
  }
36
- catch {
37
- // ignore
38
- }
46
+ catch { }
39
47
  }
40
48
  for (const { file, content } of fileCache) {
41
49
  try {
@@ -53,8 +53,17 @@ async function watch() {
53
53
  for (const file of batch) {
54
54
  try {
55
55
  const raw = await promises_1.default.readFile(file, "utf-8");
56
- const { content, virtualFile } = (0, processFile_1.processFile)(file, raw);
56
+ const { content, virtualFile, deps } = (0, processFile_1.processFile)(file, raw);
57
57
  engine.updateFile(virtualFile, content, config);
58
+ // deps
59
+ for (const dep of deps) {
60
+ try {
61
+ const depRaw = await promises_1.default.readFile(dep, "utf-8");
62
+ const { content: depContent, virtualFile: depVirtual, } = (0, processFile_1.processFile)(dep, depRaw);
63
+ engine.updateFile(depVirtual, depContent, config);
64
+ }
65
+ catch { }
66
+ }
58
67
  }
59
68
  catch {
60
69
  console.log(chalk_1.default.gray(`skip: ${file}`));
@@ -87,6 +87,7 @@ function scanSource(source, checker, config, visited = new Set(), depth = 0, inh
87
87
  const isAutoWrapper = resolvedFn && (0, functionAnalyzer_1.findTrackParamIndex)(resolvedFn) !== null;
88
88
  const isTracking = isKnownWrapper ||
89
89
  TRACKING_NAMES.has(name) ||
90
+ name.startsWith("$") || // NUXT FIX
90
91
  (isAutoWrapper &&
91
92
  resolvedFn &&
92
93
  !(0, boundary_1.isExternalFile)(resolvedFn.getSourceFile().fileName));
@@ -97,7 +98,6 @@ function scanSource(source, checker, config, visited = new Set(), depth = 0, inh
97
98
  if (!isKnownWrapper && isAutoWrapper && !TRACKING_NAMES.has(name)) {
98
99
  detectedFunctionWrappers.add(name);
99
100
  }
100
- // paramMap (chain support)
101
101
  const paramMap = new Map(inheritedParamMap ?? []);
102
102
  if (resolvedFn && typescript_1.default.isFunctionLike(resolvedFn)) {
103
103
  resolvedFn.parameters.forEach((param, i) => {
@@ -110,6 +110,7 @@ function scanSource(source, checker, config, visited = new Set(), depth = 0, inh
110
110
  });
111
111
  }
112
112
  let handled = false;
113
+ // MAIN RESOLVE
113
114
  if (resolvedFn) {
114
115
  const idx = (0, functionAnalyzer_1.findTrackParamIndex)(resolvedFn);
115
116
  if (idx !== null && node.arguments[idx]) {
@@ -121,6 +122,7 @@ function scanSource(source, checker, config, visited = new Set(), depth = 0, inh
121
122
  handled = true;
122
123
  }
123
124
  }
125
+ // FALLBACK
124
126
  if (!handled) {
125
127
  for (const arg of node.arguments) {
126
128
  const res = (0, resolver_1.resolveNodeValue)(arg, checker, paramMap);
@@ -130,7 +132,7 @@ function scanSource(source, checker, config, visited = new Set(), depth = 0, inh
130
132
  });
131
133
  }
132
134
  }
133
- // cross-file with paramMap
135
+ // CROSS FILE
134
136
  if (resolvedFn) {
135
137
  const sf = resolvedFn.getSourceFile();
136
138
  if (!visited.has(sf.fileName)) {
@@ -1,8 +1,13 @@
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.parseAstro = parseAstro;
4
- function parseAstro(content) {
7
+ const path_1 = __importDefault(require("path"));
8
+ function parseAstro(content, file) {
5
9
  const parts = [];
10
+ const deps = [];
6
11
  // frontmatter
7
12
  const frontmatter = content.match(/^---([\s\S]*?)---/);
8
13
  if (frontmatter?.[1]) {
@@ -13,20 +18,22 @@ function parseAstro(content) {
13
18
  for (const m of scripts) {
14
19
  const attrs = m[1];
15
20
  const body = m[2];
21
+ // external script
16
22
  if (attrs.includes("src")) {
17
23
  const src = attrs.match(/src=["'](.+?)["']/)?.[1];
18
- if (src) {
19
- parts.push(`import "${src}"`);
20
- }
24
+ if (!src)
25
+ continue;
26
+ const resolved = src.startsWith("/")
27
+ ? path_1.default.resolve(process.cwd(), src.slice(1))
28
+ : path_1.default.resolve(path_1.default.dirname(file), src);
29
+ deps.push(resolved);
21
30
  }
22
31
  else {
23
32
  parts.push(body);
24
33
  }
25
34
  }
26
- // inline handlers
27
- const inlineJS = content.matchAll(/on\w+="([^"]+)"/g);
28
- for (const m of inlineJS) {
29
- parts.push(m[1] + ";");
30
- }
31
- return parts.join("\n");
35
+ return {
36
+ code: parts.join("\n"),
37
+ deps,
38
+ };
32
39
  }
@@ -1,13 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.detectParser = detectParser;
4
+ const vue_1 = require("./vue");
5
+ const svelte_1 = require("./svelte");
6
+ const astro_1 = require("./astro");
7
+ const fallback = (content) => ({
8
+ code: content,
9
+ deps: [],
10
+ });
4
11
  function detectParser(file) {
5
- file = file.toLowerCase();
6
- if (file.endsWith(".vue"))
7
- return "vue";
8
- if (file.endsWith(".svelte"))
9
- return "svelte";
10
- if (file.endsWith(".astro"))
11
- return "astro";
12
- return "ts";
12
+ const f = file.toLowerCase();
13
+ if (f.endsWith(".vue"))
14
+ return vue_1.parseVue;
15
+ if (f.endsWith(".svelte"))
16
+ return svelte_1.parseSvelte;
17
+ if (f.endsWith(".astro"))
18
+ return astro_1.parseAstro;
19
+ return fallback;
13
20
  }
@@ -3,15 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseSvelte = parseSvelte;
4
4
  function parseSvelte(content) {
5
5
  const parts = [];
6
- // scripts
6
+ const deps = [];
7
+ // script
7
8
  const scripts = content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g);
8
9
  for (const m of scripts) {
9
10
  parts.push(m[1]);
10
11
  }
11
- // on:click / on:*
12
+ // on:click={...}
12
13
  const handlers = content.matchAll(/on:\w+=\{([^}]+)\}/g);
13
14
  for (const h of handlers) {
14
15
  parts.push(h[1] + ";");
15
16
  }
16
- return parts.join("\n");
17
+ return {
18
+ code: parts.join("\n"),
19
+ deps,
20
+ };
17
21
  }
@@ -1,41 +1,51 @@
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.parseVue = parseVue;
4
- function parseVue(content) {
7
+ const path_1 = __importDefault(require("path"));
8
+ function parseVue(content, file) {
5
9
  const parts = [];
6
- // --- SCRIPT ---
10
+ const deps = [];
11
+ // SCRIPT
7
12
  const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
8
13
  for (const m of scripts) {
9
14
  const attrs = m[1];
10
15
  const body = m[2];
11
16
  if (attrs.includes("src")) {
12
17
  const src = attrs.match(/src=["'](.+?)["']/)?.[1];
13
- if (src) {
14
- parts.push(`import "${src}"`);
15
- }
18
+ if (!src)
19
+ continue;
20
+ const resolved = src.startsWith("/")
21
+ ? path_1.default.resolve(process.cwd(), src.slice(1))
22
+ : path_1.default.resolve(path_1.default.dirname(file), src);
23
+ deps.push(resolved);
16
24
  continue;
17
25
  }
18
26
  parts.push(body);
19
27
  }
20
- // --- TEMPLATE ---
28
+ // TEMPLATE
21
29
  const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/);
22
30
  let template = templateMatch?.[1] ?? "";
23
- // remove comments
24
31
  template = template.replace(/<!--[\s\S]*?-->/g, "");
25
- // --- event handlers (@click)
32
+ // @click
26
33
  const handlers = template.matchAll(/@[\w-]+="([^"]+)"/g);
27
34
  for (const h of handlers) {
28
35
  parts.push(h[1] + ";");
29
36
  }
30
- // --- v-on
37
+ // v-on
31
38
  const vOn = template.matchAll(/v-on:[\w-]+="([^"]+)"/g);
32
39
  for (const v of vOn) {
33
40
  parts.push(v[1] + ";");
34
41
  }
35
- // --- :prop bindings
42
+ // :prop
36
43
  const binds = template.matchAll(/:[\w-]+="([^"]+)"/g);
37
44
  for (const b of binds) {
38
45
  parts.push(b[1] + ";");
39
46
  }
40
- return parts.join("\n");
47
+ return {
48
+ code: parts.join("\n"),
49
+ deps,
50
+ };
41
51
  }
@@ -2,21 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.processFile = processFile;
4
4
  const router_1 = require("./parsers/router");
5
- const vue_1 = require("./parsers/vue");
6
- const svelte_1 = require("./parsers/svelte");
7
- const astro_1 = require("./parsers/astro");
8
5
  function processFile(file, content) {
9
6
  const parser = (0, router_1.detectParser)(file);
10
- if (parser === "vue")
11
- content = (0, vue_1.parseVue)(content);
12
- if (parser === "svelte")
13
- content = (0, svelte_1.parseSvelte)(content);
14
- if (parser === "astro")
15
- content = (0, astro_1.parseAstro)(content);
7
+ const res = parser(content, file);
16
8
  const virtualFile = file.endsWith(".vue") ||
17
9
  file.endsWith(".svelte") ||
18
10
  file.endsWith(".astro")
19
11
  ? file + ".tsx"
20
12
  : file;
21
- return { content, virtualFile };
13
+ return {
14
+ content: res.code,
15
+ virtualFile,
16
+ deps: res.deps,
17
+ };
22
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventra_dev/eventra-cli",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Eventra CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -26,16 +26,25 @@ export async function check({ fix = false }: { fix?: boolean }) {
26
26
  try {
27
27
  const raw = await fs.readFile(file, "utf-8");
28
28
 
29
- const { content, virtualFile } = processFile(file, raw);
29
+ const { content, virtualFile, deps } = processFile(file, raw);
30
30
 
31
31
  engine.scanFile(virtualFile, content, config);
32
32
 
33
- } catch (err) {
34
- console.log(chalk.yellow(`Skipped: ${file}`));
33
+ for (const dep of deps) {
34
+ try {
35
+ const depRaw = await fs.readFile(dep, "utf-8");
36
+
37
+ const {
38
+ content: depContent,
39
+ virtualFile: depVirtual,
40
+ } = processFile(dep, depRaw);
35
41
 
36
- if (err instanceof Error) {
37
- console.log(chalk.gray(err.message));
42
+ engine.scanFile(depVirtual, depContent, config);
43
+ } catch {}
38
44
  }
45
+
46
+ } catch (err) {
47
+ console.log(chalk.yellow(`Skipped: ${file}`));
39
48
  }
40
49
  }
41
50
 
@@ -45,31 +54,45 @@ export async function check({ fix = false }: { fix?: boolean }) {
45
54
  const newEvents = [...found].filter(e => !known.has(e));
46
55
  const removed = [...known].filter(e => !found.has(e));
47
56
 
57
+ // FIX MODE
48
58
  if (fix) {
49
- const merged = new Set(config.events ?? []);
59
+ const next = new Set<string>();
60
+
61
+ found.forEach(e => next.add(e));
50
62
 
51
- newEvents.forEach(e => {
52
- merged.add(e);
53
- console.log(chalk.green(`+ ${e}`));
54
- });
63
+ newEvents.forEach(e =>
64
+ console.log(chalk.green(`+ ${e}`))
65
+ );
55
66
 
56
- config.events = [...merged].sort();
67
+ removed.forEach(e =>
68
+ console.log(chalk.red(`- ${e}`))
69
+ );
70
+
71
+ config.events = [...next].sort();
57
72
 
58
73
  await saveConfig(config);
59
74
 
60
- console.log(chalk.green("\nFixed"));
75
+ console.log(
76
+ chalk.green(`\nSynced (${config.events.length} events)`)
77
+ );
78
+
61
79
  return;
62
80
  }
63
81
 
82
+ // CHECK MODE
64
83
  if (newEvents.length || removed.length) {
65
84
  if (newEvents.length) {
66
85
  console.log(chalk.red("\nNew events:"));
67
- newEvents.forEach(e => console.log(chalk.red(`+ ${e}`)));
86
+ newEvents.forEach(e =>
87
+ console.log(chalk.red(`+ ${e}`))
88
+ );
68
89
  }
69
90
 
70
91
  if (removed.length) {
71
92
  console.log(chalk.yellow("\nRemoved events:"));
72
- removed.forEach(e => console.log(chalk.yellow(`- ${e}`)));
93
+ removed.forEach(e =>
94
+ console.log(chalk.yellow(`- ${e}`))
95
+ );
73
96
  }
74
97
 
75
98
  process.exit(1);
@@ -31,12 +31,29 @@ export async function sync() {
31
31
  for (const file of files) {
32
32
  try {
33
33
  const raw = await fs.readFile(file, "utf-8");
34
- const { content, virtualFile } = processFile(file, raw);
34
+
35
+ const { content, virtualFile, deps } = processFile(file, raw);
36
+
35
37
  engine["ts"].updateFile(virtualFile, content);
36
38
  fileCache.push({ file: virtualFile, content });
37
- } catch {
38
- // ignore
39
- }
39
+
40
+ // deps
41
+ for (const dep of deps) {
42
+ try {
43
+ const depRaw = await fs.readFile(dep, "utf-8");
44
+
45
+ const {
46
+ content: depContent,
47
+ virtualFile: depVirtual,
48
+ } = processFile(dep, depRaw);
49
+
50
+ engine["ts"].updateFile(depVirtual, depContent);
51
+ fileCache.push({ file: depVirtual, content: depContent });
52
+
53
+ } catch {}
54
+ }
55
+
56
+ } catch {}
40
57
  }
41
58
 
42
59
  for (const { file, content } of fileCache) {
@@ -60,10 +60,26 @@ export async function watch() {
60
60
  for (const file of batch) {
61
61
  try {
62
62
  const raw = await fs.readFile(file, "utf-8");
63
- const { content, virtualFile } = processFile(file, raw);
63
+
64
+ const { content, virtualFile, deps } = processFile(file, raw);
64
65
 
65
66
  engine.updateFile(virtualFile, content, config);
66
67
 
68
+ // deps
69
+ for (const dep of deps) {
70
+ try {
71
+ const depRaw = await fs.readFile(dep, "utf-8");
72
+
73
+ const {
74
+ content: depContent,
75
+ virtualFile: depVirtual,
76
+ } = processFile(dep, depRaw);
77
+
78
+ engine.updateFile(depVirtual, depContent, config);
79
+
80
+ } catch {}
81
+ }
82
+
67
83
  } catch {
68
84
  console.log(chalk.gray(`skip: ${file}`));
69
85
  }
@@ -126,6 +126,7 @@ export function scanSource(
126
126
  const isTracking =
127
127
  isKnownWrapper ||
128
128
  TRACKING_NAMES.has(name) ||
129
+ name.startsWith("$") || // NUXT FIX
129
130
  (isAutoWrapper &&
130
131
  resolvedFn &&
131
132
  !isExternalFile(resolvedFn.getSourceFile().fileName));
@@ -139,7 +140,6 @@ export function scanSource(
139
140
  detectedFunctionWrappers.add(name);
140
141
  }
141
142
 
142
- // paramMap (chain support)
143
143
  const paramMap = new Map(inheritedParamMap ?? []);
144
144
 
145
145
  if (resolvedFn && ts.isFunctionLike(resolvedFn)) {
@@ -155,6 +155,7 @@ export function scanSource(
155
155
 
156
156
  let handled = false;
157
157
 
158
+ // MAIN RESOLVE
158
159
  if (resolvedFn) {
159
160
  const idx = findTrackParamIndex(resolvedFn);
160
161
 
@@ -173,6 +174,7 @@ export function scanSource(
173
174
  }
174
175
  }
175
176
 
177
+ // FALLBACK
176
178
  if (!handled) {
177
179
  for (const arg of node.arguments) {
178
180
  const res = resolveNodeValue(arg, checker, paramMap);
@@ -183,7 +185,7 @@ export function scanSource(
183
185
  }
184
186
  }
185
187
 
186
- // cross-file with paramMap
188
+ // CROSS FILE
187
189
  if (resolvedFn) {
188
190
  const sf = resolvedFn.getSourceFile();
189
191
 
package/src/types.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  export type ScanMode = "strict" | "hybrid" | "discovery";
2
2
 
3
+ export type ParseResult = {
4
+ code: string;
5
+ deps: string[];
6
+ };
7
+
8
+ export type Parser = (content: string, file: string) => ParseResult;
9
+
10
+
3
11
  export type ComponentWrapper = {
4
12
  name: string;
5
13
  prop: string;
@@ -23,8 +31,3 @@ export type EventraConfig = {
23
31
  exclude: string[];
24
32
  };
25
33
  };
26
-
27
- export type ResolveResult = {
28
- values: string[];
29
- dynamic: boolean;
30
- };
@@ -1,5 +1,9 @@
1
- export function parseAstro(content: string) {
1
+ import path from "path";
2
+ import { ParseResult } from "../../types";
3
+
4
+ export function parseAstro(content: string, file: string): ParseResult {
2
5
  const parts: string[] = [];
6
+ const deps: string[] = [];
3
7
 
4
8
  // frontmatter
5
9
  const frontmatter = content.match(/^---([\s\S]*?)---/);
@@ -14,22 +18,23 @@ export function parseAstro(content: string) {
14
18
  const attrs = m[1];
15
19
  const body = m[2];
16
20
 
21
+ // external script
17
22
  if (attrs.includes("src")) {
18
23
  const src = attrs.match(/src=["'](.+?)["']/)?.[1];
19
- if (src) {
20
- parts.push(`import "${src}"`);
21
- }
24
+ if (!src) continue;
25
+
26
+ const resolved = src.startsWith("/")
27
+ ? path.resolve(process.cwd(), src.slice(1))
28
+ : path.resolve(path.dirname(file), src);
29
+
30
+ deps.push(resolved);
22
31
  } else {
23
32
  parts.push(body);
24
33
  }
25
34
  }
26
35
 
27
- // inline handlers
28
- const inlineJS = content.matchAll(/on\w+="([^"]+)"/g);
29
-
30
- for (const m of inlineJS) {
31
- parts.push(m[1] + ";");
32
- }
33
-
34
- return parts.join("\n");
36
+ return {
37
+ code: parts.join("\n"),
38
+ deps,
39
+ };
35
40
  }
@@ -1,9 +1,19 @@
1
- export function detectParser(file: string) {
2
- file = file.toLowerCase();
1
+ import { Parser } from "../../types";
2
+ import { parseVue } from "./vue";
3
+ import { parseSvelte } from "./svelte";
4
+ import { parseAstro } from "./astro";
3
5
 
4
- if (file.endsWith(".vue")) return "vue";
5
- if (file.endsWith(".svelte")) return "svelte";
6
- if (file.endsWith(".astro")) return "astro";
6
+ const fallback: Parser = (content) => ({
7
+ code: content,
8
+ deps: [],
9
+ });
7
10
 
8
- return "ts";
11
+ export function detectParser(file: string): Parser {
12
+ const f = file.toLowerCase();
13
+
14
+ if (f.endsWith(".vue")) return parseVue;
15
+ if (f.endsWith(".svelte")) return parseSvelte;
16
+ if (f.endsWith(".astro")) return parseAstro;
17
+
18
+ return fallback;
9
19
  }
@@ -1,17 +1,24 @@
1
- export function parseSvelte(content: string) {
1
+ import { ParseResult } from "../../types";
2
+
3
+ export function parseSvelte(content: string): ParseResult {
2
4
  const parts: string[] = [];
5
+ const deps: string[] = [];
3
6
 
4
- // scripts
7
+ // script
5
8
  const scripts = content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g);
6
9
  for (const m of scripts) {
7
10
  parts.push(m[1]);
8
11
  }
9
12
 
10
- // on:click / on:*
13
+ // on:click={...}
11
14
  const handlers = content.matchAll(/on:\w+=\{([^}]+)\}/g);
15
+
12
16
  for (const h of handlers) {
13
17
  parts.push(h[1] + ";");
14
18
  }
15
19
 
16
- return parts.join("\n");
20
+ return {
21
+ code: parts.join("\n"),
22
+ deps,
23
+ };
17
24
  }
@@ -1,7 +1,11 @@
1
- export function parseVue(content: string) {
1
+ import path from "path";
2
+ import { ParseResult } from "../../types";
3
+
4
+ export function parseVue(content: string, file: string): ParseResult {
2
5
  const parts: string[] = [];
6
+ const deps: string[] = [];
3
7
 
4
- // --- SCRIPT ---
8
+ // SCRIPT
5
9
  const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
6
10
 
7
11
  for (const m of scripts) {
@@ -10,39 +14,45 @@ export function parseVue(content: string) {
10
14
 
11
15
  if (attrs.includes("src")) {
12
16
  const src = attrs.match(/src=["'](.+?)["']/)?.[1];
13
- if (src) {
14
- parts.push(`import "${src}"`);
15
- }
17
+ if (!src) continue;
18
+
19
+ const resolved = src.startsWith("/")
20
+ ? path.resolve(process.cwd(), src.slice(1))
21
+ : path.resolve(path.dirname(file), src);
22
+
23
+ deps.push(resolved);
16
24
  continue;
17
25
  }
18
26
 
19
27
  parts.push(body);
20
28
  }
21
29
 
22
- // --- TEMPLATE ---
30
+ // TEMPLATE
23
31
  const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/);
24
32
  let template = templateMatch?.[1] ?? "";
25
33
 
26
- // remove comments
27
34
  template = template.replace(/<!--[\s\S]*?-->/g, "");
28
35
 
29
- // --- event handlers (@click)
36
+ // @click
30
37
  const handlers = template.matchAll(/@[\w-]+="([^"]+)"/g);
31
38
  for (const h of handlers) {
32
39
  parts.push(h[1] + ";");
33
40
  }
34
41
 
35
- // --- v-on
42
+ // v-on
36
43
  const vOn = template.matchAll(/v-on:[\w-]+="([^"]+)"/g);
37
44
  for (const v of vOn) {
38
45
  parts.push(v[1] + ";");
39
46
  }
40
47
 
41
- // --- :prop bindings
48
+ // :prop
42
49
  const binds = template.matchAll(/:[\w-]+="([^"]+)"/g);
43
50
  for (const b of binds) {
44
51
  parts.push(b[1] + ";");
45
52
  }
46
53
 
47
- return parts.join("\n");
54
+ return {
55
+ code: parts.join("\n"),
56
+ deps,
57
+ };
48
58
  }
@@ -1,14 +1,9 @@
1
1
  import { detectParser } from "./parsers/router";
2
- import { parseVue } from "./parsers/vue";
3
- import { parseSvelte } from "./parsers/svelte";
4
- import { parseAstro } from "./parsers/astro";
5
2
 
6
3
  export function processFile(file: string, content: string) {
7
4
  const parser = detectParser(file);
8
5
 
9
- if (parser === "vue") content = parseVue(content);
10
- if (parser === "svelte") content = parseSvelte(content);
11
- if (parser === "astro") content = parseAstro(content);
6
+ const res = parser(content, file);
12
7
 
13
8
  const virtualFile =
14
9
  file.endsWith(".vue") ||
@@ -17,5 +12,9 @@ export function processFile(file: string, content: string) {
17
12
  ? file + ".tsx"
18
13
  : file;
19
14
 
20
- return { content, virtualFile };
15
+ return {
16
+ content: res.code,
17
+ virtualFile,
18
+ deps: res.deps,
19
+ };
21
20
  }