@eventra_dev/eventra-cli 0.1.15 → 0.1.17
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.
- package/dist/commands/sync.js +1 -1
- package/dist/commands/watch.js +5 -16
- package/dist/engine/engine.js +14 -18
- package/dist/utils/parsers/astro.js +27 -8
- package/dist/utils/parsers/svelte.js +12 -4
- package/dist/utils/parsers/vue.js +34 -24
- package/package.json +1 -1
- package/src/commands/sync.ts +1 -3
- package/src/commands/watch.ts +5 -23
- package/src/engine/engine.ts +17 -21
- package/src/utils/parsers/astro.ts +31 -8
- package/src/utils/parsers/svelte.ts +14 -4
- package/src/utils/parsers/vue.ts +40 -26
package/dist/commands/sync.js
CHANGED
|
@@ -30,8 +30,8 @@ async function sync() {
|
|
|
30
30
|
try {
|
|
31
31
|
const raw = await promises_1.default.readFile(file, "utf-8");
|
|
32
32
|
const { content, virtualFile } = (0, processFile_1.processFile)(file, raw);
|
|
33
|
-
fileCache.push({ file: virtualFile, content });
|
|
34
33
|
engine["ts"].updateFile(virtualFile, content);
|
|
34
|
+
fileCache.push({ file: virtualFile, content });
|
|
35
35
|
}
|
|
36
36
|
catch {
|
|
37
37
|
// ignore
|
package/dist/commands/watch.js
CHANGED
|
@@ -13,7 +13,6 @@ const config_1 = require("../utils/config");
|
|
|
13
13
|
const engine_1 = require("../engine/engine");
|
|
14
14
|
const processFile_1 = require("../utils/processFile");
|
|
15
15
|
async function watch() {
|
|
16
|
-
process.env.EVENTRA_WATCH = "1";
|
|
17
16
|
const config = await (0, config_1.loadConfig)();
|
|
18
17
|
if (!config)
|
|
19
18
|
return;
|
|
@@ -30,7 +29,6 @@ async function watch() {
|
|
|
30
29
|
const raw = await promises_1.default.readFile(abs, "utf-8");
|
|
31
30
|
const { content, virtualFile } = (0, processFile_1.processFile)(abs, raw);
|
|
32
31
|
fileCache.push({ file: virtualFile, content });
|
|
33
|
-
engine["ts"].updateFile(virtualFile, content);
|
|
34
32
|
}
|
|
35
33
|
catch {
|
|
36
34
|
console.log(chalk_1.default.gray(`skip: ${file}`));
|
|
@@ -54,22 +52,14 @@ async function watch() {
|
|
|
54
52
|
queued.clear();
|
|
55
53
|
for (const file of batch) {
|
|
56
54
|
try {
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
engine["ts"].updateFile(virtualFile, content);
|
|
55
|
+
const raw = await promises_1.default.readFile(file, "utf-8");
|
|
56
|
+
const { content, virtualFile } = (0, processFile_1.processFile)(file, raw);
|
|
57
|
+
engine.updateFile(virtualFile, content, config);
|
|
61
58
|
}
|
|
62
59
|
catch {
|
|
63
60
|
console.log(chalk_1.default.gray(`skip: ${file}`));
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
|
-
const allFiles = [...engine["ts"]["fileNames"]];
|
|
67
|
-
for (const file of allFiles) {
|
|
68
|
-
const content = engine["ts"].getFileContent(file);
|
|
69
|
-
if (!content)
|
|
70
|
-
continue;
|
|
71
|
-
engine.scanFile(file, content, config);
|
|
72
|
-
}
|
|
73
63
|
const next = engine.getAllEvents();
|
|
74
64
|
const added = next.filter(e => !config.events.includes(e));
|
|
75
65
|
const removed = config.events.filter(e => !next.includes(e));
|
|
@@ -83,11 +73,10 @@ async function watch() {
|
|
|
83
73
|
locked = false;
|
|
84
74
|
};
|
|
85
75
|
const schedule = (file) => {
|
|
86
|
-
|
|
87
|
-
queued.add(abs);
|
|
76
|
+
queued.add(path_1.default.resolve(file));
|
|
88
77
|
if (timer)
|
|
89
78
|
clearTimeout(timer);
|
|
90
|
-
timer = setTimeout(run,
|
|
79
|
+
timer = setTimeout(run, 200);
|
|
91
80
|
};
|
|
92
81
|
const watcher = chokidar_1.default.watch(config.sync.include, {
|
|
93
82
|
ignored: config.sync.exclude,
|
package/dist/engine/engine.js
CHANGED
|
@@ -19,9 +19,8 @@ class EventraEngine {
|
|
|
19
19
|
// SCAN FILE
|
|
20
20
|
scanFile(file, content, config) {
|
|
21
21
|
const h = (0, hash_1.hash)(content);
|
|
22
|
-
const isWatch = process.env.EVENTRA_WATCH === "1";
|
|
23
22
|
// skip unchanged
|
|
24
|
-
if (this.fileHash.get(file) === h
|
|
23
|
+
if (this.fileHash.get(file) === h) {
|
|
25
24
|
return (this.fileResults.get(file) ?? {
|
|
26
25
|
events: new Set(),
|
|
27
26
|
detectedFunctionWrappers: new Set(),
|
|
@@ -39,7 +38,6 @@ class EventraEngine {
|
|
|
39
38
|
detectedComponentWrappers: new Map(),
|
|
40
39
|
};
|
|
41
40
|
}
|
|
42
|
-
// update dependency graph
|
|
43
41
|
this.graph.update(file, source);
|
|
44
42
|
const res = (0, scanner_1.scanSource)(source, checker, config);
|
|
45
43
|
this.fileResults.set(file, res);
|
|
@@ -47,25 +45,24 @@ class EventraEngine {
|
|
|
47
45
|
}
|
|
48
46
|
// UPDATE FILE (incremental)
|
|
49
47
|
updateFile(file, content, config) {
|
|
48
|
+
// сначала обновляем текущий файл
|
|
50
49
|
const res = this.scanFile(file, content, config);
|
|
51
50
|
const dependents = this.graph.getAllDependentsDeep(file);
|
|
52
51
|
for (const dep of dependents) {
|
|
53
|
-
// skip external files
|
|
54
52
|
if ((0, boundary_1.isExternalFile)(dep))
|
|
55
53
|
continue;
|
|
56
|
-
const source = this.ts.getSourceFile(dep);
|
|
57
|
-
const checker = this.ts.getChecker();
|
|
58
|
-
if (!source || !checker)
|
|
59
|
-
continue;
|
|
60
54
|
const depContent = this.ts.getFileContent(dep);
|
|
61
55
|
if (!depContent)
|
|
62
56
|
continue;
|
|
63
57
|
const h = (0, hash_1.hash)(depContent);
|
|
64
|
-
|
|
65
|
-
// skip unchanged dependents
|
|
66
|
-
if (this.fileHash.get(dep) === h && !isWatch)
|
|
58
|
+
if (this.fileHash.get(dep) === h)
|
|
67
59
|
continue;
|
|
68
60
|
this.fileHash.set(dep, h);
|
|
61
|
+
this.ts.updateFile(dep, depContent);
|
|
62
|
+
const source = this.ts.getSourceFile(dep);
|
|
63
|
+
const checker = this.ts.getChecker();
|
|
64
|
+
if (!source || !checker)
|
|
65
|
+
continue;
|
|
69
66
|
this.graph.update(dep, source);
|
|
70
67
|
const r = (0, scanner_1.scanSource)(source, checker, config);
|
|
71
68
|
this.fileResults.set(dep, r);
|
|
@@ -90,19 +87,18 @@ class EventraEngine {
|
|
|
90
87
|
for (const dep of dependents) {
|
|
91
88
|
if ((0, boundary_1.isExternalFile)(dep))
|
|
92
89
|
continue;
|
|
93
|
-
const source = this.ts.getSourceFile(dep);
|
|
94
|
-
const checker = this.ts.getChecker();
|
|
95
|
-
if (!source || !checker)
|
|
96
|
-
continue;
|
|
97
90
|
const content = this.ts.getFileContent(dep);
|
|
98
91
|
if (!content)
|
|
99
92
|
continue;
|
|
100
93
|
const h = (0, hash_1.hash)(content);
|
|
101
|
-
|
|
102
|
-
// skip unchanged
|
|
103
|
-
if (this.fileHash.get(dep) === h && !isWatch)
|
|
94
|
+
if (this.fileHash.get(dep) === h)
|
|
104
95
|
continue;
|
|
105
96
|
this.fileHash.set(dep, h);
|
|
97
|
+
this.ts.updateFile(dep, content);
|
|
98
|
+
const source = this.ts.getSourceFile(dep);
|
|
99
|
+
const checker = this.ts.getChecker();
|
|
100
|
+
if (!source || !checker)
|
|
101
|
+
continue;
|
|
106
102
|
const r = (0, scanner_1.scanSource)(source, checker, config ?? {
|
|
107
103
|
events: [],
|
|
108
104
|
wrappers: [],
|
|
@@ -2,12 +2,31 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseAstro = parseAstro;
|
|
4
4
|
function parseAstro(content) {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
const parts = [];
|
|
6
|
+
// frontmatter
|
|
7
|
+
const frontmatter = content.match(/^---([\s\S]*?)---/);
|
|
8
|
+
if (frontmatter?.[1]) {
|
|
9
|
+
parts.push(frontmatter[1]);
|
|
10
|
+
}
|
|
11
|
+
// scripts
|
|
12
|
+
const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
|
|
13
|
+
for (const m of scripts) {
|
|
14
|
+
const attrs = m[1];
|
|
15
|
+
const body = m[2];
|
|
16
|
+
if (attrs.includes("src")) {
|
|
17
|
+
const src = attrs.match(/src=["'](.+?)["']/)?.[1];
|
|
18
|
+
if (src) {
|
|
19
|
+
parts.push(`import "${src}"`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
parts.push(body);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
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");
|
|
13
32
|
}
|
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseSvelte = parseSvelte;
|
|
4
4
|
function parseSvelte(content) {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
];
|
|
8
|
-
|
|
5
|
+
const parts = [];
|
|
6
|
+
// scripts
|
|
7
|
+
const scripts = content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g);
|
|
8
|
+
for (const m of scripts) {
|
|
9
|
+
parts.push(m[1]);
|
|
10
|
+
}
|
|
11
|
+
// on:click / on:*
|
|
12
|
+
const handlers = content.matchAll(/on:\w+=\{([^}]+)\}/g);
|
|
13
|
+
for (const h of handlers) {
|
|
14
|
+
parts.push(h[1] + ";");
|
|
15
|
+
}
|
|
16
|
+
return parts.join("\n");
|
|
9
17
|
}
|
|
@@ -2,30 +2,40 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseVue = parseVue;
|
|
4
4
|
function parseVue(content) {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
];
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
const parts = [];
|
|
6
|
+
// --- SCRIPT ---
|
|
7
|
+
const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
|
|
8
|
+
for (const m of scripts) {
|
|
9
|
+
const attrs = m[1];
|
|
10
|
+
const body = m[2];
|
|
11
|
+
if (attrs.includes("src")) {
|
|
12
|
+
const src = attrs.match(/src=["'](.+?)["']/)?.[1];
|
|
13
|
+
if (src) {
|
|
14
|
+
parts.push(`import "${src}"`);
|
|
15
|
+
}
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
parts.push(body);
|
|
19
|
+
}
|
|
20
|
+
// --- TEMPLATE ---
|
|
21
|
+
const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/);
|
|
11
22
|
let template = templateMatch?.[1] ?? "";
|
|
23
|
+
// remove comments
|
|
12
24
|
template = template.replace(/<!--[\s\S]*?-->/g, "");
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
);
|
|
29
|
-
`;
|
|
30
|
-
return script + "\n" + jsx;
|
|
25
|
+
// --- event handlers (@click)
|
|
26
|
+
const handlers = template.matchAll(/@[\w-]+="([^"]+)"/g);
|
|
27
|
+
for (const h of handlers) {
|
|
28
|
+
parts.push(h[1] + ";");
|
|
29
|
+
}
|
|
30
|
+
// --- v-on
|
|
31
|
+
const vOn = template.matchAll(/v-on:[\w-]+="([^"]+)"/g);
|
|
32
|
+
for (const v of vOn) {
|
|
33
|
+
parts.push(v[1] + ";");
|
|
34
|
+
}
|
|
35
|
+
// --- :prop bindings
|
|
36
|
+
const binds = template.matchAll(/:[\w-]+="([^"]+)"/g);
|
|
37
|
+
for (const b of binds) {
|
|
38
|
+
parts.push(b[1] + ";");
|
|
39
|
+
}
|
|
40
|
+
return parts.join("\n");
|
|
31
41
|
}
|
package/package.json
CHANGED
package/src/commands/sync.ts
CHANGED
|
@@ -32,10 +32,8 @@ export async function sync() {
|
|
|
32
32
|
try {
|
|
33
33
|
const raw = await fs.readFile(file, "utf-8");
|
|
34
34
|
const { content, virtualFile } = processFile(file, raw);
|
|
35
|
-
|
|
36
|
-
fileCache.push({ file: virtualFile, content });
|
|
37
|
-
|
|
38
35
|
engine["ts"].updateFile(virtualFile, content);
|
|
36
|
+
fileCache.push({ file: virtualFile, content });
|
|
39
37
|
} catch {
|
|
40
38
|
// ignore
|
|
41
39
|
}
|
package/src/commands/watch.ts
CHANGED
|
@@ -9,8 +9,6 @@ import { EventraEngine } from "../engine/engine";
|
|
|
9
9
|
import { processFile } from "../utils/processFile";
|
|
10
10
|
|
|
11
11
|
export async function watch() {
|
|
12
|
-
process.env.EVENTRA_WATCH = "1";
|
|
13
|
-
|
|
14
12
|
const config = await loadConfig();
|
|
15
13
|
if (!config) return;
|
|
16
14
|
|
|
@@ -29,12 +27,8 @@ export async function watch() {
|
|
|
29
27
|
try {
|
|
30
28
|
const abs = path.resolve(file);
|
|
31
29
|
const raw = await fs.readFile(abs, "utf-8");
|
|
32
|
-
|
|
33
30
|
const { content, virtualFile } = processFile(abs, raw);
|
|
34
|
-
|
|
35
31
|
fileCache.push({ file: virtualFile, content });
|
|
36
|
-
|
|
37
|
-
engine["ts"].updateFile(virtualFile, content);
|
|
38
32
|
} catch {
|
|
39
33
|
console.log(chalk.gray(`skip: ${file}`));
|
|
40
34
|
}
|
|
@@ -65,27 +59,16 @@ export async function watch() {
|
|
|
65
59
|
|
|
66
60
|
for (const file of batch) {
|
|
67
61
|
try {
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
const { content, virtualFile } = processFile(abs, raw);
|
|
62
|
+
const raw = await fs.readFile(file, "utf-8");
|
|
63
|
+
const { content, virtualFile } = processFile(file, raw);
|
|
72
64
|
|
|
73
|
-
engine
|
|
65
|
+
engine.updateFile(virtualFile, content, config);
|
|
74
66
|
|
|
75
67
|
} catch {
|
|
76
68
|
console.log(chalk.gray(`skip: ${file}`));
|
|
77
69
|
}
|
|
78
70
|
}
|
|
79
71
|
|
|
80
|
-
const allFiles = [...engine["ts"]["fileNames"]];
|
|
81
|
-
|
|
82
|
-
for (const file of allFiles) {
|
|
83
|
-
const content = engine["ts"].getFileContent(file);
|
|
84
|
-
if (!content) continue;
|
|
85
|
-
|
|
86
|
-
engine.scanFile(file, content, config);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
72
|
const next = engine.getAllEvents();
|
|
90
73
|
|
|
91
74
|
const added = next.filter(e => !config.events.includes(e));
|
|
@@ -107,11 +90,10 @@ export async function watch() {
|
|
|
107
90
|
};
|
|
108
91
|
|
|
109
92
|
const schedule = (file: string) => {
|
|
110
|
-
|
|
111
|
-
queued.add(abs);
|
|
93
|
+
queued.add(path.resolve(file));
|
|
112
94
|
|
|
113
95
|
if (timer) clearTimeout(timer);
|
|
114
|
-
timer = setTimeout(run,
|
|
96
|
+
timer = setTimeout(run, 200);
|
|
115
97
|
};
|
|
116
98
|
|
|
117
99
|
const watcher = chokidar.watch(config.sync.include, {
|
package/src/engine/engine.ts
CHANGED
|
@@ -26,10 +26,9 @@ export class EventraEngine {
|
|
|
26
26
|
config: EventraConfig
|
|
27
27
|
): ScanResult {
|
|
28
28
|
const h = hash(content);
|
|
29
|
-
const isWatch = process.env.EVENTRA_WATCH === "1";
|
|
30
29
|
|
|
31
30
|
// skip unchanged
|
|
32
|
-
if (this.fileHash.get(file) === h
|
|
31
|
+
if (this.fileHash.get(file) === h) {
|
|
33
32
|
return (
|
|
34
33
|
this.fileResults.get(file) ?? {
|
|
35
34
|
events: new Set(),
|
|
@@ -53,11 +52,9 @@ export class EventraEngine {
|
|
|
53
52
|
};
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
// update dependency graph
|
|
57
55
|
this.graph.update(file, source);
|
|
58
56
|
|
|
59
57
|
const res = scanSource(source, checker, config);
|
|
60
|
-
|
|
61
58
|
this.fileResults.set(file, res);
|
|
62
59
|
|
|
63
60
|
return res;
|
|
@@ -69,29 +66,28 @@ export class EventraEngine {
|
|
|
69
66
|
content: string,
|
|
70
67
|
config: EventraConfig
|
|
71
68
|
) {
|
|
69
|
+
// сначала обновляем текущий файл
|
|
72
70
|
const res = this.scanFile(file, content, config);
|
|
73
71
|
|
|
74
72
|
const dependents = this.graph.getAllDependentsDeep(file);
|
|
75
73
|
|
|
76
74
|
for (const dep of dependents) {
|
|
77
|
-
// skip external files
|
|
78
75
|
if (isExternalFile(dep)) continue;
|
|
79
76
|
|
|
80
|
-
const source = this.ts.getSourceFile(dep);
|
|
81
|
-
const checker = this.ts.getChecker();
|
|
82
|
-
|
|
83
|
-
if (!source || !checker) continue;
|
|
84
|
-
|
|
85
77
|
const depContent = this.ts.getFileContent(dep);
|
|
86
78
|
if (!depContent) continue;
|
|
87
79
|
|
|
88
80
|
const h = hash(depContent);
|
|
89
|
-
const isWatch = process.env.EVENTRA_WATCH === "1";
|
|
90
81
|
|
|
91
|
-
|
|
92
|
-
if (this.fileHash.get(dep) === h && !isWatch) continue;
|
|
82
|
+
if (this.fileHash.get(dep) === h) continue;
|
|
93
83
|
|
|
94
84
|
this.fileHash.set(dep, h);
|
|
85
|
+
this.ts.updateFile(dep, depContent);
|
|
86
|
+
|
|
87
|
+
const source = this.ts.getSourceFile(dep);
|
|
88
|
+
const checker = this.ts.getChecker();
|
|
89
|
+
|
|
90
|
+
if (!source || !checker) continue;
|
|
95
91
|
|
|
96
92
|
this.graph.update(dep, source);
|
|
97
93
|
|
|
@@ -119,26 +115,26 @@ export class EventraEngine {
|
|
|
119
115
|
this.fileResults.delete(file);
|
|
120
116
|
this.fileHash.delete(file);
|
|
121
117
|
this.graph.remove(file);
|
|
118
|
+
|
|
122
119
|
const dependents = this.graph.getAllDependentsDeep(file);
|
|
123
120
|
|
|
124
121
|
for (const dep of dependents) {
|
|
125
122
|
if (isExternalFile(dep)) continue;
|
|
126
123
|
|
|
127
|
-
const source = this.ts.getSourceFile(dep);
|
|
128
|
-
const checker = this.ts.getChecker();
|
|
129
|
-
|
|
130
|
-
if (!source || !checker) continue;
|
|
131
|
-
|
|
132
124
|
const content = this.ts.getFileContent(dep);
|
|
133
125
|
if (!content) continue;
|
|
134
126
|
|
|
135
127
|
const h = hash(content);
|
|
136
|
-
const isWatch = process.env.EVENTRA_WATCH === "1";
|
|
137
128
|
|
|
138
|
-
|
|
139
|
-
if (this.fileHash.get(dep) === h && !isWatch) continue;
|
|
129
|
+
if (this.fileHash.get(dep) === h) continue;
|
|
140
130
|
|
|
141
131
|
this.fileHash.set(dep, h);
|
|
132
|
+
this.ts.updateFile(dep, content);
|
|
133
|
+
|
|
134
|
+
const source = this.ts.getSourceFile(dep);
|
|
135
|
+
const checker = this.ts.getChecker();
|
|
136
|
+
|
|
137
|
+
if (!source || !checker) continue;
|
|
142
138
|
|
|
143
139
|
const r = scanSource(
|
|
144
140
|
source,
|
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
export function parseAstro(content: string) {
|
|
2
|
-
const
|
|
2
|
+
const parts: string[] = [];
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
]
|
|
4
|
+
// frontmatter
|
|
5
|
+
const frontmatter = content.match(/^---([\s\S]*?)---/);
|
|
6
|
+
if (frontmatter?.[1]) {
|
|
7
|
+
parts.push(frontmatter[1]);
|
|
8
|
+
}
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// scripts
|
|
11
|
+
const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
|
|
12
|
+
|
|
13
|
+
for (const m of scripts) {
|
|
14
|
+
const attrs = m[1];
|
|
15
|
+
const body = m[2];
|
|
16
|
+
|
|
17
|
+
if (attrs.includes("src")) {
|
|
18
|
+
const src = attrs.match(/src=["'](.+?)["']/)?.[1];
|
|
19
|
+
if (src) {
|
|
20
|
+
parts.push(`import "${src}"`);
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
parts.push(body);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
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");
|
|
12
35
|
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
export function parseSvelte(content: string) {
|
|
2
|
-
const
|
|
3
|
-
...content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)
|
|
4
|
-
];
|
|
2
|
+
const parts: string[] = [];
|
|
5
3
|
|
|
6
|
-
|
|
4
|
+
// scripts
|
|
5
|
+
const scripts = content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g);
|
|
6
|
+
for (const m of scripts) {
|
|
7
|
+
parts.push(m[1]);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// on:click / on:*
|
|
11
|
+
const handlers = content.matchAll(/on:\w+=\{([^}]+)\}/g);
|
|
12
|
+
for (const h of handlers) {
|
|
13
|
+
parts.push(h[1] + ";");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return parts.join("\n");
|
|
7
17
|
}
|
package/src/utils/parsers/vue.ts
CHANGED
|
@@ -1,34 +1,48 @@
|
|
|
1
1
|
export function parseVue(content: string) {
|
|
2
|
-
const
|
|
3
|
-
...content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)
|
|
4
|
-
];
|
|
2
|
+
const parts: string[] = [];
|
|
5
3
|
|
|
6
|
-
|
|
4
|
+
// --- SCRIPT ---
|
|
5
|
+
const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
for (const m of scripts) {
|
|
8
|
+
const attrs = m[1];
|
|
9
|
+
const body = m[2];
|
|
10
|
+
|
|
11
|
+
if (attrs.includes("src")) {
|
|
12
|
+
const src = attrs.match(/src=["'](.+?)["']/)?.[1];
|
|
13
|
+
if (src) {
|
|
14
|
+
parts.push(`import "${src}"`);
|
|
15
|
+
}
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
parts.push(body);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// --- TEMPLATE ---
|
|
23
|
+
const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/);
|
|
10
24
|
let template = templateMatch?.[1] ?? "";
|
|
11
25
|
|
|
26
|
+
// remove comments
|
|
12
27
|
template = template.replace(/<!--[\s\S]*?-->/g, "");
|
|
13
28
|
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return script + "\n" + jsx;
|
|
29
|
+
// --- event handlers (@click)
|
|
30
|
+
const handlers = template.matchAll(/@[\w-]+="([^"]+)"/g);
|
|
31
|
+
for (const h of handlers) {
|
|
32
|
+
parts.push(h[1] + ";");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// --- v-on
|
|
36
|
+
const vOn = template.matchAll(/v-on:[\w-]+="([^"]+)"/g);
|
|
37
|
+
for (const v of vOn) {
|
|
38
|
+
parts.push(v[1] + ";");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// --- :prop bindings
|
|
42
|
+
const binds = template.matchAll(/:[\w-]+="([^"]+)"/g);
|
|
43
|
+
for (const b of binds) {
|
|
44
|
+
parts.push(b[1] + ";");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return parts.join("\n");
|
|
34
48
|
}
|